Esempio n. 1
0
/**
 * Exports a BOP_Mesh to a BSP_CSGMesh.
 * @param mesh Input mesh
 * @param invert if TRUE export with inverted faces, no inverted otherwise
 * @return the corresponding new BSP_CSGMesh
 */
BSP_CSGMesh* BOP_exportMesh(BOP_Mesh*                  mesh, 
							bool                       invert)
{
	BSP_CSGMesh* outputMesh = BOP_newEmptyMesh();

	if (outputMesh == NULL) return NULL;

	// vtx index dictionary, to translate indeces from input to output.
	map<int,unsigned int> dic;
	map<int,unsigned int>::iterator itDic;

	unsigned int count = 0;

	// Add a new face for each face in the input list
	BOP_Faces faces = mesh->getFaces();
	BOP_Vertexs vertexs = mesh->getVertexs();

	for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) {
		if ((*face)->getTAG()!=BROKEN){    
			// Add output face
			outputMesh->FaceSet().push_back(BSP_MFace());
			BSP_MFace& outFace = outputMesh->FaceSet().back();

			// Copy face
			outFace.m_verts.clear();
			outFace.m_plane = (*face)->getPlane();
			outFace.m_orig_face = (*face)->getOriginalFace();

			// invert face if is required
			if (invert) (*face)->invert();
			
			// Add the face vertex if not added yet
			for (unsigned int pos=0;pos<(*face)->size();pos++) {
				BSP_VertexInd outVtxId;
				BOP_Index idVertex = (*face)->getVertex(pos);
				itDic = dic.find(idVertex);
				if (itDic == dic.end()) {
					// The vertex isn't added yet
					outVtxId = BSP_VertexInd(outputMesh->VertexSet().size());
					BSP_MVertex outVtx((mesh->getVertex(idVertex))->getPoint());
					outVtx.m_edges.clear();
					outputMesh->VertexSet().push_back(outVtx);
					dic[idVertex] = outVtxId;
					count++;
				}
				else {
					// The vertex is added
					outVtxId = BSP_VertexInd(itDic->second);
				}

				outFace.m_verts.push_back(outVtxId);
			}
		}
	}
	
	// Build the mesh edges using topological informtion
	outputMesh->BuildEdges();
	
	return outputMesh;
}
Esempio n. 2
0
/** 
 * Simplifies the mesh, merging the pairs of triangles that come frome the
 * same original face and define a quad.
 * @return true if a quad was added, false otherwise
 */
bool BOP_Merge::createQuads()
{
  
	BOP_Faces quads;
	
	// Get mesh faces
	BOP_Faces faces = m_mesh->getFaces();

	
    // Merge mesh triangles
	const BOP_IT_Faces facesIEnd = (faces.end()-1);
	const BOP_IT_Faces facesJEnd = faces.end();
	for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) {
		if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue;
		for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
			if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 ||
				(*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;

			// Test if both triangles share a vertex index
			BOP_Index v;
			bool found = false;
			for(unsigned int i=0;i<3 && !found;i++) {
				v = (*faceI)->getVertex(i);
				found = (*faceJ)->containsVertex(v);
				
			}
			if (!found) continue;

			BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ,v);
			if (faceK != NULL) {
				// Set triangles to BROKEN
				(*faceI)->setTAG(BROKEN);
				(*faceJ)->setTAG(BROKEN);
				quads.push_back(faceK);
				break;
			}
		}
	}

    // Add quads to mesh
	const BOP_IT_Faces quadsEnd = quads.end();
	for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad);
	return (quads.size() > 0);
}
Esempio n. 3
0
void BOP_Merge2::mergeVertex(BOP_Faces &faces, BOP_Index v1, BOP_Index v2)
{
	for(BOP_IT_Faces face=faces.begin();face!=faces.end();face++) {
		if( (*face)->size() == 3)
			mergeVertex((BOP_Face3 *) *face, v1, v2);
		else
			mergeVertex((BOP_Face4 *) *face, v1, v2);
		(*face)->setTAG(BROKEN);
#ifdef BOP_DEBUG
		cout << "  breaking " << (*face) << endl;
#endif
	}
}
Esempio n. 4
0
/** 
 * Simplifies the mesh, merging the pairs of triangles that come frome the
 * same original face and define a quad.
 * @return true if a quad was added, false otherwise
 */
bool BOP_Merge2::createQuads()
{
  
	BOP_Faces quads;
	
	// Get mesh faces
	BOP_Faces faces = m_mesh->getFaces();
	
    // Merge mesh triangles
	const BOP_IT_Faces facesIEnd = (faces.end()-1);
	const BOP_IT_Faces facesJEnd = faces.end();
	for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) {
#ifdef OLD_QUAD
		if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue;
		for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
			if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 ||
				(*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;


			BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
			if (faceK != NULL) {
				// Set triangles to BROKEN
				deleteFace(m_mesh, *faceI);
				deleteFace(m_mesh, *faceJ);
#ifdef BOP_DEBUG
			cout << "createQuad: del " << *faceI << endl;
			cout << "createQuad: del " << *faceJ << endl;
			cout << "createQuad: add " << faceK << endl;
#endif
				quads.push_back(faceK);
				break;
			}
		}
#else
		if ((*faceI)->getTAG() == BROKEN ) continue;
		for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
			if ((*faceJ)->getTAG() == BROKEN ||
				(*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;

			BOP_Face *faceK = NULL;
			if((*faceI)->size() == 3) {
				if((*faceJ)->size() == 3)
					faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
				else
					faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face4*)*faceJ);
			} else {
				if((*faceJ)->size() == 3)
					faceK = createQuad((BOP_Face3*)*faceJ,(BOP_Face4*)*faceI);
				else
					faceK = createQuad((BOP_Face4*)*faceI,(BOP_Face4*)*faceJ);
			}

			if (faceK != NULL) {
				// Set triangles to BROKEN
				deleteFace(m_mesh, *faceI);
				deleteFace(m_mesh, *faceJ);
#ifdef BOP_DEBUG
			cout << "createQuad: del " << *faceI << endl;
			cout << "createQuad: del " << *faceJ << endl;
			cout << "createQuad: add " << faceK << endl;
#endif
				quads.push_back(faceK);
				break;
			}
		}
#endif
	}

    // Add quads to mesh
	const BOP_IT_Faces quadsEnd = quads.end();
	for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad);
	return (quads.size() > 0);
}
Esempio n. 5
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
}
Esempio n. 6
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);
}