예제 #1
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;
}
예제 #2
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;
}