/** * Computes intesections of coplanars faces from object A with faces from object B. * @param mesh mesh that contains the faces, edges and vertices * @param facesA set of faces from object A * @param facesB set of faces from object B */ void BOP_sew(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB) { for(unsigned int idxFaceB = 0; idxFaceB < facesB->size(); idxFaceB++) { BOP_Face *faceB = (*facesB)[idxFaceB]; MT_Plane3 planeB = faceB->getPlane(); MT_Point3 p1 = mesh->getVertex(faceB->getVertex(0))->getPoint(); MT_Point3 p2 = mesh->getVertex(faceB->getVertex(1))->getPoint(); MT_Point3 p3 = mesh->getVertex(faceB->getVertex(2))->getPoint(); for(unsigned int idxFaceA = 0; idxFaceA < facesA->size() && faceB->getTAG() != BROKEN && faceB->getTAG() != PHANTOM; idxFaceA++) { BOP_Face *faceA = (*facesA)[idxFaceA]; if ((faceA->getTAG() != BROKEN)&&(faceA->getTAG() != PHANTOM)) { MT_Plane3 planeA = faceA->getPlane(); if (BOP_containsPoint(planeA,p1) && BOP_containsPoint(planeA,p2) && BOP_containsPoint(planeA,p3)) { if (BOP_orientation(planeA,planeB) > 0) { BOP_intersectCoplanarFaces(mesh,facesA,faceB,faceA,true); } } } } } }
/** * Removes faces from facesB that are overlapped with anyone from facesA. * @param mesh mesh that contains the faces, edges and vertices * @param facesA set of faces from object A * @param facesB set of faces from object B */ void BOP_removeOverlappedFaces(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB) { for(unsigned int i=0;i<facesA->size();i++) { BOP_Face *faceI = (*facesA)[i]; if (faceI->getTAG()==BROKEN) continue; bool overlapped = false; MT_Point3 p1 = mesh->getVertex(faceI->getVertex(0))->getPoint(); MT_Point3 p2 = mesh->getVertex(faceI->getVertex(1))->getPoint(); MT_Point3 p3 = mesh->getVertex(faceI->getVertex(2))->getPoint(); for(unsigned int j=0;j<facesB->size();) { BOP_Face *faceJ = (*facesB)[j]; if (faceJ->getTAG()!=BROKEN) { MT_Plane3 planeJ = faceJ->getPlane(); if (BOP_containsPoint(planeJ,p1) && BOP_containsPoint(planeJ,p2) && BOP_containsPoint(planeJ,p3)) { MT_Point3 q1 = mesh->getVertex(faceJ->getVertex(0))->getPoint(); MT_Point3 q2 = mesh->getVertex(faceJ->getVertex(1))->getPoint(); MT_Point3 q3 = mesh->getVertex(faceJ->getVertex(2))->getPoint(); if (BOP_overlap(MT_Vector3(planeJ.x(),planeJ.y(),planeJ.z()), p1,p2,p3,q1,q2,q3)) { facesB->erase(facesB->begin()+j,facesB->begin()+(j+1)); faceJ->setTAG(BROKEN); overlapped = true; } else j++; } else j++; }else j++; } if (overlapped) faceI->setTAG(OVERLAPPED); } }
/** * Preprocess to filter no collisioned faces. * @param meshC Input & Output mesh data * @param faces Faces list to test * @param bsp BSP tree used to filter */ void BOP_meshFilter(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp) { BOP_IT_Faces it; BOP_TAG tag; it = faces->begin(); while (it!=faces->end()) { BOP_Face *face = *it; MT_Point3 p1 = meshC->getVertex(face->getVertex(0))->getPoint(); MT_Point3 p2 = meshC->getVertex(face->getVertex(1))->getPoint(); MT_Point3 p3 = meshC->getVertex(face->getVertex(2))->getPoint(); if ((tag = bsp->classifyFace(p1,p2,p3,face->getPlane()))==OUT||tag==OUTON) { face->setTAG(BROKEN); it = faces->erase(it); } else if (tag == IN) { it = faces->erase(it); }else{ it++; } } }
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(); MT_Point3 p1 = mesh->getVertex(faceA->getVertex(0))->getPoint(); MT_Point3 p2 = mesh->getVertex(faceA->getVertex(1))->getPoint(); MT_Point3 p3 = mesh->getVertex(faceA->getVertex(2))->getPoint(); /* get (or create) bounding box for face A */ if( faceA->getBBox() == NULL ) faceA->setBBox(p1,p2,p3); BOP_BBox *boxA = faceA->getBBox(); /* start checking B faces with the previously stored split index */ for(unsigned int idxFaceB=faceA->getSplit(); idxFaceB<facesB->size() && (faceA->getTAG() != BROKEN) && (faceA->getTAG() != PHANTOM);) { BOP_Face *faceB = (*facesB)[idxFaceB]; faceA->setSplit(idxFaceB); if ((faceB->getTAG() != BROKEN) && (faceB->getTAG() != PHANTOM)) { /* get (or create) bounding box for face B */ if( faceB->getBBox() == NULL ) faceB->setBBox(mesh->getVertex(faceB->getVertex(0))->getPoint(), mesh->getVertex(faceB->getVertex(1))->getPoint(), mesh->getVertex(faceB->getVertex(2))->getPoint()); BOP_BBox *boxB = faceB->getBBox(); 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); } } } idxFaceB++; } } // Clean broken faces from facesA BOP_IT_Faces it; it = facesA->begin(); while (it != facesA->end()) { BOP_Face *face = *it; if (face->getTAG() == BROKEN) it = facesA->erase(it); else it++; } /* it = facesB->begin(); while (it != facesB->end()) { BOP_Face *face = *it; if (face->getTAG() == BROKEN) it = facesB->erase(it); else it++; } */ }