void TriangleSetTopologyContainer::clear()
{
    clearTrianglesAroundVertex();
    clearTrianglesAroundEdge();
    clearEdgesInTriangle();
    clearTriangles();
    clearBorderElementLists();
    EdgeSetTopologyContainer::clear();
}
void ManifoldTriangleSetTopologyContainer::createEdgeSetArray()
{

    if(!hasTriangles()) // this method should only be called when triangles exist
    {
#ifndef NDEBUG
        std::cout << "Warning. [ManifoldTriangleSetTopologyContainer::createEdgeSetArray] triangle array is empty." << std::endl;
#endif
        createTriangleSetArray();
    }

    if(hasEdges())
    {
#ifndef NDEBUG
        std::cout << "Warning. [ManifoldTriangleSetTopologyContainer::createEdgeSetArray] edge array is not empty." << std::endl;
#endif

        // clear edges and all shells that depend on edges
        EdgeSetTopologyContainer::clear();

        if(hasEdgesInTriangle())
            clearEdgesInTriangle();

        if(hasTrianglesAroundEdge())
            clearTrianglesAroundEdge();
    }


    // 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;
    helper::ReadAccessor< Data< sofa::helper::vector<Triangle> > > m_triangle = d_triangle;

    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];

            const Edge e = ((v1<v2) ? Edge(v1,v2) : Edge(v2,v1));
            const Edge real_e = Edge(v1,v2);

            if(edgeMap.find(e) == edgeMap.end())
            {
                // edge not in edgeMap so create a new one
                const int edgeIndex = edgeMap.size();
                edgeMap[e] = edgeIndex;
                m_edge.push_back(real_e);
            }

        }
    }

}
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
            }
        }
    }
}