Beispiel #1
0
bool TMMesh::Save(const char *fileName)
{
    std::ofstream fout(fileName);
    std::cout << "Saving " <<  fileName << std::endl;
    if (SaveVRML2(fout))
    {
        fout.close();
        return true;
    }
    return false;
}
Beispiel #2
0
    bool Mesh::SaveVRML2(const std::string & fileName) const
    {
        std::ofstream fout(fileName.c_str());
        if (fout.is_open())
        {
            const Material material;

            if (SaveVRML2(fout, material))
            {
                fout.close();
                return true;
            }
            return false;
        }
        return false;
    }
Beispiel #3
0
bool SaveVRML2(const std::string & fileName, const std::vector< HACD::Vec3<HACD::Real> > & points, 
               const std::vector< HACD::Vec3<long> > & triangles,
               const HACD::Vec3<HACD::Real> * colors)
{
    std::cout << "Saving " <<  fileName << std::endl;
    std::ofstream fout(fileName.c_str());
    if (fout.is_open()) 
    {
        const HACD::Material material;
        
        if (SaveVRML2(fout, points, triangles, material, colors))
        {
            fout.close();
            return true;
        }
        return false;
    }
    return false;
}
Beispiel #4
0
bool TMMesh::SaveVRML2(std::ofstream &fout)
{
    return SaveVRML2(fout, Material());
}
Beispiel #5
0
int main(int argc, char * argv[])
{
    if (argc != 9)
    { 
        std::cout << "Usage: ./testHACD fileName.off minNClusters maxConcavity invertInputFaces addExtraDistPoints addFacesPoints ConnectedComponentsDist targetNTrianglesDecimatedMesh"<< std::endl;
		std::cout << "Recommended parameters: ./testHACD fileName.off 2 100 0 1 1 30 2000"<< std::endl;
        return -1;
    }
    
	const std::string fileName(argv[1]);
    size_t nClusters = atoi(argv[2]);
    double concavity = atof(argv[3]);
	bool invert = (atoi(argv[4]) == 0)?false:true;
	bool addExtraDistPoints = (atoi(argv[5]) == 0)?false:true;
    bool addFacesPoints = (atoi(argv[6]) == 0)?false:true;
    double ccConnectDist = atof(argv[7]);
	size_t targetNTrianglesDecimatedMesh = atoi(argv[8]);
    
    /*
    const std::string fileName("/Users/khaledmammou/Dev/HACD/data/Sketched-Brunnen.off");
    size_t nClusters = 1;
    double concavity = 100.0;
	bool invert = false;
	bool addExtraDistPoints = true;
    bool addNeighboursDistPoints = false;
    bool addFacesPoints = true;
    double ccConnectDist = 30.0;
	size_t targetNTrianglesDecimatedMesh = 1000;
    */
    
	std::string folder;
	int found = fileName.find_last_of(PATH_SEP);
	if (found != -1)
	{
		folder = fileName.substr(0,found);
	}
	if (folder == "")
    {
        folder = ".";
    }

	std::string file(fileName.substr(found+1));
	std::string outWRLFileName = folder + PATH_SEP + file.substr(0, file.find_last_of(".")) + ".wrl";
	std::string outOFFFileName = folder + PATH_SEP + file.substr(0, file.find_last_of(".")) + ".off";
    std::string outOFFFileNameDecimated = folder + PATH_SEP + file.substr(0, file.find_last_of(".")) + "_decimated.off";
	std::vector< HACD::Vec3<HACD::Real> > points;
	std::vector< HACD::Vec3<long> > triangles;
    LoadOFF(fileName, points, triangles, invert);
	SaveVRML2(outWRLFileName.c_str(), points, triangles);
	SaveOFF(outOFFFileName.c_str(), points, triangles);

	std::cout << "invert " << invert << std::endl;

	HACD::HeapManager * heapManager = HACD::createHeapManager(65536*(1000));

	HACD::HACD * const myHACD = HACD::CreateHACD(heapManager);
	myHACD->SetPoints(&points[0]);
	myHACD->SetNPoints(points.size());
	myHACD->SetTriangles(&triangles[0]);
	myHACD->SetNTriangles(triangles.size());
	myHACD->SetCompacityWeight(0.0001);
    myHACD->SetVolumeWeight(0.0);
    myHACD->SetConnectDist(ccConnectDist);               // if two connected components are seperated by distance < ccConnectDist
                                                        // then create a virtual edge between them so the can be merged during 
                                                        // the simplification process
	      
    myHACD->SetNClusters(nClusters);                     // minimum number of clusters
    myHACD->SetNVerticesPerCH(100);                      // max of 100 vertices per convex-hull
	myHACD->SetConcavity(concavity);                     // maximum concavity
	myHACD->SetSmallClusterThreshold(0.25);				 // threshold to detect small clusters
	myHACD->SetNTargetTrianglesDecimatedMesh(targetNTrianglesDecimatedMesh); // # triangles in the decimated mesh
	myHACD->SetCallBack(&CallBack);
    myHACD->SetAddExtraDistPoints(addExtraDistPoints);   
    myHACD->SetAddFacesPoints(addFacesPoints); 
    
    clock_t start, end;
    double elapsed;
    start = clock();
    {
	    myHACD->Compute();
    }
    end = clock();
    elapsed = static_cast<double>(end - start) / CLOCKS_PER_SEC;
    std::cout << "Time " << elapsed << " s"<< std::endl;
    nClusters = myHACD->GetNClusters();
        
    bool printfInfo = false;
	if (printfInfo)
	{
		
		std::cout << "Output" << std::endl;
		for(size_t c = 0; c < nClusters; ++c)
		{
			std::cout << std::endl << "Convex-Hull " << c << std::endl;
			size_t nPoints = myHACD->GetNPointsCH(c);
			size_t nTriangles = myHACD->GetNTrianglesCH(c);
			HACD::Vec3<HACD::Real> * pointsCH = new HACD::Vec3<HACD::Real>[nPoints];
			HACD::Vec3<long> * trianglesCH = new HACD::Vec3<long>[nTriangles];
			myHACD->GetCH(c, pointsCH, trianglesCH);
			std::cout << "Points " << nPoints << std::endl;
			for(size_t v = 0; v < nPoints; ++v)
			{
				std::cout << v << "\t" 
						  << pointsCH[v].X() << "\t" 
						  << pointsCH[v].Y() << "\t" 
						  << pointsCH[v].Z() << std::endl;
			}
			std::cout << "Triangles " << nTriangles << std::endl;
			for(size_t f = 0; f < nTriangles; ++f)
			{
				std::cout   << f << "\t" 
							<< trianglesCH[f].X() << "\t" 
							<< trianglesCH[f].Y() << "\t" 
							<< trianglesCH[f].Z() << std::endl;
			}
			delete [] pointsCH;
			delete [] trianglesCH;
		}
	}
	std::string outFileName = folder + PATH_SEP + file.substr(0, file.find_last_of(".")) + "_hacd.wrl";
	myHACD->Save(outFileName.c_str(), false);
    
    const HACD::Vec3<HACD::Real> * const decimatedPoints = myHACD->GetDecimatedPoints();
    const HACD::Vec3<long> * const decimatedTriangles    = myHACD->GetDecimatedTriangles();
    if (decimatedPoints && decimatedTriangles)
    {
        SaveOFF(outOFFFileNameDecimated, myHACD->GetNDecimatedPoints(), 
                                         myHACD->GetNDecimatedTriangles(), decimatedPoints, decimatedTriangles);
    }
    
    
    
    bool exportSepFiles = false;
    if (exportSepFiles)
    {
        char outFileName[1024];
        for(size_t c = 0; c < nClusters; c++)
        {
            sprintf(outFileName, "%s%s%s_hacd_%lu.wrl", folder.c_str(), PATH_SEP, file.substr(0, file.find_last_of(".")).c_str(), static_cast<unsigned long>(c));
            myHACD->Save(outFileName, false, c);
        }
    }
    
/*   
	// to do: fix this in the case the simplification is on
    std::string outFileNamePartition = folder + PATH_SEP + file.substr(0, file.find_last_of(".")) + "_partition.wrl";
	const long * const partition = myHACD->GetPartition();
    SavePartition(outFileNamePartition, points, triangles, partition, nClusters);
*/

    HACD::DestroyHACD(myHACD);
    HACD::releaseHeapManager(heapManager);
	return 0;
}
Beispiel #6
0
bool SavePartition(const std::string & fileName, const std::vector< HACD::Vec3<HACD::Real> > & points, 
                                                 const std::vector< HACD::Vec3<long> > & triangles,
                                                 const long * partition, const size_t nClusters)
{
    if (!partition)
    {
        return false;
    }
    
    std::cout << "Saving " <<  fileName << std::endl;
    std::ofstream fout(fileName.c_str());
    if (fout.is_open()) 
    {
        HACD::Material mat;
        std::vector< HACD::Vec3<long> > triCluster;
        std::vector< HACD::Vec3<HACD::Real> > ptsCluster;
        std::vector< long > ptsMap;
        for(size_t c = 0; c < nClusters; c++)
        {
            ptsMap.resize(points.size());
            mat.m_diffuseColor.X() = mat.m_diffuseColor.Y() = mat.m_diffuseColor.Z() = 0.0;
            while (mat.m_diffuseColor.X() == mat.m_diffuseColor.Y() ||
                   mat.m_diffuseColor.Z() == mat.m_diffuseColor.Y() ||
                   mat.m_diffuseColor.Z() == mat.m_diffuseColor.X()  )
            {
                mat.m_diffuseColor.X() = (rand()%100) / 100.0;
                mat.m_diffuseColor.Y() = (rand()%100) / 100.0;
                mat.m_diffuseColor.Z() = (rand()%100) / 100.0;
            }
            long ver[3];
            long vCount = 1;
            for(size_t t = 0; t < triangles.size(); t++)
            {
                if (partition[t] == static_cast<long>(c))
                {
                    ver[0] = triangles[t].X();
                    ver[1] = triangles[t].Y();
                    ver[2] = triangles[t].Z();
                    for(int k = 0; k < 3; k++)
                    {
                        if (ptsMap[ver[k]] == 0)
                        {
                            ptsCluster.push_back(points[ver[k]]);
                            ptsMap[ver[k]] = vCount;
                            ver[k] = vCount-1;
                            vCount++;
                        }
                        else
                        {
                            ver[k] = ptsMap[ver[k]]-1;
                        }
                    }
                    triCluster.push_back(HACD::Vec3<long>(ver[0], ver[1], ver[2]));
                }
            }
            SaveVRML2(fout, ptsCluster, triCluster, mat);
            triCluster.clear();
            ptsCluster.clear();
            ptsMap.clear();
        }

        fout.close();
        return true;
    }
    return false;    
}