Exemplo n.º 1
0
void vtkPolyDataSingleSourceShortestPath::init()
{
	BuildAdjacency(this->GetInput());
	
	IdList->Reset();
	
	this->n = this->GetInput()->GetNumberOfPoints();
	
	this->d->SetNumberOfComponents(1);
	this->d->SetNumberOfTuples(this->n);
	this->pre->SetNumberOfComponents(1);
	this->pre->SetNumberOfTuples(this->n);
	this->f->SetNumberOfComponents(1);
	this->f->SetNumberOfTuples(this->n);
	this->s->SetNumberOfComponents(1);
	this->s->SetNumberOfTuples(this->n);
	this->p->SetNumberOfComponents(1);
	this->p->SetNumberOfTuples(this->n);
	
	// The heap has elements from 1 to n
	this->H->SetNumberOfComponents(1);
	this->H->SetNumberOfTuples(this->n+1);
	
	Hsize = 0;
}
// -------------------------------------------------------------------------- //
void Class_VolTri::ExtractBoundaries(
    Class_SurfTri    &Bounds,
    int               BC_flag
) {

// ========================================================================== //
// void Class_VolTri::ExtractBoundaries(                                      //
//     Class_SurfTri    &Bounds,                                              //
//     int               BC_flag)                                             //
//                                                                            //
// Extract boundaries of volume mesh.                                         //
// ========================================================================== //
// INPUT                                                                      //
// ========================================================================== //
// - Bounds     : Class_SurfTri, surface mesh                                 //
// - BC_flag    : int, boundary condition flag                                //
// ========================================================================== //
// OUTPUT                                                                     //
// ========================================================================== //
// - none                                                                     //
// ========================================================================== //

// ========================================================================== //
// VARIABLES DECLARATION                                                      //
// ========================================================================== //

// Local variables
ivector1D                simplex;

// Counters
int                      nS;
int                      i, j;
int                      n, m;
int                      T;

// ========================================================================== //
// BUILD ADJACENCY IF NOT ALREADY BUILT                                       //
// ========================================================================== //
if ((Adjacency.size() == 0) || (Adjacency.size() < nSimplex)) {
    BuildAdjacency();
}

// ========================================================================== //
// RESIZE DATA STRUCTURES                                                     //
// ========================================================================== //
Bounds.AddVertices(Vertex);
nS = Bounds.nSimplex;
Bounds.nSimplex += CountFreeFaces();
Bounds.ResizeSimplex();
Bounds.nSimplex = nS;

// ========================================================================== //
// LOOP OVER SIMPLICIES                                                       //
// ========================================================================== //
for (T = 0; T < nSimplex; ++T) {
    n = infos[e_type[T]].n_faces;
    for (i = 0; i < n; ++i) {
        if (Adjacency[T][i] == BC_flag) {
            m = infos[e_type[T]].faces[i].size();
            simplex.resize(m, -1);
            for (j = 0; j < m; ++j) {
                simplex[j] = Simplex[T][infos[e_type[T]].faces[i][j]];
            } //next j
            Bounds.AddSimplex(simplex);
        }
    } //next i
} //next T

// ========================================================================== //
// CLEAN SURFACE TASSELATION                                                  //
// ========================================================================== //
Bounds.RemoveIsolatedVertex();
Bounds.ResizeVertex();

return; };
// -------------------------------------------------------------------------- //
int Class_VolTri::ReturnSimplexID(
    a3vector1D  &P,
    int          S0
) {

// ========================================================================== //
// int Class_VolTri::ReturnSimplexID(                                         //
//     a3vector1D  &P,                                                        //
//     int          S0)                                                       //
//                                                                            //
// Return the ID of the simplex enclosing point P.                            //
// ========================================================================== //
// INPUT                                                                      //
// ========================================================================== //
// - P     : a3vector1D, point coordinates                                    //
// - S0    : int, seed for search procedure                                   //
// ========================================================================== //
// OUTPUT                                                                     //
// ========================================================================== //
// - S     : int, ID of simplex enclosing point P                             //
// ========================================================================== //

// ========================================================================== //
// VARIABLES DECLARATION                                                      //
// ========================================================================== //

// Local variables
bool                        check = false;
int                         n, m, p;
double                      max_dp, dp;
bvector1D                   visited(nSimplex, false);
ivector2D                   face_vlist;
a3vector1D                  x, y, xF, xS, dir;
a3vector2D                  face_normals;
LIFOstack<int>              stack;

// Counters
int                         i, j, k, l, S, A;
/*debug*/int                         n_visited = 0;

// /*debug*/ofstream       log_file;
// /*debug*/log_file.open("SEARCH.log", ifstream::app);

// ========================================================================== //
// INITIALIZE PARAMETERS                                                      //
// ========================================================================== //
// x.fill(0.0);
// y.fill(0.0);

// /*debug*/log_file << "point coordinates: " << P << endl;

// ========================================================================== //
// BUILD ADJACENCY IF NOT ALREADY BUILT                                       //
// ========================================================================== //
if ((Adjacency.size() == 0) || (Adjacency.size() < nSimplex)) {
    BuildAdjacency();
}

// ========================================================================== //
// LOOP UNTIL SIMPLEX IS FOUND                                                //
// ========================================================================== //
stack.push(S0);
while ((stack.TOPSTK > 0) && (!check)) {

// /*debug*/n_visited++;

    // Pop item from stack -------------------------------------------------- //
    S = stack.pop();
    visited[S] = true;

// /*debug*/log_file << "  traversing simplex: " << S << endl;
// /*debug*/log_file << "  (visited: " << n_visited << " of " << nSimplex << endl;

    // Simplex infos -------------------------------------------------------- //
    n = infos[e_type[S]].n_vert;
    m = infos[e_type[S]].n_faces;

    // Get face vertices ---------------------------------------------------- //
    {
        face_vlist.resize(m);
        for (j = 0; j < m; ++j) {
            face_vlist[j] = FaceVertices(S, j);
        } //next j
    }

    // Simplex baricenter --------------------------------------------------- //
    {
        xS.fill(0.0);
        for (j = 0; j < n; ++j) {
            for (l = 0; l < 3; ++l) {
                xS[l] += Vertex[Simplex[S][j]][l];
            } //next l
        } //next j
        xS = xS/((double) n);
    }

    // Compute face normals ------------------------------------------------- //
    {
        face_normals.resize(m);
        for (j = 0; j < m; ++j) {
            if (face_vlist[j].size() == 2) {
                x = Vertex[face_vlist[j][1]] - Vertex[face_vlist[j][0]];
                x[2] = 0.0;
                y[0] = 0.0;
                y[1] = 0.0;
                y[2] = 1.0;
                face_normals[j] = Cross_Product(x, y);
            }
            else {
                x = Vertex[face_vlist[j][2]] - Vertex[face_vlist[j][1]];
                y = Vertex[face_vlist[j][1]] - Vertex[face_vlist[j][0]];
                face_normals[j] = Cross_Product(x, y);
            }
            face_normals[j] = face_normals[j]/max(norm_2(face_normals[j]), 2.0e-16);
        } //next j
    }
    
    // Check if Simplex S encloses point P ---------------------------------- //
    {
        check = true;
        for (j = 0; j < m; ++j) {
            n = face_vlist[j].size();
    
            // Compute face center
            xF.fill(0.0);
            for (k = 0; k < n; ++k) {
                for (l = 0; l < 3; l++) {
                    xF[l] += Vertex[face_vlist[j][k]][l];
                } //next l
            } //next k
            xF = xF/((double) n);
    
            // Check if simplex encloses point
            dir = P - xF;
            dir = dir/max(norm_2(dir), 2.0e-16);
            check = (check && (Dot_Product(dir, face_normals[j]) <= 0.0));
        } //next j
    }

// /*debug*/log_file << "    encloses point: " << check << endl;

    // Look for best direction (Euristic search of best path) --------------- //
    // NOTES:                                                                 //
    // - modificare il criterio euristico per la scelta del path migliore     //
    //   * congiungente P-xS attraversa una faccia.                           //
    //   * distanza minima dalle facce.                                       //
    // ---------------------------------------------------------------------- //
    if (!check) {

        // local direction of searching path
        dir = P - xS;
        dir = dir/max(norm_2(dir), 2.0e-16);
    
        // Loop over simplex faces
        max_dp = -2.0;
        i = 0;
        j = -1;
        while (i < m) {
            dp = Dot_Product(face_normals[i], dir);
            if (dp > max_dp) {
                j = i;
                max_dp = dp;
            }
            i++;
        } //next i
    
        // Alternative directions
        for (i = 0; i < m; ++i) {
            A = Adjacency[S][i];
            if ((i != j) && (A >= 0) && (!visited[A])) {
                stack.push(A);
            }
        } //next i
        A = Adjacency[S][j];
        if ((A >= 0) && (!visited[A])) {
            stack.push(A);
        }
    }

} //next simplex

// /*debug*/log_file << "  (visited: " << n_visited << " of " << nSimplex << ")" << endl;

// Old algorithm ============================================================ //
{
    // while ((n_visited <= nSimplex) && (!check) && (S0 >= 0)) {
    
        // // Update simplex ID ---------------------------------------------------- //
        // // cout << "    on simplex " << S0;
        // S = S0;
        // n_visited++;
        // visited[S] = true;
        // /*debug*/log_file << "  traversing simplex: " << S << endl;
        // /*debug*/log_file << "  (visited: " << n_visited << " of " << nSimplex << endl;
    
        // // Simplex infos -------------------------------------------------------- //
        // m = infos[e_type[S]].n_faces;
        // p = infos[e_type[S]].n_vert;
    
        // // Compute simplex baricenter ------------------------------------------- //
        // {
            // xS.fill(0.0);
            // for (j = 0; j < p; ++j) {
                // for (l = 0; l < dim; ++l) {
                    // xS[l] += Vertex[Simplex[S][j]][l];
                // } //next l
            // } //next j
            // xS = xS/((double) p);
        // }
    
        // // Get face vertices ---------------------------------------------------- //
        // {
            // face_vlist.resize(m);
            // for (j = 0; j < m; ++j) {
                // face_vlist[j] = FaceVertices(S, j);
            // } //next j
        // }
    
        // // Compute face normals ------------------------------------------------- //
        // {
            // face_normals.resize(m);
            // for (j = 0; j < m; ++j) {
                // if (face_vlist[j].size() == 2) {
                    // x[0] = Vertex[face_vlist[j][1]][0] - Vertex[face_vlist[j][0]][0];
                    // x[1] = Vertex[face_vlist[j][1]][1] - Vertex[face_vlist[j][0]][1];
                    // x[2] = 0.0;
                    // y[0] = 0.0;
                    // y[1] = 0.0;
                    // y[2] = 1.0;
                    // face_normals[j] = Cross_Product(x, y);
                // }
                // else {
                    // x[0] = Vertex[face_vlist[j][2]][0] - Vertex[face_vlist[j][1]][0];
                    // x[1] = Vertex[face_vlist[j][2]][1] - Vertex[face_vlist[j][1]][1];
                    // x[2] = Vertex[face_vlist[j][2]][2] - Vertex[face_vlist[j][1]][2];
                    // y[0] = Vertex[face_vlist[j][1]][0] - Vertex[face_vlist[j][0]][0];
                    // y[1] = Vertex[face_vlist[j][1]][1] - Vertex[face_vlist[j][0]][1];
                    // y[2] = Vertex[face_vlist[j][1]][2] - Vertex[face_vlist[j][0]][2];
                    // face_normals[j] = Cross_Product(x, y);
                // }
                // face_normals[j] = face_normals[j]/max(norm_2(face_normals[j]), 2.0e-16);
            // } //next j
        // }
    
        // // Check if P is enclosed in simplex S0 --------------------------------- //
        // {
            // check = true;
            // for (j = 0; j < m; ++j) {
                // n = face_vlist[j].size();
        
                // // Compute face center
                // xF.fill(0.0);
                // for (k = 0; k < n; ++k) {
                    // for (l = 0; l < dim; l++) {
                        // xF[l] += Vertex[face_vlist[j][k]][l];
                    // } //next l
                // } //next k
                // xF = xF/((double) n);
        
                // // Check if simplex encloses point
                // for (l = 0; l < dim; l++) {
                    // dir[l] = P[l] - xF[l];
                // } //next l
                // dir = dir/max(norm_2(dir), 2.0e-16);
                // check = (check && (Dot_Product(dir, face_normals[j]) <= 0.0));
                // // cout << " f " << j << ", c: " << check;
            // } //next j
        // }
        // // cout << ", check: " << check << endl;
        // /*debug*/log_file << "    encloses point: " << check << endl;
    
        // // Look for best direction (Euristic search) ---------------------------- //
        // if (!check) {
        
            // // Find face to be crossed (Euristic search of best path)
            // {
        
                // // path local direction
                // for (l = 0; l < dim; ++l) {
                    // dir[l] = P[l] - xS[l];
                // } //next l
                // dir = dir/max(norm_2(dir), 2.0e-16);
        
                // // Loop over simplex faces
                // // WARNING: infinite loop at corner simplicies!!
                // max_dp = -2.0;
                // i = -1;
                // j = 0;
                // while (j < m) {
                    // dp = Dot_Product(face_normals[j], dir);
                    // A = Adjacency[S][j];
                    // if ((dp > max_dp) && (A >= 0)) {//&& (!visited[A])) {
                        // i = j;
                        // max_dp = dp;
                    // }
                    // j++;
                // } //next j
            // }
    
            // // Move to adjacent simplex
            // if (i >= 0) { S0 = Adjacency[S][i]; }
            // else        { S0 = -1;}
        // }
    
        // /*debug*/log_file << "    next simplex: " << S0 << endl;
    // } //next simplex
}
// /*debug*/log_file.close();

return(S); };
// -------------------------------------------------------------------------- //
ivector1D Class_VolTri::VertNeigh(
    int          T,
    int          i
) {

// ========================================================================== //
// ivector1D Class_VolTri::VertNeigh(                                         //
//     int          T,                                                        //
//     int          i)                                                        //
//                                                                            //
// Returns the indices of neighbors at the i-th vertex of simplex T.          //
// ========================================================================== //
// INPUT                                                                      //
// ========================================================================== //
// - T      : int, simplex global index                                       //
// - i      : int, vertex local index                                         //
// ========================================================================== //
// OUTPUT                                                                     //
// ========================================================================== //
// - neigh  : ivector1D, vertex neighbors                                     //
// ========================================================================== //

// ========================================================================== //
// INPUT                                                                      //
// ========================================================================== //

// Local variables
int                             n_faces = infos[e_type[T]].n_faces;
LIFOstack<int>                  stack(4*n_faces), visited(4*n_faces);
ivector1D                       e;
ivector1D                       neigh;
ivector1D                       e_neigh;
ivector1D::iterator             it_, end_;

// Counters
int                             n, m;
int                             j, k;
int                             S, A, V;

// ========================================================================== //
// BUILD ADJACENCIES IF NOT ALREADY BUILT                                     //
// ========================================================================== //
if ((Adjacency.size() == 0) || (Adjacency.size() < nSimplex)) {
    BuildAdjacency();
}

// ========================================================================== //
// ITERATIVELY ADD SIMPLICIES TO STACK                                        //
// ========================================================================== //

// Initialize stack --------------------------------------------------------- //
stack.push(T);
visited.push(T);
V = Simplex[T][i];

// Iterate until stack is empty --------------------------------------------- //
while (stack.TOPSTK > 0) {

    // Pop item from stack
    S = stack.pop();

    // Loop over S-neighbors
    n = infos[e_type[S]].n_faces;
    for (j = 0; j < n; ++j) {
        A = Adjacency[S][j];
        if (A >= 0) {
            end_ = visited.STACK.begin() + visited.TOPSTK;
            if (find(visited.STACK.begin(), end_, A) == end_) {
                if (vertex(A, V) >= 0) {
                    stack.push(A);
                    visited.push(A);
                    neigh.push_back(A);
                }
            }
        }
    } //next j
} //next item

// Remove face adjacent simplicies ------------------------------------------ //
for (j = 0; j < n_faces; ++j) {
    A = Adjacency[T][j];
    if (A >= 0) {
        it_ = find(neigh.begin(), neigh.end(), A);
        if (it_ != neigh.end()) {
            neigh.erase(it_);
        }
    }
} //next j

// Remove edge-adjacent simplicies ------------------------------------------ //

// find edges incident to vertex (T, i)
m = infos[e_type[T]].n_edges;
for (k = 0; k < m; k++) {
    if (find(infos[e_type[T]].edges[k].begin(),
             infos[e_type[T]].edges[k].end(),
             i) != infos[e_type[T]].edges[k].end()) {
        e.push_back(k);
    }
} //next k

// Remove edge-adjacent simplicies from neigh
m = e.size();
for (k = 0; k < m; ++k) {
    e_neigh = EdgeNeigh(T, e[k]);
    n = e_neigh.size();
    for (j = 0; j < n; ++j) {
        it_ = find(neigh.begin(), neigh.end(), e_neigh[j]);
        if (it_ != neigh.end()) {
            neigh.erase(it_);
        }
    } //next j
} //next k

return(neigh); };
// -------------------------------------------------------------------------- //
ivector1D Class_VolTri::EdgeNeigh(
    int          T, 
    int          i
) {

// ========================================================================== //
// ivector1D Class_VolTri::EdgeNeigh(                                         //
//     int          T,                                                        //
//     int          i)                                                        //
//                                                                            //
// Find neighboring simplicies of simplex T along the i-th edge.              //
// ========================================================================== //
// INPUT                                                                      //
// ========================================================================== //
// - T      : int, simplex global index                                       //
// - i      : int, edge local index                                           //
// ========================================================================== //
// OUTPUT                                                                     //
// ========================================================================== //
// - list   : ivector1D, list of edge neighbors                               //
// ========================================================================== //

// ========================================================================== //
// INPUT                                                                      //
// ========================================================================== //

// Local variables
int                             n_faces = infos[e_type[T]].n_faces;
LIFOstack<int>                  stack(4*n_faces), visited(4*n_faces);
ivector1D                       e;
ivector1D                       neigh;
ivector1D::iterator             it_, end_;

// Counters
int                             n;
int                             j;
int                             S, A;

// ========================================================================== //
// BUILD ADJACENCIES IF NOT ALREADY BUILT                                     //
// ========================================================================== //
if ((Adjacency.size() == 0) || (Adjacency.size() < nSimplex)) {
    BuildAdjacency();
}

// ========================================================================== //
// ITERATIVELY ADD SIMPLICIES TO STACK                                        //
// ========================================================================== //

// Initialize stack --------------------------------------------------------- //
stack.push(T);
n = infos[e_type[T]].edges[i].size();
e.resize(n, -1);
for (j = 0; j < n; ++j) {
    e[j] = Simplex[T][infos[e_type[T]].edges[i][j]];
} //next i

// Iterate until stack is empty --------------------------------------------- //

// Initialize visited list
for (i = 0; i < visited.STACK.size(); ++i) {
    visited.STACK[i] = -1;
} //next i
visited.push(T);

// Loop over items in stack
while (stack.TOPSTK > 0) {

    // Pop item from stack
    S = stack.pop();

    // Loop over S-neighbors
    n = infos[e_type[S]].n_faces;
    for (j = 0; j < n; ++j) {
        A = Adjacency[S][j];
        if (A >= 0) {
            end_ = visited.STACK.begin() + visited.TOPSTK;
            if (find(visited.STACK.begin(), end_, A) == end_) {
                if (edge(A, e) >= 0) {
                    stack.push(A);
                    visited.push(A);
                    neigh.push_back(A);
                }
            }
        }
    } //next j
} //next item

// Remove face adjacent simplicies ------------------------------------------ //
for (j = 0; j < n_faces; ++j) {
    A = Adjacency[T][j];
    if (A >= 0) {
        it_ = find(neigh.begin(), neigh.end(), A);
        if (it_ != neigh.end()) {
            neigh.erase(it_);
        }
    }
} //next j

return(neigh); };