Example #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);
	}
}
Example #2
0
/** 
 * Returns a new quad (convex) from the merge of two triangles that share the
 * vertex index v.
 * @param faceI mesh triangle
 * @param faceJ mesh triangle
 * @param v vertex index shared by both triangles
 * @return a new convex quad if the merge is possible
 */
BOP_Face* BOP_Merge::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v)
{
	BOP_Face *faceK = NULL;

	// Get faces data
	BOP_Index prevI, nextI, prevJ, nextJ;
	faceI->getNeighbours(v,prevI,nextI);
	faceJ->getNeighbours(v,prevJ,nextJ);
	MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
	MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
	MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
	MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
	MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();

	// Quad test
	if (prevI == nextJ) {
		if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) &&
			BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) {
				faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
		}
	}
	else if (nextI == prevJ) {
		if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) &&
			BOP_convex(vertex,vNextJ,vNextI,vPrevI)) {
				faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
			}
	}
	return faceK;
}
Example #3
0
/** 
 * Returns a new triangle from the merge of two triangles that share the vertex
 * v and come from the same original face.
 * @param faceI mesh triangle
 * @param faceJ mesh triangle
 * @param v vertex index shared by both triangles
 * @return If the merge is possible, a new triangle without v
 */
BOP_Face* BOP_Merge::mergeFaces(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v)
{
	BOP_Face *faceK = NULL;

	// Get faces data
	BOP_Index prevI, nextI, prevJ, nextJ;	
	faceI->getNeighbours(v,prevI,nextI);
	faceJ->getNeighbours(v,prevJ,nextJ);
	MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
	MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
	MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
	MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
	MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();

	// Merge test
	if (prevI == nextJ) {
		// Both faces share the edge (prevI,v) == (v,nextJ)
		if (BOP_between(vertex,vNextI,vPrevJ)) {
			faceK = new BOP_Face3(prevI,prevJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
			faceK->setTAG(faceI->getTAG());
		}
	}
	else if (nextI == prevJ) {
		// Both faces share the edge (v,nextI) == (prevJ,v)
		if (BOP_between(vertex,vPrevI,vNextJ)) {
			faceK = new BOP_Face3(prevI,nextJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
			faceK->setTAG(faceI->getTAG());
		}
	}
	return faceK;
}
Example #4
0
/** 
 * Returns a new quad (convex) from the merge of two triangles that share the
 * vertex index v.
 * @param faceI mesh triangle
 * @param faceJ mesh triangle
 * @param v vertex index shared by both triangles
 * @return a new convex quad if the merge is possible
 */
BOP_Face* BOP_Merge2::createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ)
{
	BOP_Face *faceK = NULL;
	//
	// Test if both quads share a vertex index
	//
	BOP_Index v;
	unsigned int i;
	for(i=0;i<4 ;i++) {
		v = faceI->getVertex(i);
		if( faceJ->containsVertex(v) ) break;
	}
	if (i == 3) return NULL;


	// Get faces data
	BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ;
	faceI->getNeighbours(v,prevI,nextI,oppI);
	faceJ->getNeighbours(v,prevJ,nextJ,oppJ);

	// Quad test
	BOP_Index edge;
	if (nextI == prevJ) {
		if (prevI == nextJ) {	// v is in center
			faceK = new BOP_Face4(nextI,oppI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
			faceK->setTAG(faceI->getTAG());
			m_mesh->getIndexEdge(v,prevI,edge);
			m_mesh->getVertex(v)->removeEdge(edge);
			m_mesh->getVertex(prevI)->removeEdge(edge);
			m_mesh->getIndexEdge(v,nextI,edge);
			m_mesh->getVertex(v)->removeEdge(edge);
			m_mesh->getVertex(nextI)->removeEdge(edge);
			freeVerts(v, m_mesh->getVertex(v));
		} else if (oppI == oppJ) {	// nextI is in center
			faceK = new BOP_Face4(v,nextJ,oppJ,prevI,faceI->getPlane(),faceI->getOriginalFace());
			faceK->setTAG(faceI->getTAG());
			m_mesh->getIndexEdge(v,nextI,edge);
			m_mesh->getVertex(v)->removeEdge(edge);
			m_mesh->getVertex(nextI)->removeEdge(edge);
			m_mesh->getIndexEdge(prevI,nextI,edge);
			m_mesh->getVertex(prevI)->removeEdge(edge);
			m_mesh->getVertex(nextI)->removeEdge(edge);
			freeVerts(nextI, m_mesh->getVertex(nextI));
		}
	} else if (prevI == nextJ && oppI == oppJ) { // prevI is in center
		faceK = new BOP_Face4(v,nextI,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace());
		faceK->setTAG(faceI->getTAG());
		m_mesh->getIndexEdge(v,prevI,edge);
		m_mesh->getVertex(v)->removeEdge(edge);
		m_mesh->getVertex(prevI)->removeEdge(edge);
		m_mesh->getIndexEdge(nextI,prevI,edge);
		m_mesh->getVertex(nextI)->removeEdge(edge);
		m_mesh->getVertex(prevI)->removeEdge(edge);
		freeVerts(prevI, m_mesh->getVertex(prevI));
	}
	return faceK;
}
Example #5
0
/** 
 * Returns a new face (quad or triangle) from the merge of one quad and one 
 * triangle that share the vertex v and come from the same original face.
 * @param faceI mesh quad
 * @param faceJ mesh triangle
 * @param pending vector with pending vertices (required to merge one quad 
 * and one triangle into a new triangle; it supposes to remove two vertexs,
 * v and its neighbour, that will be a new pending vertex if it wasn't)
 * @param v vertex index shared by both faces
 * @return If the merge is possible, a new face without v
 */
BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Indexs &pending, BOP_Index v)
{
	BOP_Face *faceK = NULL;

	// Get faces data
	BOP_Index prevI, nextI, opp, prevJ, nextJ;
	faceI->getNeighbours(v,prevI,nextI,opp);
	faceJ->getNeighbours(v,prevJ,nextJ);
	MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
	MT_Point3 vOpp = m_mesh->getVertex(opp)->getPoint();
	MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
	MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
	MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
	MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();

	// Merge test
	if (prevI == nextJ) {
		if (BOP_between(vertex,vNextI,vPrevJ)) {
			if (!BOP_collinear(vPrevJ,vPrevI,vOpp) && BOP_convex(vOpp,vPrevI,vPrevJ,vNextI)) {
				// The result is a new quad
				faceK = new BOP_Face4(opp,prevI,prevJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
			}
			else if (BOP_between(vPrevI,vPrevJ,vOpp)) {
				// The result is a triangle (only if prevI can be merged)
				if (prevI < m_firstVertex) return NULL; // It can't be merged
				faceK = new BOP_Face3(nextI,opp,prevJ,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
				if (!containsIndex(pending, prevI)) pending.push_back(prevI);
			}
		}
	}
	else if (nextI == prevJ) {
		if (BOP_between(vertex,vPrevI,vNextJ)) {
			if (!BOP_collinear(vNextJ,vNextI,vOpp) && BOP_convex(vOpp,vPrevI,vNextJ,vNextI)) {
				// The result is a new quad
				faceK = new BOP_Face4(opp,prevI,nextJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
			}
			else if (BOP_between(vNextI,vOpp,vNextJ)) {
				// The result is a triangle (only if nextI can be merged)
				if (nextI < m_firstVertex) return NULL;
				faceK = new BOP_Face3(prevI,nextJ,opp,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
				if (!containsIndex(pending, nextI)) pending.push_back(nextI);
			}
		}
	}
	return faceK;
}
Example #6
0
/** 
 * Returns a new quad (convex) from the merge of two triangles that share the
 * vertex index v.
 * @param faceI mesh triangle
 * @param faceJ mesh triangle
 * @param v vertex index shared by both triangles
 * @return a new convex quad if the merge is possible
 */
BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ)
{
	// Test if both triangles share a vertex index
	BOP_Index v;
	unsigned int i;
	for(i=0;i<3 ;i++) {
		v = faceI->getVertex(i);
		if( faceJ->containsVertex(v) ) break;
	}
	if (i == 3) return NULL;

	BOP_Face *faceK = NULL;

	// Get faces data
	BOP_Index prevI, nextI, prevJ, nextJ;
	faceI->getNeighbours(v,prevI,nextI);
	faceJ->getNeighbours(v,prevJ,nextJ);
	MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
	MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
	MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
	MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
	MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();

	// Quad test
	if (prevI == nextJ) {
		if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) &&
			BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) {
				faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
				BOP_Index edge;
				m_mesh->getIndexEdge(v,prevI,edge);
				m_mesh->getVertex(v)->removeEdge(edge);
				m_mesh->getVertex(prevI)->removeEdge(edge);
		}
	}
	else if (nextI == prevJ) {
		if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) &&
			BOP_convex(vertex,vNextJ,vNextI,vPrevI)) {
				faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
				BOP_Index edge;
				m_mesh->getIndexEdge(v,nextI,edge);
				m_mesh->getVertex(v)->removeEdge(edge);
				m_mesh->getVertex(nextI)->removeEdge(edge);
			}
	}
	return faceK;
}
Example #7
0
/** 
 * Returns a new quad from the merge of two quads that share 
 * the vertex v and come from the same original face.
 * @param faceI mesh quad
 * @param faceJ mesh quad
 * @param pending vector with pending vertices (required to merge the two
 * quads supposes to remove two vertexs, v and its neighbour, 
 * that will be a new pending vertex if it wasn't)
 * @param v vertex index shared by both quads
 * @return If the merge is possible, a new quad without v
 */
BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face4 *faceJ, BOP_Indexs &pending, BOP_Index v)
{
	BOP_Face *faceK = NULL;

	// Get faces data
	BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ;
	faceI->getNeighbours(v,prevI,nextI,oppI);
	faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
	MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
	MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
	MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
	MT_Point3 vOppI = m_mesh->getVertex(oppI)->getPoint();
	MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
	MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
	MT_Point3 vOppJ = m_mesh->getVertex(oppJ)->getPoint();

	// Merge test
	if (prevI == nextJ) {
		// prevI/nextJ will be a new vertex required to merge
		if (prevI < m_firstVertex) return NULL; // It can't be merged
		if (BOP_between(vertex,vPrevJ,vNextI) && BOP_between(vNextJ,vOppJ,vOppI)) {
			faceK = new BOP_Face4(oppJ,prevJ,nextI,oppI,faceI->getPlane(),faceI->getOriginalFace());
			faceK->setTAG(faceI->getTAG());
			// We add prevI to the pending list if it wasn't yet
			if (!containsIndex(pending, prevI)) pending.push_back(prevI);
		}
	}
	else if (nextI == prevJ) {
		// nextI/prevJ will be a new vertex required to merge
		if (nextI < m_firstVertex) return NULL; // It can't be merged
		if (BOP_between(vertex,vPrevI,vNextJ) && BOP_between(vNextI,vOppI,vOppJ)) {
			faceK = new BOP_Face4(oppI,prevI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
			faceK->setTAG(faceI->getTAG());
			// Add nextI to the pending list if it wasn't yet
			if (!containsIndex(pending, nextI)) pending.push_back(nextI);
		}
	}
	return faceK;
}
Example #8
0
/**
 * Tests if faces since firstFace have all vertexs non-coincident of colinear, otherwise repairs the mesh.
 * @param mesh mesh that contains the faces, edges and vertices
 * @param firstFace first face index to be tested
 */
void BOP_mergeVertexs(BOP_Mesh *mesh, unsigned int firstFace)
{
	unsigned int numFaces = mesh->getNumFaces();
	for(unsigned int idxFace = firstFace; idxFace < numFaces; idxFace++) {
		BOP_Face *face = mesh->getFace(idxFace);
		if ((face->getTAG() != BROKEN) && (face->getTAG() != PHANTOM)) {
			MT_Point3 vertex1 = mesh->getVertex(face->getVertex(0))->getPoint();
			MT_Point3 vertex2 = mesh->getVertex(face->getVertex(1))->getPoint();
			MT_Point3 vertex3 = mesh->getVertex(face->getVertex(2))->getPoint();
			if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle 
				face->setTAG(PHANTOM);
		}
	}
}
Example #9
0
/**
 * Pre-process to filter no collisioned faces.
 * @param meshC Input & Output mesh data
 * @param faces Faces list to test
 * @param bsp BSP tree used to filter
 * @param inverted determines if the object is inverted
 */
void BOP_simplifiedMeshFilter(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp, bool inverted)
{
	BOP_IT_Faces it;
	
	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 (bsp->filterFace(p1,p2,p3,face)==OUT) {
			if (!inverted) face->setTAG(BROKEN);
			it = faces->erase(it);
		}
		else {
			it++;
		}
	}
}
Example #10
0
/**
 * 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++;
		}
	}
}