Beispiel #1
0
void BOP_Merge2::mergeFaces(BOP_Mesh *m, BOP_Index v)
{
	m_mesh = m;

#ifdef BOP_DEBUG
	cout << "##############################" << endl;
#endif
	cleanup( );

	m_firstVertex = v;
	bool cont = false;

	// Merge faces
	mergeFaces();	

	do {
		// Add quads ...
		cont = createQuads();
		// ... and merge new faces
		if( cont ) cont = mergeFaces();

#ifdef BOP_DEBUG
		cout << "called mergeFaces " << cont << endl;
#endif
		// ... until the merge is not succesful
	} while(cont);
}
Beispiel #2
0
/**
 * Returns a new quad from the merge of two faces (one quad and one triangle) 
 * that share the vertex v and come from the same original face.
 * @param faceI mesh face (quad or triangle) with index v
 * @param faceJ mesh face (quad or triangle) with index v
 * @param v vertex index shared by both faces
 * @return if the merge is possible, a new quad without v
 */
BOP_Face* BOP_Merge::mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v)
{
	if (faceI->size() == 3) {
		if (faceJ->size() == 4)
			return mergeFaces((BOP_Face4*)faceJ,(BOP_Face3*)faceI,v);
	}
	else if (faceI->size() == 4) {
		if (faceJ->size() == 3)
			return mergeFaces((BOP_Face4*)faceI,(BOP_Face3*)faceJ,v);
	}
	return NULL;
}
Beispiel #3
0
/**
 * Simplifies a mesh, merging its faces.
 * @param m mesh
 * @param v index of the first mergeable vertex (can be removed by merge) 
 */
void BOP_Merge::mergeFaces(BOP_Mesh *m, BOP_Index v)
{
	m_mesh = m;
	m_firstVertex = v;

	bool cont = false;

	// Merge faces
	mergeFaces();

	do {
		// Add quads ...
		cont = createQuads();
		if (cont) {
			// ... and merge new faces
			cont = mergeFaces();
		}
		// ... until the merge is not succesful
	} while(cont);
}
Beispiel #4
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);
}
Beispiel #5
0
/**
 * Simplifies a mesh, merging the faces with vertex v that come from the same face.
 * @param oldFaces sequence of old mesh faces obtained from the merge
 * @param newFaces sequence of new mesh 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).
 * @return true if the vertex v was 'merged' (obviously it could require to test
 * some new vertices that will be added to the vertices list)
 */
bool BOP_Merge::mergeFaces(BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v) {

	bool merged = true;

	// Get faces with v that come from the same original face, (without the already 'merged' from vertices)
	BOP_LFaces facesByOriginalFace;
	getFaces(facesByOriginalFace,vertices,v);
  
	if (facesByOriginalFace.size()==0) {
		// All the faces with this vertex were already merged!!!
		return true;
	}
	else {
		// Merge faces
	  const BOP_IT_LFaces facesEnd = facesByOriginalFace.end();
		for(BOP_IT_LFaces facesByOriginalFaceX = facesByOriginalFace.begin();
			(facesByOriginalFaceX != facesEnd)&&merged;
			facesByOriginalFaceX++) {
				merged = mergeFaces((*facesByOriginalFaceX),oldFaces,newFaces,vertices,v);
		}
	}
	return merged;
}
Beispiel #6
0
        //-------------------------------------------------------------------------------------------------------
        bool Exporter::processMesh(RawMesh& rawMesh, const char* fileName)
        {
                rawMesh_ = &rawMesh;
                meshData_.reset(new(std::nothrow) Mesh::Data);
                if(!meshData_)
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                numVertices_ = rawMesh_->positions_.getSize();
                meshData_->boundingBox = rawMesh_->boundingBox_;

                boneIndices_.destroy();
                boneWeights_.destroy();

                vertices_.clear();
                newToOldVertexMapping_.clear();

                std::cout << "processing raw mesh..." << std::endl;
                faces_ = rawMesh_->faces_;
                if(faces_.getSize() != rawMesh_->faces_.getSize())
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                std::cout << "merging faces..." << std::endl;

                numVertices_ = mergeFaces(faces_, rawMesh_->normalFaces_, faces_, numVertices_);
                if(numVertices_ == 0)
                {
                        std::cout << "error: could not merge faces" << std::endl;
                        return false;
                }

                numVertices_ = mergeFaces(faces_, rawMesh_->textureFaces_, faces_, numVertices_);
                if(numVertices_ == 0)
                {
                        std::cout << "error: could not merge faces" << std::endl;
                        return false;
                }

                if(!rawMesh_->bones_.isEmpty())
                {
                        std::cout << "reading bone indices and weights..." << std::endl;

                        if(!boneIndices_.create(numVertices_) || !boneWeights_.create(numVertices_))
                        {
                                std::cout << "error: not enough memory" << std::endl;
                                return false;
                        }

                        uint32_t numFaces = faces_.getSize();
                        for(uint32_t i = 0; i < numFaces; ++i)
                        {
                                const RawMesh::Face& face = rawMesh_->faces_[i];

                                for(uint8_t j = 0; j < 3; ++j)
                                {
                                        uint32_t vertexIndex = faces_[i].indices[j];
                                        boneIndices_[vertexIndex] = rawMesh_->boneIndices_[face.indices[j]];
                                        boneWeights_[vertexIndex] = rawMesh_->boneWeights_[face.indices[j]];
                                }
                        }
                }

                std::cout << "computing tangent space..." << std::endl;
                if(!computeTangentSpace())
                {
                        std::cout << "error: broken mesh" << std::endl;
                        return false;
                }

                std::cout << "preparing vertex streams..." << std::endl;
                if(!prepareVertexStreams())
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                std::cout << "preparing faces..." << std::endl;
                if(!prepareFaces())
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                std::cout << "preparing subsets..." << std::endl;
                if(!prepareSubsets())
                {
                        std::cout << "error: not enough memory" << std::endl;
                        return false;
                }

                if(!rawMesh_->bones_.isEmpty())
                {
                        std::cout << "preparing skeleton...";
                        auto& skeleton = meshData_->skeleton;

                        skeleton.reset(new(std::nothrow) Skeleton);
                        if(!skeleton)
                        {
                                std::cout << "error: not enough memory" << std::endl;
                                return false;
                        }

                        skeleton->getBones() = rawMesh_->bones_;
                        if(skeleton->getBones().getSize() != rawMesh_->bones_.getSize())
                        {
                                std::cout << "error: not enough memory" << std::endl;
                                return false;
                        }
                }

                std::cout << "writing mesh to the file..." << std::endl;

                std::ofstream stream(fileName, std::ios_base::binary);
                MeshManager meshManager;

                if(!meshManager.writeMesh(stream, *meshData_))
                {
                        std::cout << "error: could not write mesh to the file" << std::endl;
                        return false;
                }

                std::cout << "mesh has " << numVertices_;
                std::cout << " vertices and " << faces_.getSize() << " faces" << std::endl;

                return true;
        }
Beispiel #7
0
vector<Face> FaceDetect::detectFaces(const IplImage* inputImage, const CvSize& size)
{
    if (inputImage->imageData == 0)
    {
        cout<<"Bad image given, not detecting faces."<<endl;
        return vector<Face>();
    }

    CvSize originalSize = size;
    if (!size.width && !size.height)
        originalSize = cvSize(inputImage->width, inputImage->height);

    clock_t init, detect, duration;

    if (DEBUG)
        init = clock();

    IplImage* scaled = 0;
    d->scaleFactor   = 1;

    int inputArea  = inputImage->width*inputImage->height;

    if (DEBUG)
        printf("Input area : %d\n", inputArea);

    if (inputArea > getRecommendedImageSizeForDetection() * getRecommendedImageSizeForDetection())
    {
        if (DEBUG)
            cout << "downscaling input image" << endl;
        scaled = libface::LibFaceUtils::resizeToArea(inputImage, 786432, d->scaleFactor);
    }

    const IplImage* image = scaled ? scaled : inputImage;

    updateParameters(cvSize(image->width, image->height), originalSize);

    // Now loop through each cascade, apply it, and get back a vector of detected faces
    vector<vector<Face> > primaryResults(d->cascadeSet->getSize());
    vector<Face> finalResult;

    d->storage = cvCreateMemStorage(0);

    for (int i = 0; i < d->cascadeSet->getSize(); ++i)
    {
        if (d->cascadeProperties[i].primaryCascade)
        {
            if (DEBUG)
                detect = clock();

            primaryResults[i] = cascadeResult(image, d->cascadeSet->getCascade(i).haarcasc, d->primaryParams);

            if (DEBUG)
            {
                duration = clock() - detect;
                cout <<"Primary detection with " <<  d->cascadeSet->getCascade(i).name << ": "
                     << ((double)duration / ((double)CLOCKS_PER_SEC)) << " sec" << endl;
            }
        }
    }

    // After intelligently "merging" overlaps of face regions by different cascades,
    // this creates a list of faces.
    finalResult = mergeFaces(image, primaryResults, d->maxDistance, d->minDuplicates);
    //LibFaceUtils::showImage(image, finalResult);

    // Verify faces using other cascades
    for (vector<Face>::iterator it = finalResult.begin(); it != finalResult.end(); )
    {
        if (!verifyFace(image, *it))
            it = finalResult.erase(it);
        else
            ++it;
    }

    cvReleaseMemStorage(&d->storage);
    if (scaled)
        cvReleaseImage(&scaled);

    // Insert extracted images into face
    for (vector<Face>::iterator it = finalResult.begin(); it != finalResult.end(); ++it)
    {
        // rescale to full image
        if (d->scaleFactor != 1)
        {
            it->setX1(lround(it->getX1() * d->scaleFactor));
            it->setY1(lround(it->getY1() * d->scaleFactor));
            it->setX2(lround(it->getX2() * d->scaleFactor));
            it->setY2(lround(it->getY2() * d->scaleFactor));
        }

        //Extract face-image from whole-image.
        CvRect rect       = cvRect(it->getX1(), it->getY1(), it->getWidth(), it->getHeight());
        IplImage* faceImg = LibFaceUtils::copyRect(inputImage, rect);
        it->setFace(faceImg);
    }

    if (DEBUG)
    {
        duration = clock() - init;
        cout << "Total time : " << ((double)duration / ((double)CLOCKS_PER_SEC))<< " sec" << endl;
    }

    return finalResult;
}
Beispiel #8
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;
}
Beispiel #9
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);
}