Exemple #1
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);
				}
			}
		}
	}
	}
}
Exemple #2
0
/**
 * Returns the first edge with the specified vertex index from a list of edge indexs.
 * @param edges edge indexs
 * @param v vertex index
 * @return first edge with the specified vertex index, NULL otherwise
 */
BOP_Edge* BOP_Mesh::getEdge(BOP_Indexs edges, BOP_Index v)
{
  const BOP_IT_Indexs edgesEnd = edges.end();
	for(BOP_IT_Indexs it=edges.begin();it!=edgesEnd;it++){
		BOP_Edge *edge = m_edges[*it];
		if ((edge->getVertex1() == v) || (edge->getVertex2() == v))
			return edge;
	}
	return NULL;
}
Exemple #3
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;
}
Exemple #4
0
/**
 * remove edges from vertices when the vertex is removed
 */
void BOP_Merge2::freeVerts(BOP_Index v, BOP_Vertex *vert)
{
	BOP_Indexs edges = vert->getEdges();
	BOP_Vertex *other;

	for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
		BOP_Edge *edge = m_mesh->getEdge(*it);
		BOP_Indexs edges2;
		if( edge->getVertex1() != v )
			other = m_mesh->getVertex( edge->getVertex1() );
		else
			other = m_mesh->getVertex( edge->getVertex2() );
		other->removeEdge(*it);
		vert->removeEdge(*it);
	}
}
Exemple #5
0
bool BOP_Mesh::isClosedMesh()
{
	for(unsigned int 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)
				count++;
		}

		if ((count%2)!=0) return false;
	}

	return true;
}
Exemple #6
0
static void deleteFace(BOP_Mesh *m, BOP_Face *face)
{
	BOP_Index l2 = face->getVertex(0);
	BOP_Faces faces = m->getFaces();
	for(int i = face->size(); i-- ; ) {
		BOP_Indexs edges = m->getVertex(l2)->getEdges();
		BOP_Index l1 = face->getVertex(i);
		for(BOP_IT_Indexs it1 = edges.begin(); it1 != edges.end(); ++it1 ) {
			BOP_Edge *edge = m->getEdge(*it1);
			if( ( edge->getVertex1() == l1 && edge->getVertex2() == l2 ) ||
				( edge->getVertex1() == l2 && edge->getVertex2() == l1 ) ) {
				BOP_Indexs ef = edge->getFaces();
				for(BOP_IT_Indexs it = ef.begin(); it != ef.end(); ++it ) {
					if( m->getFace(*it) == face) {
						edge->removeFace(*it);
						break;
					}
				}
				break;
			}
		}
		l2 = l1;
	}
	face->setTAG(BROKEN);
}
Exemple #7
0
/**
 * testEdges
 */
bool BOP_Mesh::testEdges(BOP_Faces *facesObj)
{
	for(unsigned int 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) && containsFace(facesObj,m_faces[*it]))
				count++;
		}
		if ((count%2)!=0) {
			return false;
		}
	}
	
	return true;
}
Exemple #8
0
/**
 * Simplifies a mesh, merging the faces with the specified vertices.
 * @param mergeVertices vertices to test
 * @return true if a face merge was performed
 */
bool BOP_Merge2::mergeFaces(BOP_Indexs &mergeVertices)
{
	// Check size > 0!
	if (mergeVertices.size() == 0) return false;
	bool didMerge = false;

	for( BOP_Index i = 0; i < mergeVertices.size(); ++i ) {
		BOP_LFaces facesByOriginalFace;
		BOP_Index v = mergeVertices[i];
		BOP_Vertex *vert = m_mesh->getVertex(v);
#ifdef BOP_DEBUG
		cout << "i = " << i << ", v = " << v << ", vert = " << vert << endl;
		if (v==48)
			cout << "found vert 48" << endl;
#endif
		if ( vert->getTAG() != BROKEN ) {
			getFaces(facesByOriginalFace,v);

			switch (facesByOriginalFace.size()) {
			case 0:
				// v has no unbroken faces (so it's a new BROKEN vertex)
				freeVerts( v, vert );
				vert->setTAG(BROKEN);
				break;
			case 2: {
#ifdef BOP_DEBUG
				cout << "size of fBOF = " << facesByOriginalFace.size() << endl;
#endif
				BOP_Faces ff = facesByOriginalFace.front();
				BOP_Faces fb = facesByOriginalFace.back();
				BOP_Index eindexs[2];
				int ecount = 0;

				// look for two edges adjacent to v which contain both ofaces
				BOP_Indexs edges = vert->getEdges();
#ifdef BOP_DEBUG
				cout << "   ff has " << ff.size() << " faces" << endl;
				cout << "   fb has " << fb.size() << " faces" << endl;
				cout << "   v  has " << edges.size() << " edges" << endl;
#endif
				for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); 
						++it ) {
					BOP_Edge *edge = m_mesh->getEdge(*it);
					BOP_Indexs faces = edge->getFaces();
#ifdef BOP_DEBUG
					cout << "  " << edge << " has " << edge->getFaces().size() << " faces" << endl;
#endif
					if( faces.size() == 2 ) {
						BOP_Face *f0 = m_mesh->getFace(faces[0]);
						BOP_Face *f1 = m_mesh->getFace(faces[1]);
						if( f0->getOriginalFace() != f1->getOriginalFace() ) {
#ifdef BOP_DEBUG
							cout << "   " << f0 << endl;
							cout << "   " << f1 << endl;
#endif
							eindexs[ecount++] = (*it);
						}
					}
				}
				if(ecount == 2) {
#ifdef BOP_DEBUG
					cout << "   edge indexes are " << eindexs[0];
					cout << " and " << eindexs[1] << endl;
#endif
					BOP_Edge *edge = m_mesh->getEdge(eindexs[0]);
					BOP_Index N = edge->getVertex1();
					if(N == v) N = edge->getVertex2();
#ifdef BOP_DEBUG
					cout << "    ## OK, replace "<<v<<" with "<<N << endl;
#endif
					mergeVertex(ff , v, N );
					mergeVertex(fb , v, N );
// now remove v and its edges
					vert->setTAG(BROKEN);
					for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); 
							++it ) {
						BOP_Edge *tedge = m_mesh->getEdge(*it);
						tedge->setUsed(false);
					}
					didMerge = true;
				}	
#ifdef BOP_DEBUG
				else {
					cout << "   HUH: ecount was " << ecount << endl;
				}
#endif
				}
				break;
			default:
				break;
			}
		}
	}

	return didMerge;
}
Exemple #9
0
void clean_nonmanifold( BOP_Mesh *m )
{
	return;

	BOP_Edges nme;
	BOP_Edges e = m->getEdges();
	for( BOP_IT_Edges it = e.begin(); it != e.end(); ++it ) {
		BOP_Indexs faces = (*it)->getFaces();
		if( faces.size() & ~2 )
			nme.push_back(*it);
	}
	if (nme.size() == 0) return;
	for( BOP_IT_Edges it = nme.begin(); it != nme.end(); ++it ) {
		if( (*it)->getFaces().size() > 1 ) {
			BOP_Indexs faces = (*it)->getFaces();
			for( BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face ) {
				MT_Point3 vertex1 = m->getVertex(m->getFace(*face)->getVertex(0))->getPoint();
				MT_Point3 vertex2 = m->getVertex(m->getFace(*face)->getVertex(1))->getPoint();
				MT_Point3 vertex3 = m->getVertex(m->getFace(*face)->getVertex(2))->getPoint();
				if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle
					deleteFace(m,m->getFace(*face));
			}
			continue;
		}
		BOP_Face *oface1 = m->getFace((*it)->getFaces().front());
		BOP_Face *oface2, *tmpface;
		BOP_Index first =(*it)->getVertex1();
		BOP_Index next =(*it)->getVertex2();
		BOP_Index last = first;
		unsigned short facecount = 0;
		bool found = false;
		BOP_Indexs vertList;
#ifdef BOP_DEBUG
		cout << "  first edge is " << (*it) << endl;
#endif
		vertList.push_back(first);
		BOP_Edge *edge;
		while(true) {
			BOP_Vertex *vert = m->getVertex(next);
			BOP_Indexs edges = vert->getEdges();
			edge = NULL;
			for( BOP_IT_Indexs eit = edges.begin(); eit != edges.end(); ++eit) {
				edge = m->getEdge(*eit);
				if( edge->getFaces().size() > 1) {
					edge = NULL;
					continue;
				}
				if( edge->getVertex1() == next && edge->getVertex2() != last ) {
					last = next;
					next = edge->getVertex2();
					break;
				}
				if( edge->getVertex2() == next && edge->getVertex1() != last ) {
					last = next;
					next = edge->getVertex1();
					break;
				}
				edge = NULL;
			}
			if( !edge ) break;
#ifdef BOP_DEBUG
			cout << "   next edge is " << edge << endl;
#endif
			tmpface = m->getFace(edge->getFaces().front());
			if( oface1->getOriginalFace() != tmpface->getOriginalFace() )
				oface2 = tmpface;
			else
				++facecount;
			vertList.push_back(last);
			if( vertList.size() > 3 ) break;
			if( next == first ) {
				found = true;
				break;
			}
		}
		if(found) {
			edge = *it;
#ifdef BOP_DEBUG
			cout << "   --> found a loop" << endl;
#endif
			if( vertList.size() == 3 ) {
				BOP_Face3 *face = (BOP_Face3 *)m->getFace(edge->getFaces().front());
				face->getNeighbours(first,last,next);
			} else if( vertList.size() == 4 ) {
				BOP_Face4 *face = (BOP_Face4 *)m->getFace(edge->getFaces().front());
				face->getNeighbours(first,last,next,last);
			} else {
#ifdef BOP_DEBUG
				cout << "loop has " << vertList.size() << "verts"; 
#endif
				continue;
			}
			if(facecount == 1) oface1 = oface2;
			next = vertList[1];
			last = vertList[2];
			if( edge->getVertex2() == next ) { 
				BOP_Face3 *f = new BOP_Face3(next,first,last,
					oface1->getPlane(),oface1->getOriginalFace());
				m->addFace( f );
#ifdef BOP_DEBUG
				cout << "   face is backward: " << f << endl;
#endif
				
			} else {
				BOP_Face3 *f = new BOP_Face3(last,first,next,
					oface1->getPlane(),oface1->getOriginalFace());
				m->addFace( f );
#ifdef BOP_DEBUG
				cout << "   face is forward: " << f << endl;
#endif
			}
		}
	}
}
Exemple #10
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);
	}
}
Exemple #11
0
/**
 * Replaces a vertex index.
 * @param oldIndex old vertex index
 * @param newIndex new vertex index
 */
BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) 
{
	BOP_IT_Indexs oldEdgeIndex;
	if (oldIndex==newIndex) return newIndex;
  
	// Update faces, edges and vertices  
	BOP_Vertex *oldVertex = m_vertexs[oldIndex];
	BOP_Vertex *newVertex = m_vertexs[newIndex];
	BOP_Indexs oldEdges = oldVertex->getEdges();

	// Update faces to the newIndex
	BOP_IT_Indexs oldEdgesEnd = oldEdges.end();
	for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd;
		   oldEdgeIndex++) {
		BOP_Edge *edge = m_edges[*oldEdgeIndex];
		if ((edge->getVertex1()==oldIndex && edge->getVertex2()==newIndex) ||
			(edge->getVertex2()==oldIndex && edge->getVertex1()==newIndex)) {
			// Remove old edge  ==> set edge faces to BROKEN      
			removeBrokenFaces( edge, this );
			oldVertex->removeEdge(*oldEdgeIndex);
			newVertex->removeEdge(*oldEdgeIndex);
		}
		else {
			BOP_Indexs faces = edge->getFaces();
			const BOP_IT_Indexs facesEnd = faces.end();
			for(BOP_IT_Indexs face=faces.begin();face!=facesEnd;face++) {
				if (m_faces[*face]->getTAG()!=BROKEN)
					m_faces[*face]->replaceVertexIndex(oldIndex,newIndex);
			}
		}
	} 

	oldEdgesEnd = oldEdges.end();
	for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd;
		   oldEdgeIndex++) {
		BOP_Edge * edge = m_edges[*oldEdgeIndex];
		BOP_Edge * edge2;
		BOP_Index v1 = edge->getVertex1();
    
		v1 = (v1==oldIndex?edge->getVertex2():v1);      
		if ((edge2 = getEdge(newIndex,v1)) == NULL) {
			edge->replaceVertexIndex(oldIndex,newIndex);
			if ( edge->getVertex1() == edge->getVertex2() ) {
				removeBrokenFaces( edge, this );
				oldVertex->removeEdge(*oldEdgeIndex);
			}
#ifdef HASH
			rehashVertex(oldIndex,newIndex,v1);
#endif
			newVertex->addEdge(*oldEdgeIndex);
		}
		else {
			BOP_Indexs faces = edge->getFaces();
			const BOP_IT_Indexs facesEnd = faces.end();
			for(BOP_IT_Indexs f=faces.begin();f!=facesEnd;f++) {
				if (m_faces[*f]->getTAG()!=BROKEN)
				edge2->addFace(*f);
			}
			BOP_Vertex *oppositeVertex = m_vertexs[v1];
			oppositeVertex->removeEdge(*oldEdgeIndex);
			edge->replaceVertexIndex(oldIndex,newIndex);
			if ( edge->getVertex1() == edge->getVertex2() ) {
				removeBrokenFaces( edge, this );
				oldVertex->removeEdge(*oldEdgeIndex);
				newVertex->removeEdge(*oldEdgeIndex);
			}
#ifdef HASH
			rehashVertex(oldIndex,newIndex,v1);
#endif
		}
	}
	oldVertex->setTAG(BROKEN);

	return newIndex;
}