Ejemplo n.º 1
0
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 );
    }
}
Ejemplo n.º 3
0
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 );
			}
		}
	}
Ejemplo n.º 7
0
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();
}