Exemplo n.º 1
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
/**
 * Creates a list of lists L1, L2, ... LN where
 *   LX = mesh faces with vertex v that come from the same original face
 *        and without any of the vertices that appear before v in vertices
 * @param facesByOriginalFace list of faces lists
 * @param vertices vector with vertices indexs that contains v
 * @param v vertex index
 */
void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v)
{
	// Get edges with vertex v
	BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
	const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
	for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {	
		// Foreach edge, add its no broken faces to the output list
		BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
		BOP_Indexs faceIndexs = edge->getFaces();
		const BOP_IT_Indexs faceEnd = faceIndexs.end();
		for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
			BOP_Face* face = m_mesh->getFace(*faceIndex);
			if (face->getTAG() != BROKEN) {
				// Search if the face contains any of the forbidden vertices
				bool found = false;
				for(BOP_IT_Indexs vertex = vertices.begin();*vertex!= v;vertex++) {
					if (face->containsVertex(*vertex)) {
						// face contains a forbidden vertex!
						found = true;
						break;
				}
			}
			if (!found) {
				// Search if we already have created a list with the 
				// faces that come from the same original face
			  const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
				for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
					facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
					if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
						// Search that the face has not been added to the list before
						for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
							if ((*facesByOriginalFaceX)[i] == face) {
								found = true;
								break;
							}
						}
						if (!found) {
						  // Add face to the list
						  if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
						  else facesByOriginalFaceX->push_back(face);
						  found = true;
						}
						break;
					}
				}
				if (!found) {
					// Create a new list and add the current face
					BOP_Faces facesByOriginalFaceX;
					facesByOriginalFaceX.push_back(face);
					facesByOriginalFace.push_back(facesByOriginalFaceX);
				}
			}
		}
	}
	}
}
Exemplo n.º 5
0
/**
 * 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);
					}
				}
			}
		}
	}
}
Exemplo n.º 6
0
/**
 * testMesh
 */
void BOP_Mesh::testMesh()
{

	BOP_Face* cares[10];
	unsigned int nedges=0,i;
	for(i=0;i<m_edges.size();i++) {
		BOP_Edge *edge = m_edges[i];
		BOP_Indexs faces = edge->getFaces();
		unsigned int count = 0;
		const BOP_IT_Indexs facesEnd = faces.end();
		for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) {
			if (m_faces[*it]->getTAG()!=BROKEN) {
				cares[count] = m_faces[*it];
				count++;
				
			}
		}

		if ((count%2)!=0) nedges++;
	}
	if (nedges)
	  cout << nedges << " wrong edges." << endl;
	else
	  cout << "well edges." << endl;

	unsigned int duplFaces = 0;
	unsigned int wrongFaces = 0;
	for(i=0;i<m_faces.size();i++){
	  BOP_Face *faceI = m_faces[i];
	  if (faceI->getTAG()==BROKEN)
	    continue;

	  if (testFace(faceI)){
	    wrongFaces++;
	    cout << "Wrong Face: " << faceI << endl;
	  }

	  for(unsigned int j=i+1;j<m_faces.size();j++){
	    BOP_Face *faceJ = m_faces[j];

	    if (faceJ->getTAG()==BROKEN)
	      continue;

	    if (testFaces(faceI,faceJ)){
	      duplFaces++;
	      cout << "Duplicate FaceI: " << faceI << endl;
	      cout << "Duplicate FaceJ: " << faceJ << endl;
	    }
	  }
	}

	cout << duplFaces << " duplicate faces." << endl;
	cout << wrongFaces << " wrong faces." << endl;
}
Exemplo n.º 7
0
/**
 * updatePlanes
 */
void BOP_Mesh::updatePlanes() 
{
  const BOP_IT_Faces facesEnd = m_faces.end();
	for(BOP_IT_Faces it = m_faces.begin();it!=facesEnd;it++) {
	  BOP_Face *face = *it;
	  MT_Plane3 plane(m_vertexs[face->getVertex(0)]->getPoint(), 
			  m_vertexs[face->getVertex(1)]->getPoint(),
			  m_vertexs[face->getVertex(2)]->getPoint());
	  face->setPlane(plane);
	}
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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++;
		}
	}
}
Exemplo n.º 11
0
/**
 * Returns the first face of faces that shares the input edge of face.
 * @param mesh mesh that contains the faces, edges and vertices
 * @param faces set of faces
 * @param face input face
 * @param edge face's edge
 * @return first face that shares the edge of input face
 */
BOP_Face *BOP_getOppositeFace(BOP_Mesh*  mesh, 
							  BOP_Faces* faces, 
							  BOP_Face*  face,
							  BOP_Edge*  edge)
{
	if (edge == NULL)
	  return NULL;
  
	BOP_Indexs auxfaces = edge->getFaces();
	const BOP_IT_Indexs auxfacesEnd = auxfaces.end();
	for(BOP_IT_Indexs it = auxfaces.begin(); it != auxfacesEnd; it++) {
		BOP_Face *auxface = mesh->getFace(*it);
		if ((auxface != face) && (auxface->getTAG()!=BROKEN) && 
			BOP_containsFace(faces,auxface)) {
			return auxface;
		}
	}        
  
	return NULL;
}
Exemplo n.º 12
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++;
		}
	}
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
0
void BOP_Merge2::cleanup( void )
{
	BOP_Edges edges = m_mesh->getEdges();
	for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); ++edge) {
		BOP_Indexs faces = (*edge)->getFaces();
		for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face) {
			BOP_Face *f = m_mesh->getFace(*face);
			if(f->getTAG()== UNCLASSIFIED) ;
			else (*edge)->removeFace(*face);
		}
		if( (*edge)->getFaces().size() == 0) (*edge)->setUsed(false);
	}

	BOP_Vertexs v = m_mesh->getVertexs();
	for( BOP_IT_Vertexs it = v.begin(); it != v.end(); ++it ) {
		if( (*it)->getTAG() != BROKEN) {
			BOP_Indexs iedges = (*it)->getEdges();
			for(BOP_IT_Indexs i = iedges.begin();i!=iedges.end();i++)
				if( m_mesh->getEdge((*i))->getUsed( ) == false) (*it)->removeEdge( *i );
			if( (*it)->getEdges().size() == 0 ) (*it)->setTAG(BROKEN);
		}
	}
	// clean_nonmanifold( m_mesh );
}
Exemplo n.º 15
0
/**
 * Adds the new face into the faces set and the mesh and sets it a new tag.
 * @param mesh mesh that contains the faces, edges and vertices
 * @param faces set of faces that contains oldFace
 * @param face input face to be added
 * @param tag tag of the new face
 */
void BOP_addFace(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, BOP_TAG tag)
{
	BOP_Index av1 = face->getVertex(0);
	BOP_Index av2 = face->getVertex(1);
	BOP_Index av3 = face->getVertex(2);

	/*
	 * Before adding a new face to the face list, be sure it's not
	 * already there.  Duplicate faces have been found to cause at
	 * least two instances of infinite loops.  Also, some faces are
	 * created which have the same vertex twice.  Don't add these either.
	 *
	 * When someone has more time to look into this issue, it's possible
	 * this code may be removed again.
	 */
	if( av1==av2 || av2==av3  || av3==av1 ) return;

	for(unsigned int idxFace=0;idxFace<faces->size();idxFace++) {
		BOP_Face *faceA = (*faces)[idxFace];
		BOP_Index bv1 = faceA->getVertex(0);
		BOP_Index bv2 = faceA->getVertex(1);
		BOP_Index bv3 = faceA->getVertex(2);

		if( ( av1==bv1 && av2==bv2 && av3==bv3 ) ||
	        ( av1==bv1 && av2==bv3 && av3==bv2 ) ||
	        ( av1==bv2 && av2==bv1 && av3==bv3 ) ||
	        ( av1==bv2 && av2==bv3 && av3==bv1 ) ||
	        ( av1==bv3 && av2==bv2 && av3==bv1 ) ||
	        ( av1==bv3 && av2==bv1 && av3==bv3 ) )
			return;
	}

	face->setTAG(tag);    
	faces->push_back(face);
	mesh->addFace(face);
}
Exemplo n.º 16
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);
		}
	}
}
Exemplo n.º 17
0
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++;
	}
	*/
}
Exemplo n.º 18
0
/**
 * Triangulates the input face according to the specified segment.
 * @param mesh mesh that contains the faces, edges and vertices
 * @param faces set of faces that contains the original face and the new triangulated faces
 * @param face face to be triangulated
 * @param s segment used to triangulate face
 */
void triangulate(BOP_Mesh *mesh, BOP_Faces *faces, BOP_Face *face, BOP_Segment s)
{
	if (BOP_Segment::isUndefined(s.m_cfg1)) {
		// Nothing to do
	}
	else if (BOP_Segment::isVertex(s.m_cfg1)) {
		// VERTEX(v1) + VERTEX(v2) => nothing to do
	}
	else if (BOP_Segment::isEdge(s.m_cfg1)) {
		if (BOP_Segment::isVertex(s.m_cfg2) || BOP_Segment::isUndefined(s.m_cfg2)) {
			// EDGE(v1) + VERTEX(v2)
			BOP_Edge *edge = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg1));
			BOP_triangulateA(mesh,faces,face,s.m_v1,BOP_Segment::getEdge(s.m_cfg1));
			BOP_Face *opposite = BOP_getOppositeFace(mesh,faces,face,edge);
			if (opposite != NULL) {
			  unsigned int e;
			  opposite->getEdgeIndex(edge->getVertex1(), edge->getVertex2(),e);
			  BOP_triangulateA(mesh, faces, opposite, s.m_v1, e);
			}
		}
		else {
			//  EDGE(v1) + EDGE(v2)
			if (BOP_Segment::getEdge(s.m_cfg1) == BOP_Segment::getEdge(s.m_cfg2)) {
				 // EDGE(v1) == EDGE(v2)
				BOP_Edge *edge = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg1));
				BOP_triangulateD(mesh, faces, face, s.m_v1, s.m_v2, 
								 BOP_Segment::getEdge(s.m_cfg1)); 
				BOP_Face *opposite = BOP_getOppositeFace(mesh,faces,face,edge);
				if (opposite != NULL) {
				  unsigned int e;
				  opposite->getEdgeIndex(edge->getVertex1(), edge->getVertex2(),e);
				  BOP_triangulateD(mesh, faces, opposite, s.m_v1, s.m_v2, e);
				}
    		}
			else { // EDGE(v1) != EDGE(v2)
				BOP_Edge *edge1 = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg1));
				BOP_Edge *edge2 = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg2));
				BOP_triangulateE(mesh, faces, face, s.m_v1, s.m_v2,
								 BOP_Segment::getEdge(s.m_cfg1),
								 BOP_Segment::getEdge(s.m_cfg2));
				BOP_Face *opposite = BOP_getOppositeFace(mesh,faces,face,edge1);
				if (opposite != NULL) {
				  unsigned int e;
				  opposite->getEdgeIndex(edge1->getVertex1(), edge1->getVertex2(),e);
				  BOP_triangulateA(mesh, faces, opposite, s.m_v1, e);
				}
				opposite = BOP_getOppositeFace(mesh,faces,face,edge2);
				if (opposite != NULL) {
				  unsigned int e;
				  opposite->getEdgeIndex(edge2->getVertex1(), edge2->getVertex2(),e);
				  BOP_triangulateA(mesh, faces, opposite, s.m_v2, e);
				}
			}
		}
	}
	else if (BOP_Segment::isIn(s.m_cfg1)) {
		if (BOP_Segment::isVertex(s.m_cfg2) || BOP_Segment::isUndefined(s.m_cfg2)) {
			// IN(v1) + VERTEX(v2)
			BOP_triangulateB(mesh,faces,face,s.m_v1);
		}
		else if (BOP_Segment::isEdge(s.m_cfg2)) {
			// IN(v1) + EDGE(v2)
			BOP_Edge *edge = mesh->getEdge(face,BOP_Segment::getEdge(s.m_cfg2));
			BOP_triangulateF(mesh,faces,face,s.m_v1,s.m_v2,BOP_Segment::getEdge(s.m_cfg2));
			BOP_Face *opposite = BOP_getOppositeFace(mesh,faces,face,edge);
			if (opposite != NULL) {
			  unsigned int e;
			  opposite->getEdgeIndex(edge->getVertex1(), edge->getVertex2(),e);
			  BOP_triangulateA(mesh, faces, opposite, s.m_v2, e);
			}
		}
		else // IN(v1) + IN(v2)
			BOP_triangulateC(mesh,faces,face,s.m_v1,s.m_v2);
	}
}
Exemplo n.º 19
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);
	}
}
Exemplo n.º 20
0
/**
 * Triangulates faceB using edges of faceA that both are complanars.
 * @param mesh mesh that contains the faces, edges and vertices
 * @param facesB set of faces from object B
 * @param faceA face from object A
 * @param faceB face from object B
 * @param invert indicates if faceA has priority over faceB
 */
void BOP_intersectCoplanarFaces(BOP_Mesh*  mesh,
								BOP_Faces* facesB, 
								BOP_Face*  faceA, 
								BOP_Face*  faceB, 
								bool       invert)
{
	unsigned int oldSize = facesB->size();
	unsigned int originalFaceB = faceB->getOriginalFace();    
	
	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();
	
	MT_Vector3 normal(faceA->getPlane().x(),faceA->getPlane().y(),faceA->getPlane().z());
	
	MT_Vector3 p1p2 = p2-p1;
	
	MT_Plane3 plane1((p1p2.cross(normal).normalized()),p1);
	
	BOP_Segment sA;
	sA.m_cfg1 = BOP_Segment::createVertexCfg(1);
	sA.m_v1 = faceA->getVertex(0);
	sA.m_cfg2 = BOP_Segment::createVertexCfg(2);
	sA.m_v2 = faceA->getVertex(1);
	
	BOP_intersectCoplanarFaces(mesh,facesB,faceB,sA,plane1,invert);
	
	MT_Vector3 p2p3 = p3-p2;
	MT_Plane3 plane2((p2p3.cross(normal).normalized()),p2);
	
	sA.m_cfg1 = BOP_Segment::createVertexCfg(2);
	sA.m_v1 = faceA->getVertex(1);
	sA.m_cfg2 = BOP_Segment::createVertexCfg(3);
	sA.m_v2 = faceA->getVertex(2);
  
	if (faceB->getTAG() == BROKEN) {
		for(unsigned int idxFace = oldSize; idxFace < facesB->size(); idxFace++) {
			BOP_Face *face = (*facesB)[idxFace];
			if (face->getTAG() != BROKEN && originalFaceB == face->getOriginalFace())
				BOP_intersectCoplanarFaces(mesh,facesB,face,sA,plane2,invert);
		}
	}
	else {
		BOP_intersectCoplanarFaces(mesh,facesB,faceB,sA,plane2,invert);
	}
  
	MT_Vector3 p3p1 = p1-p3;
	MT_Plane3 plane3((p3p1.cross(normal).safe_normalized()),p3);
	
	sA.m_cfg1 = BOP_Segment::createVertexCfg(3);
	sA.m_v1 = faceA->getVertex(2);
	sA.m_cfg2 = BOP_Segment::createVertexCfg(1);
	sA.m_v2 = faceA->getVertex(0);
  
	if (faceB->getTAG() == BROKEN) {
		for(unsigned int idxFace = oldSize; idxFace < facesB->size(); idxFace++) {
			BOP_Face *face = (*facesB)[idxFace];
			if (face->getTAG() != BROKEN && originalFaceB == face->getOriginalFace())
				BOP_intersectCoplanarFaces(mesh,facesB,face,sA,plane3,invert);
		}
	}
	else {
		BOP_intersectCoplanarFaces(mesh,facesB,faceB,sA,plane3,invert);
	} 
}
Exemplo n.º 21
0
void dumpmesh ( BOP_Mesh *m, bool force )
{
	unsigned int nonmanifold = 0;
	{
	BOP_Edges edges = m->getEdges();
	int count = 0;
    for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
		++count, ++edge) {
		if (!(*edge)->getUsed() && (*edge)->getFaces().size() == 0 ) continue;
		BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
		BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());

		if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
			int fcount = 0;
			BOP_Indexs faces = (*edge)->getFaces();
			for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
				BOP_Face *f = m->getFace(*face);
				if(f->getTAG()== UNCLASSIFIED) ++fcount;
			}


			if(fcount !=0 && fcount !=2 ) {
				++nonmanifold;
			}
		}
	}
	if (!force && nonmanifold == 0) return;
	}
	if( nonmanifold )
		cout << nonmanifold << " edges detected" << endl;
#ifdef BOP_DEBUG
	cout << "---------------------------" << endl;

	BOP_Edges edges = m->getEdges();
	int count = 0;
    for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
		++count, ++edge) {
		BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
		BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());

		if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
			int fcount = 0;
			BOP_Indexs faces = (*edge)->getFaces();
			cout << count << ", " << (*edge) << ", " << faces.size() << endl;
			for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
				BOP_Face *f = m->getFace(*face);
				if(f->getTAG()== UNCLASSIFIED) ++fcount;
				cout << "  face " << f << endl;
			}


			if(fcount !=0 && fcount !=2 )
				cout << "    NON-MANIFOLD" << endl;
		}
	}

	BOP_Faces faces = m->getFaces();
	count = 0;
    for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) {
		if( count < 12*2 || (*face)->getTAG() != BROKEN ) {
			cout << count << ", " << *face << endl;
		}
		++count;
	}

	BOP_Vertexs verts = m->getVertexs();
	count = 0;
    for (BOP_IT_Vertexs vert = verts.begin(); vert != verts.end(); vert++) {
		cout << count++ << ", " << *vert << " " << (*vert)->getNumEdges() << endl;
		BOP_Indexs edges = (*vert)->getEdges();
	    for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
			BOP_Edge *edge = m->getEdge(*it);
			cout << "   " << edge << endl;
		}
	}
	cout << "===========================" << endl;
#endif
}