/** * 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); } }
/** * Intersects a plane with the line that contains the specified points. * @param plane split plane * @param p1 first line point * @param p2 second line point * @return intersection between plane and line that contains p1 and p2 */ MT_Point3 BOP_intersectPlane(const MT_Plane3& plane, const MT_Point3& p1, const MT_Point3& p2) { // Compute intersection between plane and line ... // // L: (p2-p1)lambda + p1 // // supposes resolve equation ... // // coefA*((p2.x - p1.y)*lambda + p1.x) + ... + coefD = 0 MT_Point3 intersection = MT_Point3(0,0,0); //never ever return anything undefined! MT_Scalar den = plane.x()*(p2.x()-p1.x()) + plane.y()*(p2.y()-p1.y()) + plane.z()*(p2.z()-p1.z()); if (den != 0) { MT_Scalar lambda = (-plane.x()*p1.x()-plane.y()*p1.y()-plane.z()*p1.z()-plane.w()) / den; intersection.setValue(p1.x() + (p2.x()-p1.x())*lambda, p1.y() + (p2.y()-p1.y())*lambda, p1.z() + (p2.z()-p1.z())*lambda); return intersection; } return intersection; }
/** * Returns if a plane contains a point with EPSILON accuracy. * @param plane plane * @param point point * @return true if the point is on the plane, false otherwise */ bool BOP_containsPoint(const MT_Plane3& plane, const MT_Point3& point) { return BOP_fuzzyZero(plane.signedDistance(point)); }
/** * Classifies a point according to the specified plane with EPSILON accuracy. * @param p point * @param plane plane * @return >0 if the point is above (OUT), * =0 if the point is on (ON), * <0 if the point is below (IN) */ int BOP_classify(const MT_Point3& p, const MT_Plane3& plane) { // Compare plane - point distance with zero return BOP_comp0(plane.signedDistance(p)); }
/** * Returns if two planes share the same orientation. * @return >0 if planes share the same orientation */ MT_Scalar BOP_orientation(const MT_Plane3& p1, const MT_Plane3& p2) { // Dot product between plane normals return (p1.x()*p2.x() + p1.y()*p2.y() + p1.z()*p2.z()); }
bool BSP_CSGMesh:: SC_Face( BSP_FaceInd f ){ #if 0 { // check area is greater than zero. vector<BSP_MVertex> & verts = VertexSet(); vector<BSP_VertexInd> f_verts; FaceVertices(f,f_verts); MT_assert(f_verts.size() >= 3); BSP_VertexInd root = f_verts[0]; MT_Scalar area = 0; for (int i=2; i < f_verts.size(); i++) { MT_Vector3 a = verts[root].m_pos; MT_Vector3 b = verts[f_verts[i-1]].m_pos; MT_Vector3 c = verts[f_verts[i]].m_pos; MT_Vector3 l1 = b-a; MT_Vector3 l2 = c-b; area += (l1.cross(l2)).length()/2; } MT_assert(!MT_fuzzyZero(area)); } #endif // Check coplanarity #if 0 MT_Plane3 plane = FacePlane(f); const BSP_MFace & face = FaceSet()[f]; vector<BSP_VertexInd>::const_iterator f_verts_it = face.m_verts.begin(); vector<BSP_VertexInd>::const_iterator f_verts_end = face.m_verts.end(); for (;f_verts_it != f_verts_end; ++f_verts_it) { MT_Scalar dist = plane.signedDistance( VertexSet()[*f_verts_it].m_pos ); MT_assert(fabs(dist) < BSP_SPLIT_EPSILON); } #endif // Check connectivity vector<BSP_EdgeInd> f_edges; FaceEdges(f,f_edges); MT_assert(f_edges.size() == FaceSet()[f].m_verts.size()); unsigned int i; for (i = 0; i < f_edges.size(); ++i) { int matches = 0; for (unsigned int j = 0; j < EdgeSet()[f_edges[i]].m_faces.size(); j++) { if (EdgeSet()[f_edges[i]].m_faces[j] == f) matches++; } MT_assert(matches == 1); } return true; }