/** * testPlane */ void BOP_Mesh::testPlane(BOP_Face *face) { MT_Plane3 plane1(m_vertexs[face->getVertex(0)]->getPoint(), m_vertexs[face->getVertex(1)]->getPoint(), m_vertexs[face->getVertex(2)]->getPoint()); if (BOP_orientation(plane1,face->getPlane()) < 0) { cout << "Test Plane " << face << " v1: "; cout << m_vertexs[face->getVertex(0)]->getPoint() << " v2: "; cout << m_vertexs[face->getVertex(1)]->getPoint() << " v3: "; cout << m_vertexs[face->getVertex(2)]->getPoint() << " plane: "; cout << face->getPlane() << endl; cout << "Incorrect vertices order!!! plane1: " << plane1 << " ("; cout << BOP_orientation(plane1,face->getPlane()) << ") " << " invert "; cout << MT_Plane3(m_vertexs[face->getVertex(2)]->getPoint(), m_vertexs[face->getVertex(1)]->getPoint(), m_vertexs[face->getVertex(0)]->getPoint()) << endl; if (BOP_collinear(m_vertexs[face->getVertex(0)]->getPoint(), m_vertexs[face->getVertex(1)]->getPoint(), m_vertexs[face->getVertex(2)]->getPoint())) { cout << " COLLINEAR!!!" << endl; } else { cout << endl; } } }
/** * Computes the best quad triangulation. * @param mesh mesh that contains the faces, edges and vertices * @param plane plane used to create the news faces * @param v1 first vertex index * @param v2 second vertex index * @param v3 third vertex index * @param v4 fourth vertex index * @param triangles array of faces where the new two faces will be saved * @param original face index to the new faces */ void BOP_splitQuad(BOP_Mesh* mesh, MT_Plane3 plane, BOP_Index v1, BOP_Index v2, BOP_Index v3, BOP_Index v4, BOP_Face* triangles[], BOP_Index original) { MT_Point3 p1 = mesh->getVertex(v1)->getPoint(); MT_Point3 p2 = mesh->getVertex(v2)->getPoint(); MT_Point3 p3 = mesh->getVertex(v3)->getPoint(); MT_Point3 p4 = mesh->getVertex(v4)->getPoint(); int res = BOP_concave(p1,p2,p3,p4); if (res==0) { MT_Plane3 plane1(p1, p2, p3); MT_Plane3 plane2(p1, p3, p4); if (BOP_isInsideCircle(mesh, v1, v2, v4, v3) && BOP_orientation(plane1, plane) && BOP_orientation(plane2, plane)) { triangles[0] = new BOP_Face3(v1, v2, v3, plane, original); triangles[1] = new BOP_Face3(v1, v3, v4, plane, original); } else { triangles[0] = new BOP_Face3(v1, v2, v4, plane, original); triangles[1] = new BOP_Face3(v2, v3, v4, plane, original); } } else if (res==-1) { triangles[0] = new BOP_Face3(v1, v2, v4, plane, original); triangles[1] = new BOP_Face3(v2, v3, v4, plane, original); } else { triangles[0] = new BOP_Face3(v1, v2, v3, plane, original); triangles[1] = new BOP_Face3(v1, v3, v4, plane, original); } }
/** * 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); } } } } } }
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++; } */ }