void Convexe2D::ajoutPointConvex(const Vector2D& p) { int nbP = getNbPoints(); if(nbP < 2) { _points.push_back(p); return; } int deb, fin; if(findIndicesCoupe(p,deb,fin)) { int i = (deb+1)%nbP; if(i == fin) _points.insert(fin, p); //on a juste à supprimer le segment entre deux points et à relier ces dernier au point à ajouter else { //sinon, on enlève les points entre l'index de debut de découpe et l'index de fin de découpe if(i < fin) //on ne repasse pas par le point 0 { _points[i] = p; _points.remove(i+1, fin-i-1); } else //sinon, on enlève ce qui est avant indice fin et après l'indice deb { _points.remove(i, nbP-i); if(fin != 0) _points.remove(0,fin); _points.push_back(p); } } } }
void TriangleSetTopologyContainer::createTrianglesAroundVertexArray () { if(!hasTriangles()) // this method should only be called when triangles exist { #ifndef NDEBUG sout << "Warning. [TriangleSetTopologyContainer::createTrianglesAroundVertexArray] triangle array is empty." << sendl; #endif createTriangleSetArray(); } if(hasTrianglesAroundVertex()) { clearTrianglesAroundVertex(); } m_trianglesAroundVertex.resize( getNbPoints() ); helper::ReadAccessor< Data< sofa::helper::vector<Triangle> > > m_triangle = d_triangle; for (unsigned int i = 0; i < m_triangle.size(); ++i) { // adding edge i in the edge shell of both points for (unsigned int j=0; j<3; ++j) m_trianglesAroundVertex[ m_triangle[i][j] ].push_back( i ); } }
Convexe2D::Convexe2D(const QVector<Vector2D>& points) { if(points.size() < 3) { _points = points; initMinMaxCentre(); setLinked(true); return; } int i0, i1, i2; if(!initNonAlignee(points, i0,i1,i2)) //si tous les points sont alignés { _points.push_back(points[i0]); _points.push_back(points[i1]); _min = min(points[i0], points[i1]); _max = max(points[i0], points[i1]); _centre =(_min+_max)/2; setLinked(true); return; } initTriangle(points[i0],points[i1],points[i2]); for(int i=i2+1; i< points.size(); i++){ ajoutPointConvex(points[i]); #ifdef DEBUG_PROBLEME if(i == -1) //pour le débug, retrouver un indice précis où il y a un problème std::cout << "ici" << std::endl; else for(int i3 = 0; i3 < getNbPoints(); i3++) { if(inHalfSpaceDroit(_points[i3], _points[(i3+1)%getNbPoints()], _points[(i3+2)%getNbPoints()])) std::cout << "problème " << i3 << " -> " << getNbPoints() << " => " << i << std::endl; } #endif } initMinMaxCentre(); setLinked(true); }
const sofa::helper::vector<TriangleSetTopologyContainer::Triangle> & TriangleSetTopologyContainer::getTriangleArray() { if(!hasTriangles() && getNbPoints()>0) { #ifndef NDEBUG sout << "[TriangleSetTopologyContainer::getTriangleArray] creating triangle array." << sendl; #endif createTriangleSetArray(); } return d_triangle.getValue(); }
const sofa::helper::vector<Tetrahedron> &TetrahedronSetTopologyContainer::getTetrahedronArray() { if (!hasTetrahedra() && getNbPoints()>0) { #ifndef NDEBUG sout << "[TetrahedronSetTopologyContainer::getTetrahedronArray] creating tetrahedron array." << endl; #endif createTetrahedronSetArray(); } return d_tetrahedron.getValue(); }
void TetrahedronSetTopologyContainer::createTetrahedraAroundVertexArray () { if(hasTetrahedraAroundVertex()) clearTetrahedraAroundVertex(); m_tetrahedraAroundVertex.resize( getNbPoints() ); helper::ReadAccessor< Data< sofa::helper::vector<Tetrahedron> > > m_tetrahedron = d_tetrahedron; for (unsigned int i = 0; i < getNumberOfTetrahedra(); ++i) { // adding edge i in the edge shell of both points for (unsigned int j=0; j<4; ++j) { m_tetrahedraAroundVertex[ m_tetrahedron[i][j] ].push_back( i ); } } }
bool Convexe2D::findIndicesCoupe(const Vector2D& p, int& deb, int& fin) { //if(p.x == 0.5) // deb = -1; int i = 0, i2 = (i+1)%getNbPoints(); int cote = inHalfSpaceDroit(_points[i], _points[i2], p); bool startOut; //indique si le segment 0<->1 n'est pas compris dans la zone à couper. if(cote == ALIGNEE){ int cote2 = coteAlignement(p, _points[i], _points[i2]); if(cote2 == 0) return false; //le point à ajouter est sur l'enveloppe convexe. Il n'y a pas à l'ajouter à l'enveloppe. else if(cote2 == -1) startOut = false; else startOut = true; } else if(cote == GAUCHE) startOut = true; else //droit startOut = false; if(startOut) { if(cote == ALIGNEE) deb = 0; else { for(i = 1; i < getNbPoints(); i++) { i2 = (i+1)%getNbPoints(); int cote1 = inHalfSpaceDroit(_points[i], _points[i2], p); if(cote1 == ALIGNEE){ if(coteAlignement(p, _points[i], _points[i2]) == 0) return false; //le point à ajouter est sur l'enveloppe convexe. Il n'y a pas à l'ajouter à l'enveloppe. else break; //on commence la coupe au point i } else if(cote1 == DROIT) break; //on conmmence la coupe au point i } if(i == getNbPoints()) return false; //le points est à l'interieur de l'enveloppe deb = i; } for(i = deb+1; i < getNbPoints(); i++) { i2 = (i+1)%getNbPoints(); cote = inHalfSpaceDroit(_points[i], _points[i2], p); if(cote == ALIGNEE){ if(coteAlignement(p, _points[i], _points[i2]) == 0) return false; //le point à ajouter est sur l'enveloppe convexe. Il n'y a pas à l'ajouter à l'enveloppe. else{ i++; break; //on termine la coupe au point i } } else if(cote == GAUCHE) break; //on termine la coupe au point i } fin = (i == getNbPoints() ? 0 : i); } else { for(i = getNbPoints()-1; i > 2; i--) { i2 = (i+1)%getNbPoints(); int cote1 = inHalfSpaceDroit(_points[i], _points[i2], p); if(cote1 == ALIGNEE){ if(coteAlignement(p, _points[i], _points[i2]) == 0) return false; //le point à ajouter est sur l'enveloppe convexe. Il n'y a pas à l'ajouter à l'enveloppe. else { i--; break; //on commence la coupe au point i2 } } else if(cote1 == GAUCHE) break; //on conmmence la coupe au point i2 } deb = (i+1)%getNbPoints(); if(cote == ALIGNEE) fin = 1; else { for(i = 1; i < getNbPoints()-1; i++) { i2 = (i+1)%getNbPoints(); cote = inHalfSpaceDroit(_points[i], _points[i2], p); if(cote == ALIGNEE){ if(coteAlignement(p, _points[i], _points[i2]) == 0) return false; //le point à ajouter est sur l'enveloppe convexe. Il n'y a pas à l'ajouter à l'enveloppe. else{ i++; break; //on termine la coupe au point i } } else if(cote == GAUCHE) break; //on termine la coupe au point i } fin = i; } } return true; }
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(); }