Пример #1
0
/**
 * Simplifies a mesh, merging its faces.
 */
bool BOP_Merge::mergeFaces()
{
	BOP_Indexs mergeVertices;
	BOP_Vertexs vertices = m_mesh->getVertexs();
	BOP_IT_Vertexs v = vertices.begin();
	const BOP_IT_Vertexs verticesEnd = vertices.end();

	// Advance to first mergeable vertex
	advance(v,m_firstVertex);
	BOP_Index pos = m_firstVertex;

	// Add unbroken vertices to the list
	while(v!=verticesEnd) {
		if ((*v)->getTAG() != BROKEN) mergeVertices.push_back(pos);
		v++;pos++;
	}

	// Merge faces with that vertices
	return mergeFaces(mergeVertices);
}
Пример #2
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
			}
		}
	}
}
Пример #3
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_Merge::mergeFaces(BOP_Indexs &mergeVertices)
{
	// Check size > 0!
	if (mergeVertices.size() == 0) return false;

	// New faces added by merge
	BOP_Faces newFaces;

	// Old faces removed by merge
	BOP_Faces oldFaces;

	// Get the first vertex index and add it to 
	// the current pending vertices to merge
	BOP_Index v = mergeVertices[0];
	BOP_Indexs pendingVertices;
	pendingVertices.push_back(v);

	// Get faces with index v that come from the same original face
	BOP_LFaces facesByOriginalFace;
	getFaces(facesByOriginalFace,v);

	bool merged = true;

	// Check it has any unbroken face
	if (facesByOriginalFace.size()==0) {
		// v has not any unbroken face (so it's a new BROKEN vertex)
		(m_mesh->getVertex(v))->setTAG(BROKEN);
		merged = false;
	}

	// Merge vertex faces	
	const BOP_IT_LFaces facesEnd = facesByOriginalFace.end();
	
	for(BOP_IT_LFaces facesByOriginalFaceX = facesByOriginalFace.begin();
		(facesByOriginalFaceX != facesEnd)&&merged;
		facesByOriginalFaceX++) {		
			merged = mergeFaces((*facesByOriginalFaceX),oldFaces,newFaces,pendingVertices,v);
	}

	// Check if the are some pendingVertices to merge
	if (pendingVertices.size() > 1 && merged) {
		// There are pending vertices that we need to merge in order to merge v ...
		for(unsigned int i=1;i<pendingVertices.size() && merged;i++) 
			merged = mergeFaces(oldFaces,newFaces,pendingVertices,pendingVertices[i]);
	}

	// If merge was succesful ...
	if (merged) {
		// Set old faces to BROKEN...
	  const BOP_IT_Faces oldFacesEnd = oldFaces.end();
		for(BOP_IT_Faces face=oldFaces.begin();face!=oldFacesEnd;face++) 
			(*face)->setTAG(BROKEN);

		// ... and add merged faces (that are the new merged faces without pending vertices)
		const BOP_IT_Faces newFacesEnd = newFaces.end();
		for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) {
			m_mesh->addFace(*newFace);
			// Also, add new face vertices to the queue of vertices to merge if they weren't
			for(BOP_Index i = 0;i<(*newFace)->size();i++) {
				BOP_Index vertexIndex = (*newFace)->getVertex(i);
				if (vertexIndex >= m_firstVertex && !containsIndex(mergeVertices,vertexIndex))
					mergeVertices.push_back(vertexIndex);
			}
		}
		// Set the merged vertices to BROKEN ...
		const BOP_IT_Indexs pendingEnd = pendingVertices.end();
		for(BOP_IT_Indexs pendingVertex = pendingVertices.begin(); pendingVertex != pendingEnd;pendingVertex++) {
			BOP_Index pV = *pendingVertex;
			m_mesh->getVertex(pV)->setTAG(BROKEN);
			// ... and remove them from mergeVertices queue
			const BOP_IT_Indexs mergeEnd = mergeVertices.end();
			for(BOP_IT_Indexs mergeVertex = mergeVertices.begin(); mergeVertex != mergeEnd;mergeVertex++) {
				BOP_Index mV = *mergeVertex;
				if (mV == pV) {
					mergeVertices.erase(mergeVertex);
					break;
				}
			}
		}
	}
	else {
		// The merge  was not succesful, remove the vertex frome merge vertices queue
		mergeVertices.erase(mergeVertices.begin());
		
		// free the not used newfaces
		const BOP_IT_Faces newFacesEnd = newFaces.end();
		for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) {
			delete (*newFace);
		}
	}

	// Invoke mergeFaces and return the merge result
	return (mergeFaces(mergeVertices) || merged);
}