Esempio n. 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);
				}
			}
		}
	}
	}
}
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
/** 
 * 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. 4
0
/**
 * Merge a set of faces removing the vertex index v.
 * @param faces set of faces
 * @param oldFaces set of old faces obtained from the merge
 * @param newFaces set of new faces obtained from the merge
 * @param vertices sequence of indexs (v1 ... vi = v ... vn) where :
 *   v is the current vertex to test,
 *   vj (j < i) are tested vertices, 
 *   vk (k >= i) are vertices required to test to merge vj
 * (so if a vertex vk can't be merged, the merge is not possible).
 * @param v vertex index
 * @return true if the merge is succesful, false otherwise
 */
bool BOP_Merge::mergeFaces(BOP_Faces &faces, BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v)
{

	bool merged = false;

	if (faces.size() == 2) {
		// Merge a pair of faces into a new face without v
		BOP_Face *faceI = faces[0];
		BOP_Face *faceJ = faces[1];
		BOP_Face *faceK = mergeFaces(faceI,faceJ,vertices,v);
		if (faceK != NULL) {
			newFaces.push_back(faceK);
			oldFaces.push_back(faceI);
			oldFaces.push_back(faceJ);
			merged = true;
		} 
		else merged = false;
	}
	else if (faces.size() == 4) {
		// Merge two pair of faces into a new pair without v
		// First we try to perform a simplify merge to avoid more pending vertices
		// (for example, if we have two triangles and two quads it will be better
		// to do 3+4 and 3+4 than 3+3 and 4+4)
		BOP_Face *oldFace1 = faces[0];
		BOP_Face *oldFace2, *newFace1;
		unsigned int indexJ = 1;
		while (indexJ < faces.size() && !merged) {
			oldFace2 = faces[indexJ];
			newFace1 = mergeFaces(oldFace1,oldFace2,v);
			if (newFace1 != NULL) merged = true;
			else indexJ++;
		}
		if (merged) {
			// Merge the other pair of faces 
			unsigned int indexK, indexL;
			if (indexJ == 1) {indexK = 2;indexL = 3;}
			else if (indexJ == 2) {indexK = 1;indexL = 3;}
			else {indexK = 1;indexL = 2;}
			BOP_Face *oldFace3 = faces[indexK];
			BOP_Face *oldFace4 = faces[indexL];
			unsigned int oldSize = vertices.size();
			BOP_Face *newFace2 = mergeFaces(oldFace3,oldFace4,vertices,v);
			if (newFace2 != NULL) {
				newFaces.push_back(newFace1);
				newFaces.push_back(newFace2);
				oldFaces.push_back(oldFace1);
				oldFaces.push_back(oldFace2);
				oldFaces.push_back(oldFace3);
				oldFaces.push_back(oldFace4);
				merged = true;
			}
			else {
				// Undo all changes
				delete newFace1;
				merged = false;
				unsigned int count = vertices.size() - oldSize;
				if (count != 0)
					vertices.erase(vertices.end() - count, vertices.end());
			}
		} 		
		if (!merged) {
			// Try a complete merge
			merged = true;
			while (faces.size()>0 && merged) {
				indexJ = 1;
				BOP_Face *faceI = faces[0];
				merged = false;
				while (indexJ < faces.size()) {
					BOP_Face *faceJ = faces[indexJ];
					BOP_Face *faceK = mergeFaces(faceI,faceJ,vertices,v);
					if (faceK != NULL) {
						// faceK = faceI + faceJ and it does not include v!
						faces.erase(faces.begin()+indexJ,faces.begin()+(indexJ+1));
						faces.erase(faces.begin(),faces.begin()+1);
						newFaces.push_back(faceK);
						oldFaces.push_back(faceI);
						oldFaces.push_back(faceJ);
						merged = true;
						break;
					}
					else indexJ++;
				}
			}
		}
	}
	else merged = false; // there are N=1 or N=3 or N>4 faces!

	// Return merge result
	return merged;
}