diff --git a/Geo/MElementCut.cpp b/Geo/MElementCut.cpp
index 44ad5151f0a846db45f22a0e0f190baf446a4e3a..9455547eb79f730feb403eb214a3a89ec900329a 100644
--- a/Geo/MElementCut.cpp
+++ b/Geo/MElementCut.cpp
@@ -461,23 +461,40 @@ static int getBorderTag(int lsTag, int count, int &elementaryMax, std::map<int,
     borderTags[lsTag] = reg;
     return reg;
   }
+  elementaryMax = std::max(elementaryMax, lsTag);
   borderTags[lsTag] = lsTag;
   return lsTag;
 }
 
-static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM, 
+static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
                            int &numEle, std::map<int, MVertex*> &vertexMap,
                            std::vector<MVertex*> &newVertices,
                            std::map<int, std::vector<MElement*> > elements[10],
                            std::map<int, std::map<int, std::string> > physicals[4],
                            std::map<int, int> borderTags[2],
-                           std::map<int, int> newtags[4])
+                           std::map<int, int> newtags[4],
+                           std::vector<DI_CuttingPoint> &cp,
+                           std::vector<DI_Line> &lines,
+                           std::vector<DI_Triangle> &triangles,
+                           std::vector<DI_Quad> &quads,
+                           std::vector<DI_Tetra> &tetras,
+                           std::vector<DI_Hexa> &hexas)
 {
   int elementary = ge->tag();
   int eType = e->getTypeForMSH();
   int ePart = e->getPartition();
   std::vector<int> gePhysicals = ge->physicals;
 
+  int integOrder = 1;
+  std::vector<DI_IntegrationPoint> ipV;
+  std::vector<DI_IntegrationPoint> ipS;
+  bool isCut = false;
+  unsigned int nbL = lines.size();
+  unsigned int nbTr = triangles.size();
+  unsigned int nbQ = quads.size();
+  unsigned int nbTe = tetras.size();
+  unsigned int nbH = hexas.size();
+
   // copy element
   std::vector<MVertex*> vmv;
   if(eType != MSH_POLYG_ && eType != MSH_POLYH_) {
@@ -518,23 +535,13 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
   case MSH_PRI_6 :
   case MSH_POLYH_ :
     {
-      std::vector<DI_CuttingPoint> cp;
-      std::vector<DI_Tetra> subTetras;
-      std::vector<DI_Hexa> subHexas;
-      std::vector<DI_Quad> surfQuads;
-      std::vector<DI_Triangle> surfTriangles;
-      std::vector<DI_Line> boundLines;
-      int integOrder = 1;
-      std::vector<DI_IntegrationPoint> ipV;
-      std::vector<DI_IntegrationPoint> ipS;
-
       if(eType == MSH_TET_4) {
         DI_Tetra T(e->getVertex(0)->x(), e->getVertex(0)->y(), e->getVertex(0)->z(),
                    e->getVertex(1)->x(), e->getVertex(1)->y(), e->getVertex(1)->z(),
                    e->getVertex(2)->x(), e->getVertex(2)->y(), e->getVertex(2)->z(),
                    e->getVertex(3)->x(), e->getVertex(3)->y(), e->getVertex(3)->z());
-        T.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
-              subTetras, surfQuads, surfTriangles);
+        isCut = T.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
+                      tetras, quads, triangles);
       }
       else if(eType == MSH_HEX_8){
         DI_Hexa H(e->getVertex(0)->x(), e->getVertex(0)->y(), e->getVertex(0)->z(),
@@ -545,8 +552,8 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
                   e->getVertex(5)->x(), e->getVertex(5)->y(), e->getVertex(5)->z(),
                   e->getVertex(6)->x(), e->getVertex(6)->y(), e->getVertex(6)->z(),
                   e->getVertex(7)->x(), e->getVertex(7)->y(), e->getVertex(7)->z());
-        H.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder, integOrder,
-              subHexas, subTetras, surfQuads, surfTriangles, boundLines);
+        isCut = H.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder, integOrder,
+                      hexas, tetras, quads, triangles, lines);
       }
       else if(eType == MSH_PRI_6){
         DI_Tetra T1(e->getVertex(0)->x(), e->getVertex(0)->y(), e->getVertex(0)->z(),
@@ -561,12 +568,13 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
                     e->getVertex(3)->x(), e->getVertex(3)->y(), e->getVertex(3)->z(),
                     e->getVertex(4)->x(), e->getVertex(4)->y(), e->getVertex(4)->z(),
                     e->getVertex(5)->x(), e->getVertex(5)->y(), e->getVertex(5)->z());
-        T1.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
-               subTetras, surfQuads, surfTriangles);
-        T2.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
-               subTetras, surfQuads, surfTriangles);
-        T3.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
-               subTetras, surfQuads, surfTriangles);
+        bool iC1 = T1.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
+                          tetras, quads, triangles);
+        bool iC2 = T2.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
+                          tetras, quads, triangles);
+        bool iC3 = T3.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
+                          tetras, quads, triangles);
+        isCut = iC1 || iC2 || iC3;
       }
       else if(eType == MSH_PYR_5){
         DI_Tetra T1(e->getVertex(0)->x(), e->getVertex(0)->y(), e->getVertex(0)->z(),
@@ -577,10 +585,11 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
                     e->getVertex(2)->x(), e->getVertex(2)->y(), e->getVertex(2)->z(),
                     e->getVertex(3)->x(), e->getVertex(3)->y(), e->getVertex(3)->z(),
                     e->getVertex(4)->x(), e->getVertex(4)->y(), e->getVertex(4)->z());
-        T1.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
-               subTetras, surfQuads, surfTriangles);
-        T2.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
-               subTetras, surfQuads, surfTriangles);
+        bool iC1 = T1.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
+                          tetras, quads, triangles);
+        bool iC2 = T2.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
+                          tetras, quads, triangles);
+        isCut = iC1 || iC2;
       }
       else if(eType == MSH_POLYH_){
         for(int i = 0; i < e->getNumChildren(); i++) {
@@ -589,30 +598,27 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
                        t->getVertex(1)->x(), t->getVertex(1)->y(), t->getVertex(1)->z(),
                        t->getVertex(2)->x(), t->getVertex(2)->y(), t->getVertex(2)->z(),
                        t->getVertex(3)->x(), t->getVertex(3)->y(), t->getVertex(3)->z());
-          Tet.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
-                  subTetras, surfQuads, surfTriangles);
+          bool iC = Tet.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
+                            tetras, quads, triangles);
+          isCut = (isCut || iC);
         }
       }
 
-      // if cut
-      if((eType == MSH_TET_4 && subTetras.size() > 1) ||
-         (eType == MSH_HEX_8 && subTetras.size() > 6) ||
-         (eType == MSH_PRI_6 && subTetras.size() > 3) ||
-         (eType == MSH_PYR_5 && subTetras.size() > 2) ||
-         (eType == MSH_POLYH_ && subTetras.size() > e->getNumChildren())) {
+      MPolyhedron *p1 = NULL, *p2 = NULL;
+      if(isCut) {
         std::vector<MTetrahedron*> poly[2];
         
-        for (unsigned int i = 0; i < subTetras.size(); i++){
+        for (unsigned int i = nbTe; i < tetras.size(); i++){
           MVertex *mv[4] = {NULL, NULL, NULL, NULL};
           for(int j = 0; j < 4; j++){
-            int numV = getElementVertexNum(subTetras[i].pt(j), e);
+            int numV = getElementVertexNum(tetras[i].pt(j), e);
             if(numV == -1) {
               unsigned int k;
               for(k = 0; k < newVertices.size(); k++)
-                if(equalV(newVertices[k], subTetras[i].pt(j))) break;
+                if(equalV(newVertices[k], tetras[i].pt(j))) break;
               if(k == newVertices.size()) {
-                mv[j] = new MVertex(subTetras[i].x(j), subTetras[i].y(j),
-                                    subTetras[i].z(j), 0);
+                mv[j] = new MVertex(tetras[i].x(j), tetras[i].y(j),
+                                    tetras[i].z(j), 0);
                 newVertices.push_back(mv[j]);
               }
               else mv[j] = newVertices[k];
@@ -620,65 +626,33 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
             else {
               std::map<int, MVertex*>::iterator it = vertexMap.find(numV);
               if(it == vertexMap.end()) {
-                mv[j] = new MVertex(subTetras[i].x(j), subTetras[i].y(j),
-                                    subTetras[i].z(j), 0, numV);
+                mv[j] = new MVertex(tetras[i].x(j), tetras[i].y(j),
+                                    tetras[i].z(j), 0, numV);
                 vertexMap[numV] = mv[j];
               }
               else mv[j] = it->second;
             }
           }
           MTetrahedron *mt = new MTetrahedron(mv[0], mv[1], mv[2], mv[3], ++numEle, ePart);
-          if(subTetras[i].lsTag() < 0)
+          if(tetras[i].lsTag() < 0)
             poly[0].push_back(mt);
           else
             poly[1].push_back(mt);
         }
-        MPolyhedron *p1 = new MPolyhedron(poly[0], copy, true, ++numEle, ePart);
-        int reg = getElementaryTag(-1, elementary, newtags[3]);
-        elements[9][reg].push_back(p1);
-        assignPhysicals(GM, gePhysicals, reg, 3, physicals);
-        MPolyhedron *p2 = new MPolyhedron(poly[1], copy, false, ++numEle, ePart);
-        elements[9][elementary].push_back(p2);
-        assignPhysicals(GM, gePhysicals, elementary, 3, physicals);
-
-        for (unsigned int i = 0; i < surfTriangles.size(); i++){
-          MVertex *mv[3] = {NULL, NULL, NULL};
-          for(int j = 0; j < 3; j++){
-            int numV = getElementVertexNum(surfTriangles[i].pt(j), e);
-            if(numV == -1) {
-              unsigned int k;
-              for(k = 0; k < newVertices.size(); k++)
-                if(equalV(newVertices[k], surfTriangles[i].pt(j))) break;
-              if(k == newVertices.size()) {
-                mv[j] = new MVertex(surfTriangles[i].x(j), surfTriangles[i].y(j),
-                                    surfTriangles[i].z(j), 0);
-                newVertices.push_back(mv[j]);
-              }
-              else mv[j] = newVertices[k];
-            }
-            else {
-              std::map<int, MVertex*>::iterator it = vertexMap.find(numV);
-              if(it == vertexMap.end()) {
-                mv[j] = new MVertex(surfTriangles[i].x(j), surfTriangles[i].y(j),
-                                    surfTriangles[i].z(j), 0, numV);
-                vertexMap[numV] = mv[j];
-              }
-              else mv[j] = it->second;
-            }
-          }
-          MTriangleBorder *tri = new MTriangleBorder(mv[0], mv[1], mv[2],
-                                                     p1, p2, ++numEle, ePart);
-          double lsT = surfTriangles[i].lsTag();
-          int c = elements[2].count(lsT) + elements[3].count(lsT);
-          // suppose that the surfaces have been cut before the volumes!
-          int reg = getBorderTag(lsT, c, newtags[2][0], borderTags[1]);
-          elements[2][reg].push_back(tri);
-          assignPhysicals(GM, gePhysicals, reg, 2, physicals);
+        if(poly[0].size()) {
+          p1 = new MPolyhedron(poly[0], copy, true, ++numEle, ePart);
+          int reg = getElementaryTag(-1, elementary, newtags[3]);
+          elements[9][reg].push_back(p1);
+          assignPhysicals(GM, gePhysicals, reg, 3, physicals);
         }
-      }
-      
+        if(poly[1].size()) {
+          p2 = new MPolyhedron(poly[1], copy, false, ++numEle, ePart);
+          elements[9][elementary].push_back(p2);
+          assignPhysicals(GM, gePhysicals, elementary, 3, physicals);
+        }
+      } 
       else { // no cut
-        int reg = getElementaryTag(subTetras[0].lsTag(), elementary, newtags[3]);
+        int reg = getElementaryTag(tetras[nbTe].lsTag(), elementary, newtags[3]);
         if(eType == MSH_TET_4)
           elements[4][reg].push_back(copy);
         else if(eType == MSH_HEX_8)
@@ -689,38 +663,64 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
           elements[7][reg].push_back(copy);
         else if(eType == MSH_POLYH_)
           elements[9][reg].push_back(copy);
-        
         assignPhysicals(GM, gePhysicals, reg, 3, physicals);
       }
-      
+
+      for (unsigned int i = nbTr; i < triangles.size(); i++){
+        MVertex *mv[3] = {NULL, NULL, NULL};
+        for(int j = 0; j < 3; j++){
+          int numV = getElementVertexNum(triangles[i].pt(j), e);
+          if(numV == -1) {
+            unsigned int k;
+            for(k = 0; k < newVertices.size(); k++)
+              if(equalV(newVertices[k], triangles[i].pt(j))) break;
+            if(k == newVertices.size()) {
+              mv[j] = new MVertex(triangles[i].x(j), triangles[i].y(j),
+                                  triangles[i].z(j), 0);
+              newVertices.push_back(mv[j]);
+            }
+            else mv[j] = newVertices[k];
+          }
+          else {
+            std::map<int, MVertex*>::iterator it = vertexMap.find(numV);
+            if(it == vertexMap.end()) {
+              mv[j] = new MVertex(triangles[i].x(j), triangles[i].y(j),
+                                  triangles[i].z(j), 0, numV);
+              vertexMap[numV] = mv[j];
+            }
+            else mv[j] = it->second;
+          }
+        }
+        MTriangle *tri;
+        if(p1 || p2) tri = new MTriangleBorder(mv[0], mv[1], mv[2], p1, p2, ++numEle, ePart);
+        else tri = new MTriangle(mv[0], mv[1], mv[2], ++numEle, ePart);
+        double lsT = triangles[i].lsTag();
+        int c = elements[2].count(lsT) + elements[3].count(lsT);
+        // suppose that the surfaces have been cut before the volumes!
+        int reg = getBorderTag(lsT, c, newtags[2][0], borderTags[1]);
+        elements[2][reg].push_back(tri);
+        assignPhysicals(GM, gePhysicals, reg, 2, physicals);
+      }
     }
     break;
   case MSH_TRI_3 :
   case MSH_QUA_4 :
   case MSH_POLYG_ :
     {
-      std::vector<DI_CuttingPoint> cp;
-      std::vector<DI_Quad> subQuads;
-      std::vector<DI_Triangle> subTriangles;
-      std::vector<DI_Line> boundLines;
-      int integOrder = 1;
-      std::vector<DI_IntegrationPoint> ipV;
-      std::vector<DI_IntegrationPoint> ipS;
-
       if(eType == MSH_TRI_3) {
         DI_Triangle T(e->getVertex(0)->x(), e->getVertex(0)->y(), e->getVertex(0)->z(),
                       e->getVertex(1)->x(), e->getVertex(1)->y(), e->getVertex(1)->z(),
                       e->getVertex(2)->x(), e->getVertex(2)->y(), e->getVertex(2)->z());
-        T.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
-              subQuads, subTriangles, boundLines);
+        isCut = T.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
+                      quads, triangles, lines);
       }
       else if(eType == MSH_QUA_4){
         DI_Quad Q(e->getVertex(0)->x(), e->getVertex(0)->y(), e->getVertex(0)->z(),
                   e->getVertex(1)->x(), e->getVertex(1)->y(), e->getVertex(1)->z(),
                   e->getVertex(2)->x(), e->getVertex(2)->y(), e->getVertex(2)->z(),
                   e->getVertex(3)->x(), e->getVertex(3)->y(), e->getVertex(3)->z());
-        Q.cut(*ls, ipV, ipS, cp, integOrder,integOrder,integOrder,
-              subQuads, subTriangles, boundLines);
+        isCut = Q.cut(*ls, ipV, ipS, cp, integOrder,integOrder,integOrder,
+                      quads, triangles, lines);
       }
       else if(eType == MSH_POLYG_){
         for(int i = 0; i < e->getNumChildren(); i++) {
@@ -728,28 +728,27 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
           DI_Triangle Tri(t->getVertex(0)->x(), t->getVertex(0)->y(), t->getVertex(0)->z(),
                           t->getVertex(1)->x(), t->getVertex(1)->y(), t->getVertex(1)->z(),
                           t->getVertex(2)->x(), t->getVertex(2)->y(), t->getVertex(2)->z());
-          Tri.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
-                  subQuads, subTriangles, boundLines);
+          bool iC = Tri.cut(*ls, ipV, ipS, cp, integOrder, integOrder, integOrder,
+                            quads, triangles, lines);
+          isCut = (isCut || iC);
         }
       }
 
-      // if cut
-      if((eType == MSH_TRI_3 && subTriangles.size() > 1) ||
-         (eType == MSH_QUA_4 && subTriangles.size() > 2) ||
-         (eType == MSH_POLYG_ && subTriangles.size() > e->getNumChildren())) {
+      MPolygon *p1 = NULL, *p2 = NULL;
+      if(isCut) {
         std::vector<MTriangle*> poly[2];
 
-        for (unsigned int i = 0; i < subTriangles.size(); i++){
+        for (unsigned int i = nbTr; i < triangles.size(); i++){
           MVertex *mv[3] = {NULL, NULL, NULL};
           for(int j = 0; j < 3; j++){
-            int numV = getElementVertexNum(subTriangles[i].pt(j), e);
+            int numV = getElementVertexNum(triangles[i].pt(j), e);
             if(numV == -1) {
               unsigned int k;
               for(k = 0; k < newVertices.size(); k++)
-                if(equalV(newVertices[k], subTriangles[i].pt(j))) break;
+                if(equalV(newVertices[k], triangles[i].pt(j))) break;
               if(k == newVertices.size()) {
-                mv[j] = new MVertex(subTriangles[i].x(j), subTriangles[i].y(j),
-                                    subTriangles[i].z(j), 0);
+                mv[j] = new MVertex(triangles[i].x(j), triangles[i].y(j),
+                                    triangles[i].z(j), 0);
                 newVertices.push_back(mv[j]);
               }
               else mv[j] = newVertices[k];
@@ -757,63 +756,33 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
             else {
               std::map<int, MVertex*>::iterator it = vertexMap.find(numV);
               if(it == vertexMap.end()) {
-                mv[j] = new MVertex(subTriangles[i].x(j), subTriangles[i].y(j),
-                                    subTriangles[i].z(j), 0, numV);
+                mv[j] = new MVertex(triangles[i].x(j), triangles[i].y(j),
+                                    triangles[i].z(j), 0, numV);
                 vertexMap[numV] = mv[j];
               }
               else mv[j] = it->second;
             }
           }
           MTriangle *mt = new MTriangle(mv[0], mv[1], mv[2], ++numEle, ePart);
-          if(subTriangles[i].lsTag() < 0)
+          if(triangles[i].lsTag() < 0)
             poly[0].push_back(mt);
           else
             poly[1].push_back(mt);
         }
-        MPolygon *p1 = new MPolygon(poly[0], copy, true, ++numEle, ePart);
-        int reg = getElementaryTag(-1, elementary, newtags[2]);
-        elements[8][reg].push_back(p1);
-        assignPhysicals(GM, gePhysicals, reg, 2, physicals);
-        MPolygon *p2 = new MPolygon(poly[1], copy, false, ++numEle, ePart);
-        elements[8][elementary].push_back(p2);
-        assignPhysicals(GM, gePhysicals, elementary, 2, physicals);
-
-        for (unsigned int i = 0; i < boundLines.size(); i++){
-          MVertex *mv[2] = {NULL, NULL};
-          for(int j = 0; j < 2; j++){
-            int numV = getElementVertexNum(boundLines[i].pt(j), e);
-            if(numV == -1) {
-              unsigned int k;
-              for(k = 0; k < newVertices.size(); k++)
-                if(equalV(newVertices[k], boundLines[i].pt(j))) break;
-              if(k == newVertices.size()) {
-                mv[j] = new MVertex(boundLines[i].x(j), boundLines[i].y(j),
-                                    boundLines[i].z(j), 0);
-                newVertices.push_back(mv[j]);
-              }
-              else mv[j] = newVertices[k];
-            }
-            else {
-              std::map<int, MVertex*>::iterator it = vertexMap.find(numV);
-              if(it == vertexMap.end()) {
-                mv[j] = new MVertex(boundLines[i].x(j), boundLines[i].y(j),
-                                    boundLines[i].z(j), 0, numV);
-                vertexMap[numV] = mv[j];
-              }
-              else mv[j] = it->second;
-            }
-          }
-          MLineBorder *lin = new MLineBorder(mv[0], mv[1], p1, p2, ++numEle, ePart);
-          int c = elements[1].count(boundLines[i].lsTag());
-          // suppose that the lines have been cut before the surfaces!
-          int reg = getBorderTag(boundLines[i].lsTag(), c, newtags[1][0], borderTags[0]);
-          elements[1][reg].push_back(lin);
-          assignPhysicals(GM, gePhysicals, reg, 1, physicals);
+        if(poly[0].size()) {
+          p1 = new MPolygon(poly[0], copy, true, ++numEle, ePart);
+          int reg = getElementaryTag(-1, elementary, newtags[2]);
+          elements[8][reg].push_back(p1);
+          assignPhysicals(GM, gePhysicals, reg, 2, physicals);
+        }
+        if(poly[1].size()) {
+          p2 = new MPolygon(poly[1], copy, false, ++numEle, ePart);
+          elements[8][elementary].push_back(p2);
+          assignPhysicals(GM, gePhysicals, elementary, 2, physicals);
         }
       }
-
       else { // no cut
-        int reg = getElementaryTag(subTriangles[0].lsTag(), elementary, newtags[2]);
+        int reg = getElementaryTag(triangles[nbTr].lsTag(), elementary, newtags[2]);
         if(eType == MSH_TRI_3)
           elements[2][reg].push_back(copy);
         else if(eType == MSH_QUA_4)
@@ -822,20 +791,51 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
           elements[8][reg].push_back(copy);
         assignPhysicals(GM, gePhysicals, reg, 2, physicals);
       }
+
+      for (unsigned int i = nbL; i < lines.size(); i++){
+        MVertex *mv[2] = {NULL, NULL};
+        for(int j = 0; j < 2; j++){
+          int numV = getElementVertexNum(lines[i].pt(j), e);
+          if(numV == -1) {
+            unsigned int k;
+            for(k = 0; k < newVertices.size(); k++)
+              if(equalV(newVertices[k], lines[i].pt(j))) break;
+            if(k == newVertices.size()) {
+              mv[j] = new MVertex(lines[i].x(j), lines[i].y(j),
+                                  lines[i].z(j), 0);
+              newVertices.push_back(mv[j]);
+            }
+            else mv[j] = newVertices[k];
+          }
+          else {
+            std::map<int, MVertex*>::iterator it = vertexMap.find(numV);
+            if(it == vertexMap.end()) {
+              mv[j] = new MVertex(lines[i].x(j), lines[i].y(j),
+                                  lines[i].z(j), 0, numV);
+              vertexMap[numV] = mv[j];
+            }
+            else mv[j] = it->second;
+          }
+        }
+        MLine *lin;
+        if(p1 || p2) lin = new MLineBorder(mv[0], mv[1], p1, p2, ++numEle, ePart);
+        else lin = new MLine(mv[0], mv[1], ++numEle, ePart);
+        int c = elements[1].count(lines[i].lsTag());
+        // suppose that the lines have been cut before the surfaces!
+        int reg = getBorderTag(lines[i].lsTag(), c, newtags[1][0], borderTags[0]);
+        elements[1][reg].push_back(lin);
+        assignPhysicals(GM, gePhysicals, reg, 1, physicals);
+      }
     }
     break;
   case MSH_LIN_2 :
     {
-      std::vector<DI_CuttingPoint> cp;
-      std::vector<DI_Line> lines;
-      int integOrder = 1;
-      std::vector<DI_IntegrationPoint> ip;
       DI_Line L(e->getVertex(0)->x(), e->getVertex(0)->y(), e->getVertex(0)->z(),
                 e->getVertex(1)->x(), e->getVertex(1)->y(), e->getVertex(1)->z());
-      L.cut(*ls, ip, cp, integOrder, lines);
+      isCut = L.cut(*ls, ipV, cp, integOrder, lines);
 
-      if(lines.size() > 1) {
-        for (unsigned int i = 0; i < lines.size(); i++){
+      if(isCut) {
+        for (unsigned int i = nbL; i < lines.size(); i++){
           MVertex *mv[2] = {NULL, NULL};
           for(int j = 0; j < 2; j++){
             int numV = getElementVertexNum(lines[i].pt(j), e);
@@ -865,7 +865,7 @@ static void elementCutMesh(MElement *e, gLevelset *ls, GEntity *ge, GModel *GM,
         }
       }
       else { // no cut
-        int reg = getElementaryTag(lines[0].lsTag(), elementary, newtags[1]);
+        int reg = getElementaryTag(lines[nbL].lsTag(), elementary, newtags[1]);
         elements[1][reg].push_back(copy);
         assignPhysicals(GM, gePhysicals, reg, 1, physicals);
       }
@@ -907,15 +907,22 @@ GModel *buildCutMesh(GModel *gm, gLevelset *ls,
   for(int i = 0; i < 4; i++)
     newtags[i][0] = gm->getMaxElementaryNumber(i);
   std::map<int, int> borderTags[2];
-    
+
+  std::vector<DI_CuttingPoint> cp;
+  std::vector<DI_Line> lines;
+  std::vector<DI_Triangle> triangles;
+  std::vector<DI_Quad> quads;
+  std::vector<DI_Tetra> tetras;
+  std::vector<DI_Hexa> hexas;
   for(unsigned int i = 0; i < gmEntities.size(); i++) {
     for(unsigned int j = 0; j < gmEntities[i]->getNumMeshElements(); j++) {
       MElement *e = gmEntities[i]->getMeshElement(j);
       e->setVolumePositive();
-      elementCutMesh(e, ls, gmEntities[i], gm, numEle, vertexMap, newVertices, 
-                     elements, physicals, borderTags, newtags);
+      elementCutMesh(e, ls, verticesLs, gmEntities[i], gm, numEle, vertexMap, newVertices, 
+                     elements, physicals, borderTags, newtags, cp, lines, triangles, quads, tetras, hexas);
       cutGM->getMeshPartitions().insert(e->getPartition());
     }
+    cp.clear(); lines.clear(); triangles.clear(); quads.clear(); tetras.clear(); hexas.clear();
   }
 
   for(unsigned int i = 0; i < newVertices.size(); i++) {
diff --git a/Geo/MElementCut.h b/Geo/MElementCut.h
index bd262edc5653d5433a85513dc85b0565f1cf3b09..c52f486ab741108c2c2fbd03065b9dd31cdb1066 100644
--- a/Geo/MElementCut.h
+++ b/Geo/MElementCut.h
@@ -263,7 +263,11 @@ class MTriangleBorder : public MTriangle {
   }
   ~MTriangleBorder() {}
   MPolyhedron* getDomain(int i) const { return _domains[i]; }
-  virtual MElement *getParent() const { return _domains[0]->getParent(); }
+  virtual MElement *getParent() const {
+    if(_domains[0]) return _domains[0]->getParent();
+    if(_domains[1]) return _domains[1]->getParent();
+    return NULL;
+  }
   virtual const gmshFunctionSpace* getFunctionSpace(int order=-1) const 
   {
     return getParent()->getFunctionSpace(order);
@@ -299,7 +303,11 @@ class MLineBorder : public MLine {
   }
   ~MLineBorder() {}
   MPolygon* getDomain(int i) const { return _domains[i]; }
-  virtual MElement *getParent() const { return _domains[0]->getParent(); }
+  virtual MElement *getParent() const {
+    if(_domains[0]) return _domains[0]->getParent();
+    if(_domains[1]) return _domains[1]->getParent();
+    return NULL;
+  }
   virtual const gmshFunctionSpace* getFunctionSpace(int order=-1) const 
   {
     return getParent()->getFunctionSpace(order);
diff --git a/contrib/DiscreteIntegration/Integration3D.cpp b/contrib/DiscreteIntegration/Integration3D.cpp
index ad888429c3c54586327614ae862bc19b61d69dc7..6219c52786a0ab47c183330a33da6037cf8c8f00 100644
--- a/contrib/DiscreteIntegration/Integration3D.cpp
+++ b/contrib/DiscreteIntegration/Integration3D.cpp
@@ -1485,7 +1485,7 @@ void DI_Hexa::getGradShapeFunctions (const double u, const double v, const doubl
 // ----------------------------------------------------------------------------
 
 // Split a reference line cut by a level set into sublines
-void DI_Line::selfSplit (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+void DI_Line::selfSplit (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                           std::vector<DI_Line> &subLines, std::vector<DI_CuttingPoint> &cuttingPoints) const
 {
   if (!isCrossed(pt(0), pt(1))) {
@@ -1514,7 +1514,7 @@ void DI_Triangle::splitIntoSubTriangles (std::vector<DI_Triangle> &subTriangles)
   subTriangles.push_back(DI_Triangle(pt(2), p02, p12)); // 2-02-12
 }
 // Split a reference triangle cut by a level set into subtriangles
-void DI_Triangle::selfSplit (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+void DI_Triangle::selfSplit (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                              std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
                              std::vector<DI_Line> &surfLines, std::vector<DI_CuttingPoint> &cuttingPoints) const
 {
@@ -1628,7 +1628,7 @@ void DI_Quad::splitIntoTriangles(std::vector<DI_Triangle> &triangles) const
 }
 
 // Split a reference tetrahedron cut by a level set (defined in a hex) into sub tetrahedra and create triangles on the surface of the level set
-void DI_Tetra::selfSplit (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+void DI_Tetra::selfSplit (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                        std::vector<DI_Tetra> &subTetras, std::vector<DI_Triangle> &surfTriangles,
                        std::vector<DI_CuttingPoint> &cuttingPoints, std::vector<DI_QualError> &QError) const
 {
@@ -2043,7 +2043,7 @@ void DI_Hexa::getRefIntegrationPoints ( const int polynomialOrder , std::vector<
 // -----------------------------------------------------------------------------
 
 // cut a line into sublines along the levelset curve
-void DI_Line::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+bool DI_Line::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
                    std::vector<DI_CuttingPoint> &cp, const int polynomialOrder,
                    std::vector<DI_Line> &lines, int recurLevel) const
 {
@@ -2062,7 +2062,7 @@ void DI_Line::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
 
   if(signChange){
     for(int l = 0; l < (int)RPN.size(); l++) {
-      const gLevelset *Lsi = RPN[l]; //printf("LS(0,0)=%g LS(1,1)=%g\n",(*Lsi)(0,0,0),(*Lsi)(1,1,0));
+      const gLevelset *Lsi = RPN[l];
       RPNi.push_back(Lsi);
       if(Lsi->isPrimitive()) {
         ll.addLs(this, *Lsi);
@@ -2110,10 +2110,11 @@ void DI_Line::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
       if(cp[i].equal(ll_cp[p])) {isIn = true; break;}
     if(!isIn) cp.push_back(ll_cp[p]);
   }
+  return signChange;
 }
 
 // cut a line into sublines along one levelset primitive
-void DI_Line::cut(const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+void DI_Line::cut(const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
            std::vector<DI_Line> &subLines, std::vector<DI_CuttingPoint> &cp) const
 {
   // check if the line is cut by the level set
@@ -2133,7 +2134,7 @@ void DI_Line::cut(const DI_Element *e, const std::vector<const gLevelset *> RPNi
 }
 
 // cut a triangle into subtriangles along the levelset curve
-void DI_Triangle::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+bool DI_Triangle::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
                        std::vector<DI_IntegrationPoint> &ipS, std::vector<DI_CuttingPoint> &cp,
                        const int polynomialOrderQ, const int polynomialOrderTr, const int polynomialOrderL,
                        std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
@@ -2152,7 +2153,7 @@ void DI_Triangle::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip
 
   RecurElement re(&tt);
   bool signChange = re.cut(recurLevel, this, Ls);
-  re.pushSubTriangles(tt_subTriangles); //for(int i=0;i<(int)tt_subTriangles.size(); i++) tt_subTriangles[i].print();
+  re.pushSubTriangles(tt_subTriangles);
 
   if(signChange){
     for(int l = 0; l < (int)RPN.size(); l++) {
@@ -2265,8 +2266,6 @@ void DI_Triangle::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip
     }
   }*/
 
-  //printf("tt = "); tt.printls();
-
   for(int q = 0; q < (int)tt_subQuads.size(); q++) {
     tt_subQuads[q].computeLsTagDom(&tt, RPN);
     DI_Quad tt_subQ = tt_subQuads[q];
@@ -2282,10 +2281,10 @@ void DI_Triangle::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip
     subTriangles.push_back(tt_subTr);
   }
   for(int l = 0; l < (int)tt_surfLines.size(); l++) {
-    tt_surfLines[l].computeLsTagBound(tt_subQuads, tt_subTriangles);  //tt_surfLines[l].printls();
+    tt_surfLines[l].computeLsTagBound(tt_subQuads, tt_subTriangles);
     if(tt_surfLines[l].lsTag() == -1) continue;
     DI_Line tt_surfLn = tt_surfLines[l];
-    mappingEl(&tt_surfLn);                      //tt_surfLn.printls();
+    mappingEl(&tt_surfLn);
     tt_surfLn.integrationPoints(polynomialOrderL, &tt_surfLines[l], &tt, RPN, ipS);
     surfLines.push_back(tt_surfLn);
   }
@@ -2297,10 +2296,11 @@ void DI_Triangle::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip
       if(cp[i].equal(tt_cp[p])) {isIn = true; break;}
     if(!isIn) cp.push_back(tt_cp[p]);
   }
+  return signChange;
 }
 
 // cut a triangle into subtriangles along one levelset primitive
-void DI_Triangle::cut (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+void DI_Triangle::cut (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                     std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
                     std::vector<DI_Line> &surfLines, std::vector<DI_CuttingPoint> &cp) const
 {
@@ -2325,7 +2325,7 @@ void DI_Triangle::cut (const DI_Element *e, const std::vector<const gLevelset *>
 }
 
 // cut a quadrangle into subtriangles along the levelset curve
-void DI_Quad::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+bool DI_Quad::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
                    std::vector<DI_IntegrationPoint> &ipS, std::vector<DI_CuttingPoint> &cp,
                    const int polynomialOrderQ, const int polynomialOrderTr, const int polynomialOrderL,
                    std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
@@ -2346,14 +2346,6 @@ void DI_Quad::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
   bool signChange = re.cut(recurLevel, this, Ls, 1.e-5);
   re.pushSubQuads(qq_subQuads);
 
-  qq.addLs(this, Ls); printf("qq:"); qq.printls();
-  for(int i = 0; i < (int)qq_subQuads.size(); i++) {
-    qq_subQuads[i].addLs(&qq);
-    printf("qi:"); qq_subQuads[i].printls();
-    qq_subQuads[i].clearLs();
-  }
-  qq.clearLs();
-
   if(signChange) {
     for(int l = 0; l < (int)RPN.size(); l++) {
       const gLevelset *Lsi = RPN[l];
@@ -2496,10 +2488,11 @@ void DI_Quad::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
       if(cp[i].equal(qq_cp[p])) {isIn = true; break;}
     if(!isIn) cp.push_back(qq_cp[p]);
   }
+  return signChange;
 }
 
 // cut a quadrangle into subtriangles along the levelset curve
-void DI_Quad::cut (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+void DI_Quad::cut (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                 std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
                 std::vector<DI_Line> &surfLines, std::vector<DI_CuttingPoint> &cp) const
 {
@@ -2535,7 +2528,7 @@ void DI_Quad::cut (const DI_Element *e, const std::vector<const gLevelset *> RPN
 }
 
 // cut a tetrahedron into subtetrahedra along the levelset surface
-void DI_Tetra::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+bool DI_Tetra::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
                     std::vector<DI_IntegrationPoint> &ipS, std::vector<DI_CuttingPoint> &cp,
                     const int polynomialOrderT, const int polynomialOrderQ, const int polynomialOrderTr,
                     std::vector<DI_Tetra> &subTetras, std::vector<DI_Quad> &surfQuads,
@@ -2685,10 +2678,11 @@ void DI_Tetra::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
       if(cp[i].equal(tt_cp[p])) {isIn = true; break;}
     if(!isIn) cp.push_back(tt_cp[p]);
   }
+  return signChange;
 }
 
 // cut a tetrahedron into subtetrahedra along the levelset surface
-void DI_Tetra::cut (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+void DI_Tetra::cut (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                  std::vector<DI_Tetra> &subTetras, std::vector<DI_Quad> &surfQuads,
                  std::vector<DI_Triangle> &surfTriangles, std::vector<DI_CuttingPoint> &cp,
                  std::vector<DI_QualError> &QError) const
@@ -2713,7 +2707,7 @@ void DI_Tetra::cut (const DI_Element *e, const std::vector<const gLevelset *> RP
 }
 
 // cut a hex into subtetras along the levelset surface
-void DI_Hexa::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+bool DI_Hexa::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
                    std::vector<DI_IntegrationPoint> &ipS, std::vector<DI_CuttingPoint> &cp,
                    const int polynomialOrderH, const int polynomialOrderT,
                    const int polynomialOrderQ, const int polynomialOrderTr,
@@ -2937,10 +2931,11 @@ void DI_Hexa::cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
       if(cp[i].equal(hh_cp[p])) {isIn = true; break;}
     if(!isIn) cp.push_back(hh_cp[p]);
   }
+  return signChange;
 }
 
 // cut a hex into subtetras along the levelset surface
-void DI_Hexa::cut (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+void DI_Hexa::cut (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                    std::vector<DI_Hexa> &Hexas, std::vector<DI_Tetra> &subTetras,
                    std::vector<DI_Quad> &surfQuads, std::vector<DI_Triangle> &surfTriangles,
                    std::vector<DI_CuttingPoint> &cp, std::vector<DI_QualError> &QError) const
diff --git a/contrib/DiscreteIntegration/Integration3D.h b/contrib/DiscreteIntegration/Integration3D.h
index 862e040ab497a96333a1cc1b74638cb9a3b6296d..e31d4ce1812f764e6135ffdf91c8ec8690863133 100644
--- a/contrib/DiscreteIntegration/Integration3D.h
+++ b/contrib/DiscreteIntegration/Integration3D.h
@@ -411,12 +411,12 @@ class DI_Line : public DI_Element
   void getGradShapeFunctions (const double u, const double v, const double w,
                               double s[][3], int order = -1) const;
   double detJ (const double &xP, const double &yP, const double &zP) const;
-  void cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+  bool cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
             std::vector<DI_CuttingPoint> &cp, const int polynomialOrderL,
             std::vector<DI_Line> &subLines, int recurLevel = 0) const;
-  void cut(const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+  void cut(const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
            std::vector<DI_Line> &subLines, std::vector<DI_CuttingPoint> &cp) const;
-  void selfSplit (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+  void selfSplit (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                   std::vector<DI_Line> &subLines, std::vector<DI_CuttingPoint> &cuttingPoints) const;
   inline double length() const {return integral_;}
 };
@@ -496,16 +496,16 @@ class DI_Triangle : public DI_Element
   void getGradShapeFunctions (const double u, const double v, const double w,
                               double s[][3], int order = -1) const;
   double detJ (const double &xP, const double &yP, const double &zP) const;
-  void cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+  bool cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
             std::vector<DI_IntegrationPoint> &ipS, std::vector<DI_CuttingPoint> &cp,
             const int polynomialOrderQ, const int polynomialOrderTr, const int polynomialOrderL,
             std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
             std::vector<DI_Line> &surfLines, int recurLevel = 0) const;
-  void cut (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+  void cut (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
             std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
             std::vector<DI_Line> &surfLines, std::vector<DI_CuttingPoint> &cp) const;
   void splitIntoSubTriangles (std::vector<DI_Triangle> &triangles) const;
-  void selfSplit (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+  void selfSplit (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                   std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
                   std::vector<DI_Line> &surfLines, std::vector<DI_CuttingPoint> &cuttingPoints) const;
   double quality () const;
@@ -594,12 +594,12 @@ class DI_Quad : public DI_Element
   void getGradShapeFunctions (const double u, const double v, const double w,
                               double s[][3], int order = -1) const;
   double detJ (const double &xP, const double &yP, const double &zP) const;
-  void cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+  bool cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
             std::vector<DI_IntegrationPoint> &ipS, std::vector<DI_CuttingPoint> &cp,
             const int polynomialOrderQ, const int polynomialOrderTr, const int polynomialOrderL,
             std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
             std::vector<DI_Line> &surfLines, int recurLevel = 0) const;
-  void cut (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+  void cut (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
             std::vector<DI_Quad> &subQuads, std::vector<DI_Triangle> &subTriangles,
             std::vector<DI_Line> &surfLines, std::vector<DI_CuttingPoint> &cp) const;
   void splitIntoTriangles (std::vector<DI_Triangle> &triangles) const;
@@ -689,16 +689,16 @@ class DI_Tetra : public DI_Element
   void getGradShapeFunctions (const double u, const double v, const double w,
                               double s[][3], int order = -1) const;
   double detJ (const double &xP, const double &yP, const double &zP) const;
-  void cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+  bool cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
             std::vector<DI_IntegrationPoint> &ipS, std::vector<DI_CuttingPoint> &cp,
             const int polynomialOrderT, const int polynomialOrderQ, const int polynomialOrderTr,
             std::vector<DI_Tetra> &subTetras, std::vector<DI_Quad> &surfQuads,
             std::vector<DI_Triangle> &surfTriangles, int recurLevel = 0) const;
-  void cut (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+  void cut (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
             std::vector<DI_Tetra> &subTetras, std::vector<DI_Quad> &surfQuads,
             std::vector<DI_Triangle> &surfTriangles, std::vector<DI_CuttingPoint> &cp,
             std::vector<DI_QualError> &QE) const;
-  void selfSplit ( const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+  void selfSplit ( const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
                    std::vector<DI_Tetra> &subTetras, std::vector<DI_Triangle> &surfTriangles,
                    std::vector<DI_CuttingPoint> &cuttingPoints, std::vector<DI_QualError> &QE) const;
   double quality () const;
@@ -818,14 +818,14 @@ class DI_Hexa : public DI_Element
   void getGradShapeFunctions (const double u, const double v, const double w,
                               double s[][3], int order = -1) const;
   double detJ (const double &xP, const double &yP, const double &zP) const;
-  void cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
+  bool cut (const gLevelset &Ls, std::vector<DI_IntegrationPoint> &ip,
             std::vector<DI_IntegrationPoint> &ipS, std::vector<DI_CuttingPoint> &cp,
             const int polynomialOrderH, const int polynomialOrderT,
             const int polynomialOrderQ, const int polynomialOrderTr,
             std::vector<DI_Hexa> &notCutHexas, std::vector<DI_Tetra> &subTetras,
             std::vector<DI_Quad> &surfQuads, std::vector<DI_Triangle> &surfTriangles,
             std::vector<DI_Line> &frontLines, int recurLevel = 0) const;
-  void cut (const DI_Element *e, const std::vector<const gLevelset *> RPNi,
+  void cut (const DI_Element *e, const std::vector<const gLevelset *> &RPNi,
             std::vector<DI_Hexa> &unCutHexas, std::vector<DI_Tetra> &subTetras,
             std::vector<DI_Quad> &surfQuads, std::vector<DI_Triangle> &surfTriangles,
             std::vector<DI_CuttingPoint> &cp, std::vector<DI_QualError> &QE) const;
diff --git a/contrib/DiscreteIntegration/recurCut.cpp b/contrib/DiscreteIntegration/recurCut.cpp
index d101fa81879158d483372b041f76fb24bdba38cf..51f24f4b0d3206d07c58cd551b2d5d8fd18994c3 100644
--- a/contrib/DiscreteIntegration/recurCut.cpp
+++ b/contrib/DiscreteIntegration/recurCut.cpp
@@ -166,7 +166,7 @@ void recurCut(RecurElement *re, int maxlevel, int level)
 
 // return true if the element re->el is crossed or run along by a primitive levelset in RPN and by the final levelset
 // (the levelset is computed with the values at the nodes of the element e)
-bool signChange (RecurElement *re, const DI_Element *e, const std::vector<const gLevelset *> RPN) {
+bool signChange (RecurElement *re, const DI_Element *e, const std::vector<const gLevelset *> &RPN) {
   bool cS = false;
   DI_Element* elem = re->root()->el;
   std::vector<DI_CuttingPoint> cp;
@@ -200,7 +200,7 @@ bool signChange (RecurElement *re, const DI_Element *e, const std::vector<const
 // Set isCrossed to true if a sub RecurElement is crossed. 
 // If it has no sub RecurElement, set isCrossed to true if the element is crossed or run along by the levelset
 //(the levelset is computed with the values at the nodes of the triangle e)
-bool computeIsCrossed (RecurElement *re, const DI_Element *e, const std::vector<const gLevelset *> RPN) {
+bool computeIsCrossed (RecurElement *re, const DI_Element *e, const std::vector<const gLevelset *> &RPN) {
   if (!re->sub[0])
     re->isCrossed = signChange(re, e, RPN);
   else {
@@ -227,7 +227,7 @@ void recurChangeVisibility(RecurElement *re){
     recurChangeVisibility(re->sub[i]);
 }
 
-void recurChangeVisibility(RecurElement *re, const std::vector<const gLevelset *> RPN, double TOL){
+void recurChangeVisibility(RecurElement *re, const std::vector<const gLevelset *> &RPN, double TOL){
   printf("rCV : "); re->el->printls();
   if(!re->sub[0]){
     re->visible = true;