Boolean op are undeffined when one of the two meshes are a no closed mesh (without...
authorMarc Freixas <mfreixas@lsi.upc.edu>
Wed, 30 Nov 2005 17:35:54 +0000 (17:35 +0000)
committerMarc Freixas <mfreixas@lsi.upc.edu>
Wed, 30 Nov 2005 17:35:54 +0000 (17:35 +0000)
I put a test to check the input meshes before do any thing. If one mesh have holes a error code is returned.

intern/boolop/intern/BOP_Face2Face.cpp
intern/boolop/intern/BOP_Interface.cpp
intern/boolop/intern/BOP_Mesh.cpp
intern/boolop/intern/BOP_Mesh.h
intern/bsp/intern/CSG_BooleanOps.cpp

index 08928935f33da85c5869a70a4687746dc3c4ad26..bdd3637a5986bcbe0c918a1eb115874a245cf1c2 100644 (file)
@@ -146,7 +146,7 @@ void BOP_mergeVertexs(BOP_Mesh *mesh, unsigned int firstFace);
  * @param facesB set of faces from object B
  */
 void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB)
-{              
+{
        for(unsigned int idxFaceA=0;idxFaceA<facesA->size();idxFaceA++) {
                BOP_Face *faceA = (*facesA)[idxFaceA];
                MT_Plane3 planeA = faceA->getPlane();
@@ -160,28 +160,28 @@ void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB)
                        idxFaceB<facesB->size() && (faceA->getTAG() != BROKEN) && (faceA->getTAG() != PHANTOM);) {
                        BOP_Face *faceB = (*facesB)[idxFaceB];
                        if ((faceB->getTAG() != BROKEN) && (faceB->getTAG() != PHANTOM)) {
-                         BOP_BBox boxB(mesh->getVertex(faceB->getVertex(0))->getPoint(),
-                                       mesh->getVertex(faceB->getVertex(1))->getPoint(),
-                                       mesh->getVertex(faceB->getVertex(2))->getPoint());
-                         if (boxA.intersect(boxB)) {
+                               BOP_BBox boxB(mesh->getVertex(faceB->getVertex(0))->getPoint(),
+                                                         mesh->getVertex(faceB->getVertex(1))->getPoint(),
+                                                         mesh->getVertex(faceB->getVertex(2))->getPoint());
+                               if (boxA.intersect(boxB)) {
 
-                           MT_Plane3 planeB = faceB->getPlane();
-                           if (BOP_containsPoint(planeB,p1) && 
-                               BOP_containsPoint(planeB,p2) && 
-                               BOP_containsPoint(planeB,p3)) {
-                             if (BOP_orientation(planeB,planeA)>0) {
-                               BOP_intersectCoplanarFaces(mesh,facesB,faceA,faceB,false);
-                             }
-                           }
-                           else {
-                             BOP_intersectNonCoplanarFaces(mesh,facesA,facesB,faceA,faceB);
-                           }
-                         }                       
+                                       MT_Plane3 planeB = faceB->getPlane();
+                                       if (BOP_containsPoint(planeB,p1) && 
+                                               BOP_containsPoint(planeB,p2) && 
+                                               BOP_containsPoint(planeB,p3)) {
+                                               if (BOP_orientation(planeB,planeA)>0) {
+                                                       BOP_intersectCoplanarFaces(mesh,facesB,faceA,faceB,false);
+                                               }
+                                       }
+                                       else {
+                                               BOP_intersectNonCoplanarFaces(mesh,facesA,facesB,faceA,faceB);
+                                       }
+                               }                         
                        }
                        if (faceB->getTAG()==BROKEN){
-                         facesB->erase(facesB->begin()+idxFaceB);
+                               facesB->erase(facesB->begin()+idxFaceB);
                        }else
-                         idxFaceB++;
+                               idxFaceB++;
                }
        }
        
index 02945340d55e25dd34c0405a764e154955b1597f..1ef394963ac03387033464336286ff408c2ef6f6 100644 (file)
@@ -92,9 +92,9 @@ BoolOpState BOP_performBooleanOperation(BoolOpType                    opType,
                                                                                CSG_VertexIteratorDescriptor  obBVertices,
                                                                                CSG_InterpolateUserFaceVertexDataFunc interpFunc)
 {
-       #ifdef DEBUG
+#ifdef DEBUG
        cout << "BEGIN BOP_performBooleanOperation" << endl;
-       #endif
+#endif
 
        // Set invert flags depending on boolean operation type:
        // INTERSECTION: A^B = and(A,B)
@@ -121,6 +121,9 @@ BoolOpState BOP_performBooleanOperation(BoolOpType                    opType,
        // Add B-mesh into C-mesh
        BOP_addMesh(&meshC, &meshBFacesId, &materials, obBProps, obBFaces, obBVertices, invertMeshB);
 
+       if (!meshC.isClosedMesh())
+               return BOP_NO_SOLID;
+
        // Perform the intersection boolean operation.
        BoolOpState result = BOP_intersectionBoolOp(&meshC, &meshAFacesId, &meshBFacesId, 
                                                                                                invertMeshA, invertMeshB);
@@ -128,9 +131,9 @@ BoolOpState BOP_performBooleanOperation(BoolOpType                    opType,
        // Invert the output mesh if is required
        *outputMesh = BOP_exportMesh(&meshC, &materials, outputProps, invertMeshC);
 
-       #ifdef DEBUG
+#ifdef DEBUG
        cout << "END BOP_performBooleanOperation" << endl;
-       #endif
+#endif
        
        return result;
 }
@@ -151,13 +154,13 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh*  meshC,
                                                                   bool       invertMeshA,
                                                                   bool       invertMeshB)
 {
-       #ifdef DEBUG
+#ifdef DEBUG
        BOP_Chrono chrono;
        float t = 0.0f;
        float c = 0.0f;
        chrono.start();  
        cout << "---" << endl;
-       #endif
+#endif
 
        // Create BSPs trees for mesh A & B
        BOP_BSPTree bspA;
@@ -168,10 +171,10 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh*  meshC,
        bspB.addMesh(meshC, *facesB);
        bspB.computeBox();
        
-       #ifdef DEBUG
+#ifdef DEBUG
        c = chrono.stamp(); t += c;
        cout << "Create BSP     " << c << endl; 
-       #endif
+#endif
 
        unsigned int numVertices = meshC->getNumVertexs();
        
@@ -184,54 +187,54 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh*  meshC,
        if ((0.25*facesB->size()) > bspA.getDeep())
          BOP_meshFilter(meshC, facesB, &bspA);
        
-       #ifdef DEBUG
+#ifdef DEBUG
        c = chrono.stamp(); t += c;
        cout << "mesh Filter    " << c << endl; 
-       #endif
+#endif
 
        // Face 2 Face
        BOP_Face2Face(meshC,facesA,facesB);
 
-       #ifdef DEBUG
+#ifdef DEBUG
        c = chrono.stamp(); t += c;
        cout << "Face2Face      " << c << endl;
-       #endif
+#endif
 
        // BSP classification
        BOP_meshClassify(meshC,facesA,&bspB);
        BOP_meshClassify(meshC,facesB,&bspA);
        
-       #ifdef DEBUG
+#ifdef DEBUG
        c = chrono.stamp(); t += c;
        cout << "Classification " << c << endl;
-       #endif
+#endif
        
        // Process overlapped faces
        BOP_removeOverlappedFaces(meshC,facesA,facesB);
        
-       #ifdef DEBUG
+#ifdef DEBUG
        c = chrono.stamp(); t += c;
        cout << "Remove overlap " << c << endl;
-       #endif
+#endif
 
        // Sew two meshes
        BOP_sew(meshC,facesA,facesB);
 
-       #ifdef DEBUG
+#ifdef DEBUG
        c = chrono.stamp(); t += c;
        cout << "Sew            " << c << endl;
-       #endif
+#endif
 
        // Merge faces
        BOP_Merge::getInstance().mergeFaces(meshC,numVertices);
 
-       #ifdef DEBUG
+#ifdef DEBUG
        c = chrono.stamp(); t += c;
        cout << "Merge faces    " << c << endl;
        cout << "Total          " << t << endl;
        // Test integrity
        meshC->testMesh();
-       #endif
+#endif
        
        return BOP_OK;
 }
index 24d5b3fb6a90b64df4cadd8865750a8ab36d99b8..a7e7ef61e435e2fa2d84942187eb1ed2b73db347 100644 (file)
@@ -553,6 +553,23 @@ BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
        return newIndex;
 }
 
+bool BOP_Mesh::isClosedMesh()
+{
+       for(unsigned int i=0; i<m_edges.size(); i++) {
+               BOP_Edge *edge = m_edges[i];
+               BOP_Indexs faces = edge->getFaces();
+               unsigned int count = 0;
+               const BOP_IT_Indexs facesEnd = faces.end();
+               for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) {
+                       if (m_faces[*it]->getTAG()!=BROKEN)
+                               count++;
+               }
+
+               if ((count%2)!=0) return false;
+       }
+
+       return true;
+}
 
 
 /** ***************************************************************************
index 6751df7c4e76058f12db0be546c4111acd447290..adc92c915594e9d50523b4173257fdc89ea6c258 100644 (file)
@@ -82,6 +82,7 @@ public:
        unsigned int getNumVertexs(BOP_TAG tag);
        unsigned int getNumFaces(BOP_TAG tag);
        BOP_Index replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex);
+       bool isClosedMesh();
        
        // Debug functions
        void print();
index 6c9fecd88e14feb7703b5061cf10b350ae5b7757..a677c9c6e94a9029e43a382a510f52ff4c99efec 100755 (executable)
@@ -103,15 +103,15 @@ CSG_DescibeOperands(
 /**
  * Compute the boolean operation, UNION, INTERSECION or DIFFERENCE
  */
-       int
+int
 CSG_PerformBooleanOperation(
-       CSG_BooleanOperation                 *operation,
-       CSG_OperationType                     op_type,
-       CSG_FaceIteratorDescriptor            obAFaces,
-       CSG_VertexIteratorDescriptor          obAVertices,
-       CSG_FaceIteratorDescriptor            obBFaces,
-       CSG_VertexIteratorDescriptor          obBVertices,
-       CSG_InterpolateUserFaceVertexDataFunc interp_func
+                                                       CSG_BooleanOperation                 *operation,
+                                                       CSG_OperationType                     op_type,
+                                                       CSG_FaceIteratorDescriptor            obAFaces,
+                                                       CSG_VertexIteratorDescriptor          obAVertices,
+                                                       CSG_FaceIteratorDescriptor            obBFaces,
+                                                       CSG_VertexIteratorDescriptor          obBVertices,
+                                                       CSG_InterpolateUserFaceVertexDataFunc interp_func
 ){
        if (operation == NULL) return 0;
        BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
@@ -128,33 +128,39 @@ CSG_PerformBooleanOperation(
        
        switch( op_type ) {
        case e_csg_union:
-         boolType = BOP_UNION;
-         break;
+               boolType = BOP_UNION;
+               break;
        case e_csg_difference:
-         boolType = BOP_DIFFERENCE;
-         break;
+               boolType = BOP_DIFFERENCE;
+               break;
        default:
-         boolType = BOP_INTERSECTION;
-         break;
+               boolType = BOP_INTERSECTION;
+               break;
        }
 
+       BoolOpState boolOpResult;
        try {
-       BOP_performBooleanOperation( boolType,
-                                    mesh_info->output_descriptor,
-                                    (BSP_CSGMesh**) &(mesh_info->output_mesh),
-                                        mesh_info->obB_descriptor,
-                                        obBFaces,
-                                        obBVertices,
-                                        mesh_info->obA_descriptor,
-                                    obAFaces,
-                                    obAVertices,
-                                    interp_func );
+               boolOpResult= BOP_performBooleanOperation( boolType,
+                                                                                                  mesh_info->output_descriptor,
+                                                                                                  (BSP_CSGMesh**) &(mesh_info->output_mesh),
+                                                                                                  mesh_info->obB_descriptor,
+                                                                                                  obBFaces,
+                                                                                                  obBVertices,
+                                                                                                  mesh_info->obA_descriptor,
+                                                                                                  obAFaces,
+                                                                                                  obAVertices,
+                                                                                                  interp_func );
        }
        catch(...) {
                return 0;
        }
 
-       return success;
+       switch (boolOpResult) {
+       case BOP_OK: return 1;
+       case BOP_NO_SOLID: return -2;
+       case BOP_ERROR: return 0;
+       default: return 1;
+       }
 }
 
        int