diff --git a/intern/boolop/CMakeLists.txt b/intern/boolop/CMakeLists.txt index d0870c8da9c..d8e9c0c94d7 100644 --- a/intern/boolop/CMakeLists.txt +++ b/intern/boolop/CMakeLists.txt @@ -23,6 +23,8 @@ # # ***** END GPL LICENSE BLOCK ***** +remove_strict_flags() + set(INC . extern diff --git a/intern/boolop/intern/BOP_CarveInterface.cpp b/intern/boolop/intern/BOP_CarveInterface.cpp index 3e0daf83ef6..6fc08e52ade 100644 --- a/intern/boolop/intern/BOP_CarveInterface.cpp +++ b/intern/boolop/intern/BOP_CarveInterface.cpp @@ -43,9 +43,6 @@ using namespace carve::mesh; using namespace carve::geom; typedef unsigned int uint; -static void Carve_unionIntersections(MeshSet<3> **left_r, MeshSet<3> **right_r, - carve::interpolate::FaceAttr &oface_num); - #define MAX(x,y) ((x)>(y)?(x):(y)) #define MIN(x,y) ((x)<(y)?(x):(y)) @@ -210,30 +207,35 @@ static void Carve_getIntersectedOperandMeshes(std::vector::mesh_t*> & while(it != meshes.end()) { MeshSet<3>::mesh_t *mesh = *it; - bool isIntersect = false; + bool isAdded = false; RTreeNode<3, Face<3> *> *rtree = RTreeNode<3, Face<3> *>::construct_STR(mesh->faces.begin(), mesh->faces.end(), 4, 4); - std::vector::mesh_t*>::iterator operand_it = operandMeshes.begin(); - std::vector *> *>::iterator tree_it = meshRTree.begin(); - for(; operand_it!=operandMeshes.end(); operand_it++, tree_it++) { - RTreeNode<3, Face<3> *> *operandRTree = *tree_it; + if (rtree->bbox.intersects(otherAABB)) { + bool isIntersect = false; + + std::vector::mesh_t*>::iterator operand_it = operandMeshes.begin(); + std::vector *> *>::iterator tree_it = meshRTree.begin(); + for(; operand_it!=operandMeshes.end(); operand_it++, tree_it++) { + RTreeNode<3, Face<3> *> *operandRTree = *tree_it; - if(operandRTree->bbox.intersects(otherAABB)) { if(Carve_checkMeshSetInterseciton(rtree, operandRTree)) { isIntersect = true; break; } } + + if(!isIntersect) { + operandMeshes.push_back(mesh); + meshRTree.push_back(rtree); + + it = meshes.erase(it); + isAdded = true; + } } - if(!isIntersect) { - operandMeshes.push_back(mesh); - meshRTree.push_back(rtree); - - it = meshes.erase(it); - } - else { + if (!isAdded) { + delete rtree; it++; } } @@ -249,6 +251,9 @@ static MeshSet<3> *Carve_getIntersectedOperand(std::vector::mesh_t*> std::vector::mesh_t*> operandMeshes; Carve_getIntersectedOperandMeshes(meshes, otherAABB, operandMeshes); + if (operandMeshes.size() == 0) + return NULL; + return Carve_meshSetFromMeshes(operandMeshes); } @@ -269,9 +274,19 @@ static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly, MeshSet<3> *left = Carve_getIntersectedOperand(orig_meshes, otherAABB); + if (!left) { + /* no maniforlds which intersects another object at all */ + return poly; + } + while(orig_meshes.size()) { MeshSet<3> *right = Carve_getIntersectedOperand(orig_meshes, otherAABB); + if (!right) { + /* no more intersecting manifolds which intersects other object */ + break; + } + try { if(left->meshes.size()==0) { delete left; @@ -279,10 +294,6 @@ static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly, left = right; } else { - /* there might be intersections between manifolds of one operand and another mesh which isn't - * taking into accound in Carve_getIntersectedOperand because of optimization purposes */ - Carve_unionIntersections(&left, &right, oface_num); - MeshSet<3> *result = csg.compute(left, right, carve::csg::CSG::UNION, NULL, carve::csg::CSG::CLASSIFY_EDGE); delete left; @@ -309,6 +320,15 @@ static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly, } } + /* append all meshes which doesn't have intersection with another operand as-is */ + if (orig_meshes.size()) { + MeshSet<3> *result = Carve_meshSetFromTwoMeshes(left->meshes, orig_meshes); + + delete left; + + return result; + } + return left; }