void HexahedronSetTopologyModifier::addHexahedronProcess(Hexahedron t)
{
#ifndef NDEBUG
    // check if the 8 vertices are different
    assert(t[0]!=t[1]); assert(t[0]!=t[2]); assert(t[0]!=t[3]); assert(t[0]!=t[4]); assert(t[0]!=t[5]); assert(t[0]!=t[6]); assert(t[0]!=t[7]);
    assert(t[1]!=t[2]); assert(t[1]!=t[3]); assert(t[1]!=t[4]); assert(t[1]!=t[5]); assert(t[1]!=t[6]); assert(t[1]!=t[7]);
    assert(t[2]!=t[3]); assert(t[2]!=t[4]); assert(t[2]!=t[5]); assert(t[2]!=t[6]); assert(t[2]!=t[7]);
    assert(t[3]!=t[4]); assert(t[3]!=t[5]); assert(t[3]!=t[6]); assert(t[3]!=t[7]);
    assert(t[4]!=t[5]); assert(t[4]!=t[6]); assert(t[4]!=t[7]);
    assert(t[5]!=t[6]); assert(t[5]!=t[7]);
    assert(t[6]!=t[7]);

    // check if there already exists a hexahedron with the same indices
    assert(m_container->getHexahedronIndex(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7])== -1);
#endif
    const unsigned int hexahedronIndex = m_container->getNumberOfHexahedra();
    helper::WriteAccessor< Data< sofa::helper::vector<Hexahedron> > > m_hexahedron = m_container->d_hexahedron;

    if(m_container->hasQuadsInHexahedron())
    {
        int quadIndex;

        // Quad 0 :
        quadIndex=m_container->getQuadIndex(t[0],t[3],t[2],t[1]);
        //assert(quadIndex!= -1);
        if(quadIndex == -1)
        {
            // first create the quad
            sofa::helper::vector< Quad > v;
            Quad e1 (t[0],t[3],t[2],t[1]);
            v.push_back(e1);

            addQuadsProcess((const sofa::helper::vector< Quad > &) v);

            quadIndex=m_container->getQuadIndex(t[0],t[3],t[2],t[1]);
            sofa::helper::vector< unsigned int > quadIndexList;
            quadIndexList.push_back(quadIndex);
            addQuadsWarning((unsigned int)v.size(), v, quadIndexList);
        }
        m_container->m_quadsInHexahedron.resize(hexahedronIndex+1);
        m_container->m_quadsInHexahedron[hexahedronIndex][0]=quadIndex;

        // Quad 1 :
        quadIndex=m_container->getQuadIndex(t[4],t[5],t[6],t[7]);
        //assert(quadIndex!= -1);
        if(quadIndex == -1)
        {
            // first create the quad
            sofa::helper::vector< Quad > v;
            Quad e1 (t[4],t[5],t[6],t[7]);
            v.push_back(e1);

            addQuadsProcess((const sofa::helper::vector< Quad > &) v);

            quadIndex=m_container->getQuadIndex(t[4],t[5],t[6],t[7]);
            sofa::helper::vector< unsigned int > quadIndexList;
            quadIndexList.push_back(quadIndex);
            addQuadsWarning((unsigned int)v.size(), v, quadIndexList);
        }
        m_container->m_quadsInHexahedron.resize(hexahedronIndex+1);
        m_container->m_quadsInHexahedron[hexahedronIndex][1]=quadIndex;

        // Quad 2 :
        quadIndex=m_container->getQuadIndex(t[0],t[1],t[5],t[4]);
        //assert(quadIndex!= -1);
        if(quadIndex == -1)
        {
            // first create the quad
            sofa::helper::vector< Quad > v;
            Quad e1 (t[0],t[1],t[5],t[4]);
            v.push_back(e1);

            addQuadsProcess((const sofa::helper::vector< Quad > &) v);

            quadIndex=m_container->getQuadIndex(t[0],t[1],t[5],t[4]);
            sofa::helper::vector< unsigned int > quadIndexList;
            quadIndexList.push_back(quadIndex);
            addQuadsWarning((unsigned int)v.size(), v, quadIndexList);
        }
        m_container->m_quadsInHexahedron.resize(hexahedronIndex+1);
        m_container->m_quadsInHexahedron[hexahedronIndex][2]=quadIndex;

        // Quad 3 :
        quadIndex=m_container->getQuadIndex(t[1],t[2],t[6],t[5]);
        //assert(quadIndex!= -1);
        if(quadIndex == -1)
        {
            // first create the quad
            sofa::helper::vector< Quad > v;
            Quad e1 (t[1],t[2],t[6],t[5]);
            v.push_back(e1);

            addQuadsProcess((const sofa::helper::vector< Quad > &) v);

            quadIndex=m_container->getQuadIndex(t[1],t[2],t[6],t[5]);
            sofa::helper::vector< unsigned int > quadIndexList;
            quadIndexList.push_back(quadIndex);
            addQuadsWarning((unsigned int)v.size(), v, quadIndexList);
        }
        m_container->m_quadsInHexahedron.resize(hexahedronIndex+1);
        m_container->m_quadsInHexahedron[hexahedronIndex][3]=quadIndex;

        // Quad 4 :
        quadIndex=m_container->getQuadIndex(t[2],t[3],t[7],t[6]);
        //assert(quadIndex!= -1);
        if(quadIndex == -1)
        {
            // first create the quad
            sofa::helper::vector< Quad > v;
            Quad e1 (t[2],t[3],t[7],t[6]);
            v.push_back(e1);

            addQuadsProcess((const sofa::helper::vector< Quad > &) v);

            quadIndex=m_container->getQuadIndex(t[2],t[3],t[7],t[6]);
            sofa::helper::vector< unsigned int > quadIndexList;
            quadIndexList.push_back(quadIndex);
            addQuadsWarning((unsigned int)v.size(), v, quadIndexList);
        }
        m_container->m_quadsInHexahedron.resize(hexahedronIndex+1);
        m_container->m_quadsInHexahedron[hexahedronIndex][4]=quadIndex;

        // Quad 5 :
        quadIndex=m_container->getQuadIndex(t[3],t[0],t[4],t[7]);
        //assert(quadIndex!= -1);
        if(quadIndex == -1)
        {
            // first create the quad
            sofa::helper::vector< Quad > v;
            Quad e1 (t[3],t[0],t[4],t[7]);
            v.push_back(e1);

            addQuadsProcess((const sofa::helper::vector< Quad > &) v);

            quadIndex=m_container->getQuadIndex(t[3],t[0],t[4],t[7]);
            sofa::helper::vector< unsigned int > quadIndexList;
            quadIndexList.push_back(quadIndex);
            addQuadsWarning((unsigned int)v.size(), v, quadIndexList);
        }
        m_container->m_quadsInHexahedron.resize(hexahedronIndex+1);
        m_container->m_quadsInHexahedron[hexahedronIndex][5]=quadIndex;

        if(m_container->hasHexahedraAroundQuad())
        {
            for(unsigned int q=0; q<6; ++q)
            {
                sofa::helper::vector< unsigned int > &shell = m_container->m_hexahedraAroundQuad[m_container->m_quadsInHexahedron[hexahedronIndex][q]];
                shell.push_back( hexahedronIndex );
            }
        }
    } // quads

    if(m_container->hasEdgesInHexahedron())
    {
        m_container->m_edgesInHexahedron.resize(hexahedronIndex+1);
        for(unsigned int edgeIdx=0; edgeIdx<12; ++edgeIdx)
        {
            unsigned p0 = edgesInHexahedronArray[edgeIdx][0];
            unsigned p1 = edgesInHexahedronArray[edgeIdx][1];

            int edgeIndex=m_container->getEdgeIndex(t[p0],t[p1]);

            // we must create the edge
            if (edgeIndex==-1)
            {
                sofa::helper::vector< Edge > v;
                Edge e1(t[p0],t[p1]);
                v.push_back(e1);

                addEdgesProcess((const sofa::helper::vector< Edge > &) v);

                edgeIndex=m_container->getEdgeIndex(t[p0],t[p1]);

                sofa::helper::vector< unsigned int > edgeIndexList;
                edgeIndexList.push_back(edgeIndex);
                addEdgesWarning((unsigned int)v.size(), v, edgeIndexList);
            }

            m_container->m_edgesInHexahedron[hexahedronIndex][edgeIdx]= edgeIndex;
        }

        if(m_container->hasHexahedraAroundEdge())
        {
            for(unsigned int e=0; e<12; ++e)
            {
                sofa::helper::vector< unsigned int > &shell = m_container->m_hexahedraAroundEdge[m_container->m_edgesInHexahedron[hexahedronIndex][e]];
                shell.push_back( hexahedronIndex );
            }
        }
    } // edges

    if(m_container->hasHexahedraAroundVertex())
    {
        for(unsigned int v=0; v<8; ++v)
        {
            sofa::helper::vector< unsigned int > &shell = m_container->getHexahedraAroundVertexForModification( t[v] );
            shell.push_back( hexahedronIndex );
        }
    }

    m_hexahedron.push_back(t);
}
      void TriangleSetTopologyModifier::addTriangleProcess(Triangle t)
      {

#ifndef NDEBUG
	// check if the 3 vertices are different
	if((t[0]==t[1]) || (t[0]==t[2]) || (t[1]==t[2]) )
	{
	  sout << "Error: [TriangleSetTopologyModifier::addTriangle] : invalid quad: "
	       << t[0] << ", " << t[1] << ", " << t[2] <<  endl;
	  return;
	}

	// check if there already exists a triangle with the same indices
	// Important: getEdgeIndex creates the quad vertex shell array
	if(m_container->hasTrianglesAroundVertex())
	{
	  if(m_container->getTriangleIndex(t[0],t[1],t[2]) != -1)
	  {
	    sout << "Error: [TriangleSetTopologyModifier::addTriangle] : Triangle "
		 << t[0] << ", " << t[1] << ", " << t[2] << " already exists." << endl;
	    return;
	  }
	}
#endif

	const unsigned int triangleIndex = m_container->getNumberOfTriangles();
	helper::WriteAccessor< Data< sofa::helper::vector<Triangle> > > m_triangle = m_container->d_triangle;

	if(m_container->hasTrianglesAroundVertex())
	{
	  for(unsigned int j=0; j<3; ++j)
	  {
	    sofa::helper::vector< unsigned int > &shell = m_container->getTrianglesAroundVertexForModification( t[j] );
	    shell.push_back( triangleIndex );
	  }
	}

	if(m_container->hasEdges())
	{
	  for(unsigned int j=0; j<3; ++j)
	  {
	    int edgeIndex = m_container->getEdgeIndex(t[(j+1)%3], t[(j+2)%3]);

	    if(edgeIndex == -1)
	    {
	      // first create the edges
	      sofa::helper::vector< Edge > v(1);
	      Edge e1 (t[(j+1)%3], t[(j+2)%3]);
	      v[0] = e1;

	      addEdgesProcess((const sofa::helper::vector< Edge > &) v);

	      edgeIndex = m_container->getEdgeIndex(t[(j+1)%3],t[(j+2)%3]);
	      sofa::helper::vector< unsigned int > edgeIndexList;
	      edgeIndexList.push_back((unsigned int) edgeIndex);
	      addEdgesWarning( v.size(), v, edgeIndexList);
	    }

	    if(m_container->hasEdgesInTriangle())
	    {
	      m_container->m_edgesInTriangle.resize(triangleIndex+1);
	      m_container->m_edgesInTriangle[triangleIndex][j]= edgeIndex;
	    }

	    if(m_container->hasTrianglesAroundEdge())
	    {
	      sofa::helper::vector< unsigned int > &shell = m_container->m_trianglesAroundEdge[m_container->m_edgesInTriangle[triangleIndex][j]];
	      shell.push_back( triangleIndex );
	    }
	  }
	}

	m_triangle.push_back(t);
      }
void QuadSetTopologyModifier::addQuadProcess(Quad t)
{
#ifndef NDEBUG
    // check if the 4 vertices are different
    if((t[0]==t[1]) || (t[0]==t[2]) || (t[0]==t[3])
       || (t[1]==t[2]) || (t[1]==t[3]) || (t[2]==t[3]))
    {
        sout << "Error: [QuadSetTopologyModifier::addQuad] : invalid quad: "
                << t[0] << ", " << t[1] << ", " << t[2] <<  ", " << t[3] <<  endl;

        return;
    }

    // check if there already exists a quad with the same indices
    // Important: getEdgeIndex creates the quad vertex shell array
    if(m_container->hasQuadsAroundVertex())
    {
        if(m_container->getQuadIndex(t[0],t[1],t[2],t[3]) != -1)
        {
            sout << "Error: [QuadSetTopologyModifier::addQuad] : Quad "
                    << t[0] << ", " << t[1] << ", " << t[2] <<  ", " << t[3] << " already exists." << endl;
            return;
        }
    }
#endif

    const unsigned int quadIndex = m_container->getNumberOfQuads();

    if(m_container->hasQuadsAroundVertex())
    {
        for(unsigned int j=0; j<4; ++j)
        {
            sofa::helper::vector< unsigned int > &shell = m_container->getQuadsAroundVertexForModification( t[j] );
            shell.push_back( quadIndex );
        }
    }

    helper::WriteAccessor< Data< sofa::helper::vector<Quad> > > m_quad = m_container->d_quad;

    if(m_container->hasEdges())
    {
        for(unsigned int j=0; j<4; ++j)
        {
            int edgeIndex = m_container->getEdgeIndex(t[(j+1)%4], t[(j+2)%4]);

            if(edgeIndex == -1)
            {
                // first create the edges
                sofa::helper::vector< Edge > v(1);
                Edge e1 (t[(j+1)%4], t[(j+2)%4]);
                v[0] = e1;

                addEdgesProcess((const sofa::helper::vector< Edge > &) v);

                edgeIndex = m_container->getEdgeIndex(t[(j+1)%4],t[(j+2)%4]);
                sofa::helper::vector< unsigned int > edgeIndexList;
                edgeIndexList.push_back((unsigned int) edgeIndex);
                addEdgesWarning((unsigned int)v.size(), v, edgeIndexList);
            }

            if(m_container->hasEdgesInQuad())
            {
                m_container->m_edgesInQuad.resize(quadIndex+1);
                m_container->m_edgesInQuad[quadIndex][j]= edgeIndex;
            }

            if(m_container->hasQuadsAroundEdge())
            {
                sofa::helper::vector< unsigned int > &shell = m_container->m_quadsAroundEdge[m_container->m_edgesInQuad[quadIndex][j]];
                shell.push_back( quadIndex );
            }
        }
    }

    m_quad.push_back(t);
}