vector<Point2D> PolygonTriangulation::getTriangle(int index){ vector<Point2D> t; if(index >= getNumberOfTriangles()) return t; t.push_back(m_p[m_he[index * 3]]); t.push_back(m_p[m_he[index * 3 + 1]]); t.push_back(m_p[m_he[index * 3 + 2]]); return t; }
void TetrahedronSetTopologyContainer::createTetrahedraAroundTriangleArray () { if(!hasTrianglesInTetrahedron()) createTrianglesInTetrahedronArray(); if(hasTetrahedraAroundTriangle()) clearTetrahedraAroundTriangle(); m_tetrahedraAroundTriangle.resize( getNumberOfTriangles()); for (unsigned int i=0; i<getNumberOfTetrahedra(); ++i) { // adding tetrahedron i in the shell of all neighbors triangles for (unsigned int j=0; j<4; ++j) { m_tetrahedraAroundTriangle[ m_trianglesInTetrahedron[i][j] ].push_back( i ); } } }
void TriangleSetTopologyContainer::createTrianglesAroundEdgeArray () { if(!hasTriangles()) // this method should only be called when triangles exist { #ifndef NDEBUG sout << "Warning. [TriangleSetTopologyContainer::createTrianglesAroundEdgeArray] triangle array is empty." << sendl; #endif createTriangleSetArray(); } if(!hasEdges()) // this method should only be called when edges exist { #ifndef NDEBUG sout << "Warning. [TriangleSetTopologyContainer::createTrianglesAroundEdgeArray] edge array is empty." << sendl; #endif createEdgeSetArray(); } if(!hasEdgesInTriangle()) createEdgesInTriangleArray(); const unsigned int numTriangles = getNumberOfTriangles(); const unsigned int numEdges = getNumberOfEdges(); if(hasTrianglesAroundEdge()) { clearTrianglesAroundEdge(); } m_trianglesAroundEdge.resize( numEdges ); for (unsigned int i = 0; i < numTriangles; ++i) { // adding triangle i in the triangle shell of all edges for (unsigned int j=0; j<3; ++j) { m_trianglesAroundEdge[ m_edgesInTriangle[i][j] ].push_back( i ); } } }
void TriangleSetTopologyContainer::createEdgesInTriangleArray() { if(!hasTriangles()) // this method should only be called when triangles exist { #ifndef NDEBUG sout << "Warning. [TriangleSetTopologyContainer::createEdgesInTriangleArray] triangle array is empty." << sendl; #endif createTriangleSetArray(); } // this should never be called : remove existing triangle edges if(hasEdgesInTriangle()) clearEdgesInTriangle(); helper::ReadAccessor< Data< sofa::helper::vector<Triangle> > > m_triangle = d_triangle; if(!hasEdges()) // To optimize, this method should be called without creating edgesArray before. { #ifndef NDEBUG sout << "Warning. [TriangleSetTopologyContainer::createEdgesInTriangleArray] edge array is empty." << sendl; #endif /// create edge array and triangle edge array at the same time const unsigned int numTriangles = getNumberOfTriangles(); m_edgesInTriangle.resize(numTriangles); // create a temporary map to find redundant edges std::map<Edge, unsigned int> edgeMap; helper::WriteAccessor< Data< sofa::helper::vector<Edge> > > m_edge = d_edge; for (unsigned int i=0; i<m_triangle.size(); ++i) { const Triangle &t = m_triangle[i]; for(unsigned int j=0; j<3; ++j) { const unsigned int v1 = t[(j+1)%3]; const unsigned int v2 = t[(j+2)%3]; // sort vertices in lexicographic order const Edge e = ((v1<v2) ? Edge(v1,v2) : Edge(v2,v1)); if(edgeMap.find(e) == edgeMap.end()) { // edge not in edgeMap so create a new one const unsigned int edgeIndex = (unsigned int)edgeMap.size(); /// add new edge edgeMap[e] = edgeIndex; // m_edge.push_back(e); m_edge.push_back(Edge(v1,v2)); } m_edgesInTriangle[i][j] = edgeMap[e]; } } } else { /// there are already existing edges : must use an inefficient method. Parse all triangles and find the edge that match each triangle edge helper::ReadAccessor< Data< sofa::helper::vector<Edge> > > m_edge = d_edge; const unsigned int numTriangles = getNumberOfTriangles(); const unsigned int numEdges = getNumberOfEdges(); m_edgesInTriangle.resize(numTriangles); /// create a multi map where the key is a vertex index and the content is the indices of edges adjacent to that vertex. std::multimap<PointID, EdgeID> edgesAroundVertexMap; std::multimap<PointID, EdgeID>::iterator it; bool foundEdge; for (unsigned int edge=0; edge<numEdges; ++edge) //Todo: check if not better using multimap <PointID ,TriangleID> and for each edge, push each triangle present in both shell { edgesAroundVertexMap.insert(std::pair<PointID, EdgeID> (m_edge[edge][0],edge)); edgesAroundVertexMap.insert(std::pair<PointID, EdgeID> (m_edge[edge][1],edge)); } for(unsigned int i=0; i<numTriangles; ++i) { const Triangle &t = m_triangle[i]; // adding edge i in the edge shell of both points for(unsigned int j=0; j<3; ++j) { //finding edge i in edge array std::pair<std::multimap<PointID, EdgeID>::iterator, std::multimap<PointID, EdgeID>::iterator > itPair=edgesAroundVertexMap.equal_range(t[(j+1)%3]); foundEdge=false; for(it=itPair.first; (it!=itPair.second) && (foundEdge==false); ++it) { unsigned int edge = (*it).second; if ( (m_edge[edge][0] == t[(j+1)%3] && m_edge[edge][1] == t[(j+2)%3]) || (m_edge[edge][0] == t[(j+2)%3] && m_edge[edge][1] == t[(j+1)%3])) { m_edgesInTriangle[i][j] = edge; foundEdge=true; } } #ifndef NDEBUG if (foundEdge==false) sout << "[TriangleSetTopologyContainer::getTriangleArray] cannot find edge for triangle " << i << "and edge "<< j << sendl; #endif } } } }
void ModelOBJ::generateTangents() { const int *pTriangle = 0; Vertex *pVertex0 = 0; Vertex *pVertex1 = 0; Vertex *pVertex2 = 0; float edge1[3] = {0.0f, 0.0f, 0.0f}; float edge2[3] = {0.0f, 0.0f, 0.0f}; float texEdge1[2] = {0.0f, 0.0f}; float texEdge2[2] = {0.0f, 0.0f}; float tangent[3] = {0.0f, 0.0f, 0.0f}; float bitangent[3] = {0.0f, 0.0f, 0.0f}; float det = 0.0f; float nDotT = 0.0f; float bDotB = 0.0f; float length = 0.0f; int totalVertices = getNumberOfVertices(); int totalTriangles = getNumberOfTriangles(); // Initialize all the vertex tangents and bitangents. for (int i = 0; i < totalVertices; ++i) { pVertex0 = &m_vertexBuffer[i]; pVertex0->tangent[0] = 0.0f; pVertex0->tangent[1] = 0.0f; pVertex0->tangent[2] = 0.0f; pVertex0->tangent[3] = 0.0f; pVertex0->bitangent[0] = 0.0f; pVertex0->bitangent[1] = 0.0f; pVertex0->bitangent[2] = 0.0f; } // Calculate the vertex tangents and bitangents. for (int i = 0; i < totalTriangles; ++i) { pTriangle = &m_indexBuffer[i * 3]; pVertex0 = &m_vertexBuffer[pTriangle[0]]; pVertex1 = &m_vertexBuffer[pTriangle[1]]; pVertex2 = &m_vertexBuffer[pTriangle[2]]; // Calculate the triangle face tangent and bitangent. edge1[0] = pVertex1->position[0] - pVertex0->position[0]; edge1[1] = pVertex1->position[1] - pVertex0->position[1]; edge1[2] = pVertex1->position[2] - pVertex0->position[2]; edge2[0] = pVertex2->position[0] - pVertex0->position[0]; edge2[1] = pVertex2->position[1] - pVertex0->position[1]; edge2[2] = pVertex2->position[2] - pVertex0->position[2]; texEdge1[0] = pVertex1->texCoord[0] - pVertex0->texCoord[0]; texEdge1[1] = pVertex1->texCoord[1] - pVertex0->texCoord[1]; texEdge2[0] = pVertex2->texCoord[0] - pVertex0->texCoord[0]; texEdge2[1] = pVertex2->texCoord[1] - pVertex0->texCoord[1]; det = texEdge1[0] * texEdge2[1] - texEdge2[0] * texEdge1[1]; if (fabs(det) < 1e-6f) { tangent[0] = 1.0f; tangent[1] = 0.0f; tangent[2] = 0.0f; bitangent[0] = 0.0f; bitangent[1] = 1.0f; bitangent[2] = 0.0f; } else { det = 1.0f / det; tangent[0] = (texEdge2[1] * edge1[0] - texEdge1[1] * edge2[0]) * det; tangent[1] = (texEdge2[1] * edge1[1] - texEdge1[1] * edge2[1]) * det; tangent[2] = (texEdge2[1] * edge1[2] - texEdge1[1] * edge2[2]) * det; bitangent[0] = (-texEdge2[0] * edge1[0] + texEdge1[0] * edge2[0]) * det; bitangent[1] = (-texEdge2[0] * edge1[1] + texEdge1[0] * edge2[1]) * det; bitangent[2] = (-texEdge2[0] * edge1[2] + texEdge1[0] * edge2[2]) * det; } // Accumulate the tangents and bitangents. pVertex0->tangent[0] += tangent[0]; pVertex0->tangent[1] += tangent[1]; pVertex0->tangent[2] += tangent[2]; pVertex0->bitangent[0] += bitangent[0]; pVertex0->bitangent[1] += bitangent[1]; pVertex0->bitangent[2] += bitangent[2]; pVertex1->tangent[0] += tangent[0]; pVertex1->tangent[1] += tangent[1]; pVertex1->tangent[2] += tangent[2]; pVertex1->bitangent[0] += bitangent[0]; pVertex1->bitangent[1] += bitangent[1]; pVertex1->bitangent[2] += bitangent[2]; pVertex2->tangent[0] += tangent[0]; pVertex2->tangent[1] += tangent[1]; pVertex2->tangent[2] += tangent[2]; pVertex2->bitangent[0] += bitangent[0]; pVertex2->bitangent[1] += bitangent[1]; pVertex2->bitangent[2] += bitangent[2]; } // Orthogonalize and normalize the vertex tangents. for (int i = 0; i < totalVertices; ++i) { pVertex0 = &m_vertexBuffer[i]; // Gram-Schmidt orthogonalize tangent with normal. nDotT = pVertex0->normal[0] * pVertex0->tangent[0] + pVertex0->normal[1] * pVertex0->tangent[1] + pVertex0->normal[2] * pVertex0->tangent[2]; pVertex0->tangent[0] -= pVertex0->normal[0] * nDotT; pVertex0->tangent[1] -= pVertex0->normal[1] * nDotT; pVertex0->tangent[2] -= pVertex0->normal[2] * nDotT; // Normalize the tangent. length = 1.0f / sqrtf(pVertex0->tangent[0] * pVertex0->tangent[0] + pVertex0->tangent[1] * pVertex0->tangent[1] + pVertex0->tangent[2] * pVertex0->tangent[2]); pVertex0->tangent[0] *= length; pVertex0->tangent[1] *= length; pVertex0->tangent[2] *= length; // Calculate the handedness of the local tangent space. // The bitangent vector is the cross product between the triangle face // normal vector and the calculated tangent vector. The resulting // bitangent vector should be the same as the bitangent vector // calculated from the set of linear equations above. If they point in // different directions then we need to invert the cross product // calculated bitangent vector. We store this scalar multiplier in the // tangent vector's 'w' component so that the correct bitangent vector // can be generated in the normal mapping shader's vertex shader. // // Normal maps have a left handed coordinate system with the origin // located at the top left of the normal map texture. The x coordinates // run horizontally from left to right. The y coordinates run // vertically from top to bottom. The z coordinates run out of the // normal map texture towards the viewer. Our handedness calculations // must take this fact into account as well so that the normal mapping // shader's vertex shader will generate the correct bitangent vectors. // Some normal map authoring tools such as Crazybump // (http://www.crazybump.com/) includes options to allow you to control // the orientation of the normal map normal's y-axis. bitangent[0] = (pVertex0->normal[1] * pVertex0->tangent[2]) - (pVertex0->normal[2] * pVertex0->tangent[1]); bitangent[1] = (pVertex0->normal[2] * pVertex0->tangent[0]) - (pVertex0->normal[0] * pVertex0->tangent[2]); bitangent[2] = (pVertex0->normal[0] * pVertex0->tangent[1]) - (pVertex0->normal[1] * pVertex0->tangent[0]); bDotB = bitangent[0] * pVertex0->bitangent[0] + bitangent[1] * pVertex0->bitangent[1] + bitangent[2] * pVertex0->bitangent[2]; pVertex0->tangent[3] = (bDotB < 0.0f) ? 1.0f : -1.0f; pVertex0->bitangent[0] = bitangent[0]; pVertex0->bitangent[1] = bitangent[1]; pVertex0->bitangent[2] = bitangent[2]; } m_hasTangents = true; }
void ModelOBJ::generateNormals() { const int *pTriangle = 0; Vertex *pVertex0 = 0; Vertex *pVertex1 = 0; Vertex *pVertex2 = 0; float edge1[3] = {0.0f, 0.0f, 0.0f}; float edge2[3] = {0.0f, 0.0f, 0.0f}; float normal[3] = {0.0f, 0.0f, 0.0f}; float length = 0.0f; int totalVertices = getNumberOfVertices(); int totalTriangles = getNumberOfTriangles(); // Initialize all the vertex normals. for (int i = 0; i < totalVertices; ++i) { pVertex0 = &m_vertexBuffer[i]; pVertex0->normal[0] = 0.0f; pVertex0->normal[1] = 0.0f; pVertex0->normal[2] = 0.0f; } // Calculate the vertex normals. for (int i = 0; i < totalTriangles; ++i) { pTriangle = &m_indexBuffer[i * 3]; pVertex0 = &m_vertexBuffer[pTriangle[0]]; pVertex1 = &m_vertexBuffer[pTriangle[1]]; pVertex2 = &m_vertexBuffer[pTriangle[2]]; // Calculate triangle face normal. edge1[0] = pVertex1->position[0] - pVertex0->position[0]; edge1[1] = pVertex1->position[1] - pVertex0->position[1]; edge1[2] = pVertex1->position[2] - pVertex0->position[2]; edge2[0] = pVertex2->position[0] - pVertex0->position[0]; edge2[1] = pVertex2->position[1] - pVertex0->position[1]; edge2[2] = pVertex2->position[2] - pVertex0->position[2]; normal[0] = (edge1[1] * edge2[2]) - (edge1[2] * edge2[1]); normal[1] = (edge1[2] * edge2[0]) - (edge1[0] * edge2[2]); normal[2] = (edge1[0] * edge2[1]) - (edge1[1] * edge2[0]); // Accumulate the normals. pVertex0->normal[0] += normal[0]; pVertex0->normal[1] += normal[1]; pVertex0->normal[2] += normal[2]; pVertex1->normal[0] += normal[0]; pVertex1->normal[1] += normal[1]; pVertex1->normal[2] += normal[2]; pVertex2->normal[0] += normal[0]; pVertex2->normal[1] += normal[1]; pVertex2->normal[2] += normal[2]; } // Normalize the vertex normals. for (int i = 0; i < totalVertices; ++i) { pVertex0 = &m_vertexBuffer[i]; length = 1.0f / sqrtf(pVertex0->normal[0] * pVertex0->normal[0] + pVertex0->normal[1] * pVertex0->normal[1] + pVertex0->normal[2] * pVertex0->normal[2]); pVertex0->normal[0] *= length; pVertex0->normal[1] *= length; pVertex0->normal[2] *= length; } m_hasNormals = true; }
void ManifoldTriangleSetTopologyContainer::createTrianglesAroundEdgeArray() { if(!hasTriangles()) // this method should only be called when triangles exist { #ifndef NDEBUG std::cout << "Warning. [ManifoldTriangleSetTopologyContainer::createTrianglesAroundEdgeArray] Triangle array is empty." << std::endl; #endif createTriangleSetArray(); } if(!hasEdges()) // this method should only be called when edges exist { #ifndef NDEBUG std::cout << "Warning. [ManifoldTriangleSetTopologyContainer::createTrianglesAroundEdgeArray] Edge array is empty." << std::endl; #endif createEdgeSetArray(); } if(!hasEdgesInTriangle()) createEdgesInTriangleArray(); if(hasTrianglesAroundEdge()) clearTrianglesAroundEdge(); //Number of different elements needed for this function const unsigned int nbrEdges = getNumberOfEdges(); const unsigned int nbrTriangles = getNumberOfTriangles(); //Temporary objects Triangle vertexTriangle; int cpt; int firstVertex; int vertexInTriangle; //Temporary containers std::multimap<unsigned int, unsigned int> map_edgesInTriangle; std::multimap<unsigned int, unsigned int>::iterator it; std::pair< std::multimap <unsigned int, unsigned int>::iterator, std::multimap <unsigned int, unsigned int>::iterator> pair_equal_range; helper::ReadAccessor< Data< sofa::helper::vector<Edge> > > m_edge = d_edge; helper::ReadAccessor< Data< sofa::helper::vector<Triangle> > > m_triangle = d_triangle; m_trianglesAroundEdge.resize(nbrEdges); for (unsigned int triangleIndex = 0; triangleIndex < nbrTriangles; ++triangleIndex) { // adding triangle i in the triangle shell of all edges for (unsigned int indexEdge = 0; indexEdge<3 ; ++indexEdge) { map_edgesInTriangle.insert(std::pair < unsigned int, unsigned int> (m_edgesInTriangle[triangleIndex][indexEdge], triangleIndex)); } } for (unsigned int indexEdge = 0; indexEdge < nbrEdges; indexEdge++) { cpt = map_edgesInTriangle.count(indexEdge); if (cpt > 2) { #ifndef NDEBUG std::cout << "Error. [ManifoldTriangleSetTopologyContainer::createTrianglesAroundEdgeArray] The mapping is not manifold."; std::cout << "There are more than 2 triangles adjacents to the Edge: " << indexEdge << std::endl; #endif //Even if this structure is not Manifold, we chosed to fill the shell with all the triangles: pair_equal_range = map_edgesInTriangle.equal_range(indexEdge); for (it = pair_equal_range.first; it != pair_equal_range.second; ++it) m_trianglesAroundEdge[indexEdge].push_back((*it).second); } else if (cpt == 1) { it = map_edgesInTriangle.find(indexEdge); m_trianglesAroundEdge[indexEdge].push_back((*it).second); } else if (cpt == 2) { pair_equal_range = map_edgesInTriangle.equal_range(indexEdge); it = pair_equal_range.first; firstVertex = m_edge[indexEdge][0]; vertexTriangle = m_triangle[(*it).second]; vertexInTriangle = getVertexIndexInTriangle (vertexTriangle, firstVertex); if ((unsigned int)m_edge[indexEdge][1] == (unsigned int)vertexTriangle[(vertexInTriangle+1)%3]) { m_trianglesAroundEdge[indexEdge].push_back((*it).second); it++; m_trianglesAroundEdge[indexEdge].push_back((*it).second); } else { it++; m_trianglesAroundEdge[indexEdge].push_back((*it).second); it--; m_trianglesAroundEdge[indexEdge].push_back((*it).second); } } } }
void ManifoldTriangleSetTopologyContainer::createTrianglesAroundVertexArray () { if(!hasTriangles()) // this method should only be called when triangles exist { #ifndef NDEBUG std::cout << "Warning. [ManifoldTriangleSetTopologyContainer::createTrianglesAroundVertexArray] triangle array is empty." << std::endl; #endif createTriangleSetArray(); } if(hasTrianglesAroundVertex()) { clearTrianglesAroundVertex(); } //Number of different elements needed for this function const unsigned int nbrVertices = getNbPoints(); const unsigned int nbrTriangles = getNumberOfTriangles(); //Temporary objects Triangle vertexTriangle; unsigned int cpt; unsigned int firstVertex; //Temporary containers sofa::helper::vector< std::map<unsigned int, unsigned int> > map_Triangles; sofa::helper::vector< std::map<unsigned int, unsigned int> > map_NextVertex; sofa::helper::vector< std::map<unsigned int, unsigned int> > map_PreviousVertex; std::map<unsigned int, unsigned int>::iterator it1; std::map<unsigned int, unsigned int>::iterator it2; m_trianglesAroundVertex.resize(nbrVertices); map_Triangles.resize(nbrVertices); map_NextVertex.resize(nbrVertices); map_PreviousVertex.resize(nbrVertices); /* Creation of the differents maps: For each vertex i of each triangles: - map_Triangles: key = vertex i+1, value = index triangle - map_Nextvertex: key = vertex i+1, value = vertex i+2 - map_PreviousVertex: key = vertex i+2, value = vertex i+1 */ for (unsigned int triangleIndex = 0; triangleIndex < nbrTriangles; ++triangleIndex) { vertexTriangle = getTriangleArray()[triangleIndex]; for (unsigned int i=0; i<3; ++i) { map_Triangles[vertexTriangle[i]].insert(std::pair<unsigned int,unsigned int> (vertexTriangle[(i+1)%3], triangleIndex)); //multi map_NextVertex[vertexTriangle[i]].insert(std::pair<unsigned int,unsigned int> (vertexTriangle[(i+1)%3], vertexTriangle[(i+2)%3])); map_PreviousVertex[vertexTriangle[i]].insert(std::pair<unsigned int,unsigned int> (vertexTriangle[(i+2)%3], vertexTriangle[(i+1)%3])); } } // General loop for m_trianglesAroundVertex creation for (unsigned int vertexIndex = 0; vertexIndex < nbrVertices; ++vertexIndex) { it1 = map_NextVertex[vertexIndex].begin(); firstVertex = (*it1).first; for (it1 = map_NextVertex[vertexIndex].begin(); it1 != map_NextVertex[vertexIndex].end(); ++it1) { it2 = map_PreviousVertex[vertexIndex].find((*it1).first); if (it2 == map_PreviousVertex[vertexIndex].end()) //it2 didn't find the it1 correspondant element in his map, means it's a border { firstVertex = (*it1).first; break; }//else we are not on a border. we keep the initialised value for firstVertex } m_trianglesAroundVertex[vertexIndex].push_back(map_Triangles[vertexIndex][firstVertex]); cpt=1; for (unsigned int i = 1; i < map_NextVertex[vertexIndex].size(); ++i) { it2 = map_NextVertex[vertexIndex].find(firstVertex); if (((*it2).first == firstVertex) && (it2 == map_NextVertex[vertexIndex].end())) { // Contour has been done without reaching the end of the map break; } firstVertex = (*it2).second; m_trianglesAroundVertex[vertexIndex].push_back(map_Triangles[vertexIndex][firstVertex]); cpt++; } if (cpt != map_Triangles[vertexIndex].size()) { #ifndef NDEBUG std::cout << "Error. [ManifoldTriangleSetTopologyContainer::createEdgesAroundVertexArray] The mapping is not manifold."; std::cout << "There is a wrong connection between triangles adjacent to the vertex: "<< vertexIndex << std::endl; #endif } } map_Triangles.clear(); map_NextVertex.clear(); map_PreviousVertex.clear(); }
void ManifoldTriangleSetTopologyContainer::createEdgesAroundVertexArray() { if(!hasEdges()) // this method should only be called when edges exist { #ifndef NDEBUG std::cout << "Warning. [ManifoldTriangleSetTopologyContainer::createEdgesAroundVertexArray] edge array is empty." << std::endl; #endif createEdgeSetArray(); } if(hasEdgesAroundVertex()) { clearEdgesAroundVertex(); } //Number of different elements needed for this function const unsigned int nbrVertices = getNbPoints(); const unsigned int nbrEdges = getNumberOfEdges(); const unsigned int nbrTriangles = getNumberOfTriangles(); //Temporary objects Triangle vertexTriangle; EdgesInTriangle edgeTriangle; int cpt; int firstVertex; int nextVertex; //Temporary containers sofa::helper::vector< std::multimap<unsigned int, unsigned int> > map_Adjacents; sofa::helper::vector< std::map<unsigned int, unsigned int> > map_NextEdgeVertex; sofa::helper::vector< std::map<unsigned int, unsigned int> > map_OppositeEdgeVertex; std::multimap<unsigned int, unsigned int>::iterator it_multimap; std::map<unsigned int, unsigned int>::iterator it_map; helper::ReadAccessor< Data< sofa::helper::vector<Edge> > > m_edge = d_edge; m_edgesAroundVertex.resize(nbrVertices); map_Adjacents.resize(nbrVertices); map_NextEdgeVertex.resize(nbrVertices); map_OppositeEdgeVertex.resize(nbrVertices); /* Creation of the differents maps: For each vertex i of each triangles: - map_NextEdgeVertex: key = vertex i+1, value = Edge i+2 - map_OppositeEdgeVertex: key = vertex i+1, value = vertex i+2 - map_Adjacents: key = vertex i+1 et i+2, value = Edge i */ for (unsigned int triangleIndex = 0; triangleIndex < nbrTriangles; triangleIndex++) { vertexTriangle = getTriangleArray()[triangleIndex]; edgeTriangle = getEdgesInTriangle(triangleIndex); for (unsigned int i=0; i<3; ++i) { map_NextEdgeVertex[vertexTriangle[i]].insert(std::pair<unsigned int,unsigned int> (vertexTriangle[(i+1)%3], edgeTriangle[(i+2)%3])); map_OppositeEdgeVertex[vertexTriangle[i]].insert(std::pair<unsigned int,unsigned int> (vertexTriangle[(i+1)%3], vertexTriangle[(i+2)%3])); map_Adjacents[vertexTriangle[i]].insert(std::pair<unsigned int,unsigned int> (vertexTriangle[(i+1)%3], edgeTriangle[i])); map_Adjacents[vertexTriangle[i]].insert(std::pair<unsigned int,unsigned int> (vertexTriangle[(i+2)%3], edgeTriangle[i])); } } for (unsigned int vertexIndex = 0; vertexIndex < nbrVertices; vertexIndex++) { it_map = map_OppositeEdgeVertex[vertexIndex].begin(); firstVertex = (*it_map).first; for (it_multimap = map_Adjacents[vertexIndex].begin(); it_multimap != map_Adjacents[vertexIndex].end(); it_multimap++) { cpt = (int)map_Adjacents[vertexIndex].count((*it_multimap).first); if( cpt > 2) { //#ifndef NDEBUG std::cout << "Error. [ManifoldTriangleSetTopologyContainer::createEdgesAroundVertexArray] The mapping is not manifold. "; std::cout << "In the neighborhood of the vertex: " << vertexIndex; std::cout << ". There are " << cpt << " edges connected to the vertex: " << (*it_multimap).first << std::endl; //#endif } else if ( cpt == 1) { it_map = map_OppositeEdgeVertex[vertexIndex].find( (*it_multimap).first ); if(it_map != map_OppositeEdgeVertex[vertexIndex].end()) { firstVertex = (*it_map).first; } } } m_edgesAroundVertex[vertexIndex].push_back(map_NextEdgeVertex[vertexIndex][firstVertex]); nextVertex = (*(it_map = map_OppositeEdgeVertex[vertexIndex].find(firstVertex))).second; for (unsigned int indexEdge = 1; indexEdge < map_OppositeEdgeVertex[vertexIndex].size(); indexEdge++) { m_edgesAroundVertex[vertexIndex].push_back(map_NextEdgeVertex[vertexIndex][nextVertex]); nextVertex = (*(it_map = map_OppositeEdgeVertex[vertexIndex].find(nextVertex))).second; //std::cout << "nextVertex: " << nextVertex << std::endl; //si different de fin } if (nextVertex != firstVertex) { const Edge lastEdge = Edge(nextVertex,vertexIndex); for ( unsigned int i = 0; i < nbrEdges; ++i) { if( m_edge[i][0] == lastEdge[0] && m_edge[i][1] == lastEdge[1]) { m_edgesAroundVertex[vertexIndex].push_back(i); break; } } } } map_Adjacents.clear(); map_NextEdgeVertex.clear(); map_OppositeEdgeVertex.clear(); }