예제 #1
0
/**
 * 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);
	}
}
예제 #2
0
/**
 * 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;
}
예제 #3
0
/**
 * 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));
}
예제 #4
0
/**
 * 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));
}
예제 #5
0
/**
 * 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());
}
예제 #6
0
	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;
}