Ejemplo n.º 1
0
MeshCoordinates l1_ls_inpainting(CMesh& mesh, const std::vector<int>& missing_idx, ParaL1LsInpainting& para)
{
    const int totalVertCount = mesh.vertCount();
    MeshLaplacian graphLaplacian;
    graphLaplacian.constructUmbrella(&mesh);
    int eigenCount = para.eigen_count;    // -1 means full decomposition
    if (eigenCount == -1) eigenCount = totalVertCount - 1;

    ZGeom::EigenSystem es;
    graphLaplacian.meshEigenDecompose(eigenCount, &g_engineWrapper, es);

    ZGeom::Dictionary dictMHB;
    computeDictionary(DT_Fourier, es, dictMHB);

    ZGeom::DenseMatrixd matCoordOld = mesh.getVertCoordinates().toDenseMatrix();
    ZGeom::DenseMatrixd matDict = dictMHB.toDenseMatrix();

    CStopWatch timer;
    timer.startTimer();
    ZGeom::DenseMatrixd matCoordInpainted = matlab_inpaintL1LS(matCoordOld, matDict, missing_idx, para.lambda, para.tol);
    timer.stopTimer("-- L1_Ls inpainting time: ");

    MeshCoordinates coordInpainted;
    coordInpainted.fromDenseMatrix(matCoordInpainted);
    return coordInpainted;
}
Ejemplo n.º 2
0
void compressMesh(const std::vector<std::string>& mesh_filenames) {
    string mesh_file = mesh_filenames.front();
    CMesh mesh;
    mesh.load(mesh_file);
    string mesh_name = mesh.getMeshName();    
    ofstream ofs(mesh_name + ".compress.log");

    // what to do:
    // 1. partition mesh with each mesh of size 300, 500, 1000, 1500, 2000
    // 2. For each submesh, do eigendecomposition
    // 3. Compute SGW dictionary
    // 4. S-OMP approximation
    // 5. Output total approximation error

    // 
    // what to output:
    // 1. eigendecomposition time
    // 2. S-OMP time
    // 3. Approximation error

    vector<int> max_sizes{ 300, 600, 1000, 1500, 2000 };
    for (int max_size : max_sizes) {
        int nPart = std::round(mesh.vertCount() / max_size);
        vector<int> part_idx = MetisMeshPartition(&mesh, nPart);
        // TODO

    }

}
Ejemplo n.º 3
0
//////////////////////////////////////////////////////////////////////////
// format: zmesh_operator [mesh_file_name] 
// currently, just output three types of Laplacian operator in .mat Matlab file
int main(int argc, char *argv[])
{
    using namespace std;
    using namespace ZGeom;
    using namespace std::tr2::sys;

    if (argc < 2) {
        std::cerr << "Lack argument!" << std::endl;
        std::exit(-1);
    }

    string meshfile = argv[1];
    if (!fileExist(meshfile)) {
        std::cerr << "Mesh file not existent!" << std::endl;
        std::exit(-1);
    }

    CMesh mesh;    
    mesh.load(meshfile);
    mesh.scaleToUnitBox();
    int N = mesh.vertCount();
    mesh.scaleAndTranslate(-mesh.calMeshCenter(), 1.0);
    Laplacian umbrella, goemUmbrella, cotformula;
    umbrella.constructUmbrella(&mesh);
    cotformula.constructCotFormula(&mesh);

    auto coord = mesh.getVertCoordinates();
    DenseMatrixd matCoord = coord.toDenseMatrix();

    ZGeom::calMeshAttrVertNormals(mesh, ZGeom::VN_AREA_WEIGHT);
    auto normals = ZGeom::getMeshVertNormals(mesh);
    DenseMatrixd matNormal(N, 3);
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < 3; ++j)
            matNormal(i, j) = normals[i][j];
    }

    calMeshAttrMixedVertAreas(mesh);
    ZGeom::computeMeshCurvatures(mesh, true);
    Laplacian anisoLap;
    anisoLap.constructAniso(&mesh);

    MatlabEngineWrapper eng;
    eng.open();
    auto pwd = initial_path<path>();
    eng.eval("cd " + pwd.string()); 

    eng.addDenseMat(matCoord, "mat_coord");
    eng.addDenseMat(matNormal, "mat_normal");
    eng.addSparseMat(umbrella.getLS(), "mat_umbrella");
    eng.addSparseMat(cotformula.getW(), "mat_weight");
    eng.addSparseMat(cotformula.getLS(), "mat_cot");
    eng.addSparseMat(anisoLap.getLS(), "mat_aniso");

    eng.eval("save meshlaplace.mat mat_coord mat_normal mat_umbrella mat_weight mat_cot mat_aniso");
    eng.close();
    cout << "Mesh and Laplace .mat file saved!" << endl;
    exit(0);
}
Ejemplo n.º 4
0
MeshCoordinates meshDLRS(CMesh& mesh, double lambda)
{
    int totalVertCount = mesh.vertCount();
    MeshCoordinates coordCurrent = mesh.getVertCoordinates();

    MeshLaplacian graphLaplacian;
    graphLaplacian.constructUmbrella(&mesh);
    vector<VecNd> vDenoisedCoord = DLRS(graphLaplacian.getLS(), lambda, coordCurrent.to3Vec());
    MeshCoordinates coordDenoised(totalVertCount, vDenoisedCoord);

    return coordDenoised;
}
Ejemplo n.º 5
0
MeshCoordinates thin_plate_energy_fairing(CMesh& mesh, int free_vert_count)
{
    const int totalVertCount = mesh.vertCount();

    const MeshCoordinates coordOld = mesh.getVertCoordinates();
    vector<VecNd> vOriginalCoords = coordOld.to3Vec();
    MeshLaplacian mesh_laplacian;
    mesh_laplacian.constructCotFormula(&mesh);
    SparseMatrixd matL = mesh_laplacian.getSparseMatrix();
    SparseMatrixd matL2;
    mulMatMat(matL, matL, matL2);

    vector<int> rowIdxL2, colIdxL2;
    vector<double> valsL2;
    matL2.convertToCOO(rowIdxL2, colIdxL2, valsL2, ZGeom::MAT_FULL);

    vector<int> rowIdxA, colIdxA; vector<double> valsA;
    for (int i = 0; i < (int)rowIdxL2.size(); ++i) {
        if (rowIdxL2[i] < free_vert_count && colIdxL2[i] < free_vert_count) {
            rowIdxA.push_back(rowIdxL2[i]);
            colIdxA.push_back(colIdxL2[i]);
            valsA.push_back(valsL2[i]);
        }
    }
    SparseMatrixd matA;
    matA.convertFromCOO(free_vert_count, free_vert_count, rowIdxA, colIdxA, valsA);

    DenseMatrixd matB(free_vert_count, 3);
    for (int m = 0; m < 3; ++m) {
        for (int i = 0; i < free_vert_count; ++i) {
            for (int j = free_vert_count; j < totalVertCount; ++j)
                matB(i, m) -= matL2(i, j) * vOriginalCoords[m][j];
        }
    }

    g_engineWrapper.addSparseMat(matA, "matA");
    g_engineWrapper.addDenseMat(matB, "matB");
    g_engineWrapper.eval("matX=matA\\matB;");
    DenseMatrixd matX = g_engineWrapper.getDenseMat("matX");

    vector<VecNd> vNewCoord = vOriginalCoords;
    for (int m = 0; m < 3; ++m)
        for (int i = 0; i < free_vert_count; ++i)
            vNewCoord[m][i] = matX(i, m);
    
    MeshCoordinates result(totalVertCount, vNewCoord);
    return result;
}
Ejemplo n.º 6
0
MeshCoordinates least_square_hole_inpainting(CMesh& mesh, const std::vector<ZGeom::MeshRegion>& hole_regions, int anchor_ring, double anchor_weight)
{
    ZGeom::logic_assert(anchor_weight >= 0, "Illegal parameter!");
    MeshCoordinates result(mesh.getVertCoordinates());

    if (anchor_ring <= 0)
    {
        vector<int> hole_verts = getMeshRegionsInsideVerts(hole_regions);
        set<int> set_hole_verts(hole_verts.begin(), hole_verts.end());
        set<int> anchor_verts;
        for (int vi = 0; vi < (int)mesh.vertCount(); ++vi) {
            if (!setHas(set_hole_verts, vi)) anchor_verts.insert(vi);
        }
        
        MeshCoordinates faired_coord = least_square_inpainting(mesh, vector<int>(anchor_verts.begin(),anchor_verts.end()), anchor_weight);
        for (int vi : hole_verts)
            result.setVertCoord(vi, faired_coord[vi]);
        return result;
    }

    for (const MeshRegion& mr : hole_regions) {
        const vector<int> anchor_verts = ZGeom::vertSurroundingVerts(mesh, mr.vert_inside, anchor_ring);
        vector<int> submesh_verts;
        int inside_vert_count = (int)mr.vert_inside.size();
        int anchor_vert_count = (int)anchor_verts.size();
        vector<int> newVert2oldVert(inside_vert_count);
        int newVertIdx(0);
        for (int vi : mr.vert_inside) {
            submesh_verts.push_back(vi);
            newVert2oldVert[newVertIdx++] = vi;
        }
        for (int vi : anchor_verts) submesh_verts.push_back(vi);

        CMesh submesh;
        mesh.getSubMesh(submesh_verts, "hole_mesh", submesh);
        vector<int> control_verts;
        for (int i = inside_vert_count; i < (int)submesh_verts.size(); ++i)
            control_verts.push_back(i);

        MeshCoordinates faired_sub_coord = least_square_inpainting(submesh, control_verts, anchor_weight);
        for (int sub_vIdx = 0; sub_vIdx < inside_vert_count; ++sub_vIdx) {
            result.setVertCoord(newVert2oldVert[sub_vIdx], faired_sub_coord[sub_vIdx]);
        }
    }

    return result;
}
Ejemplo n.º 7
0
MeshCoordinates least_square_inpainting(CMesh& mesh, const std::vector<int>& anchor_verts, double anchor_weight)
{
    const int totalVertCount = mesh.vertCount();
    const MeshCoordinates coordOld = mesh.getVertCoordinates();
    vector<VecNd> vOriginalCoords = coordOld.to3Vec();
    MeshLaplacian matLaplacian;
    matLaplacian.constructTutte(&mesh);

    const vector<int> &vControlVerts = anchor_verts;
    set<int> setControlVerts{ anchor_verts.begin(), anchor_verts.end() };
    int controlVertCount = (int)anchor_verts.size();
    double controlWeight = anchor_weight;
    vector<int> rowIdxA, colIdxA;
    vector<double> valsA;
    matLaplacian.getSparseMatrix().convertToCOO(rowIdxA, colIdxA, valsA, ZGeom::MAT_FULL);
    for (int i = 0; i < controlVertCount; ++i) {
        rowIdxA.push_back(totalVertCount + i + 1);
        colIdxA.push_back(vControlVerts[i] + 1);
        valsA.push_back(controlWeight);
    }
    SparseMatrixd matA(totalVertCount + controlVertCount, totalVertCount);
    matA.convertFromCOO(totalVertCount + controlVertCount, totalVertCount, rowIdxA, colIdxA, valsA);

    DenseMatrixd matB(totalVertCount + controlVertCount, 3);
    for (int i = 0; i < controlVertCount; ++i) {
        for (int j = 0; j < 3; ++j)
            matB(totalVertCount + i, j) = controlWeight * vOriginalCoords[j][vControlVerts[i]];
    }

    g_engineWrapper.addSparseMat(matA, "matA");
    g_engineWrapper.addDenseMat(matB, "matB");
    g_engineWrapper.eval("matX=matA\\matB;");
    DenseMatrixd matX = g_engineWrapper.getDenseMat("matX");

    MeshCoordinates result;
    result.fromDenseMatrix(matX);
    return result;
}
Ejemplo n.º 8
0
//////////////////////////////////////////////////////////////////////////
// usage: zmesh_partition [mesh-filename] -n/-m [partitionCount/maxPatchSize] [output-path]
//
int main(int argc, char *argv[])
{
	if (argc == 2 && argv[1] == std::string("--help")) {
		std::cout << "usage: zmesh_partition [mesh-filename] -n/-m [partitionCount/maxPatchSize] [output-path]" << '\n';
		exit(0);
	}

	if (argc < 4) {
		std::cerr << "Lack " << 4 -argc << " arguments!" << std::endl;
		exit(-1);
	}
	else if (argc > 5) {
		std::cerr << "Excessive arguments ignored!" << std::endl;
	}

	/// preparation of option and parameters
	std::string meshFilename = argv[1];
	std::string segOption = argv[2];
	std::string segPara = argv[3];
	std::string outputPath = "./";
	if (argc == 5) {
		outputPath = argv[4];
		if (outputPath.back() != '/') outputPath.push_back('/');	// add trailing slash if missing
	}

	if (!fileExist(meshFilename)) {
		std::cerr << "Mesh file not existent!" << std::endl;
		std::exit(-1);
	}
	bool segNumSpecified = false;
	if (segOption == "-n") segNumSpecified = true;
	else if (segOption == "-m") segNumSpecified = false;
	else {
		std::cerr << "Unrecognized option '" << segOption << " '" << std::endl;
		std::exit(-1);
	}
	int nPara = std::stoi(segPara);

	/// load mesh
	CMesh oriMesh;
	oriMesh.load(meshFilename);
    ZGeom::gatherMeshStatistics(oriMesh);

	std::string meshName = oriMesh.getMeshName();
	int totalVertCount = oriMesh.vertCount();
	int nPart;
	if (segNumSpecified) nPart = nPara;
	else nPart = totalVertCount / nPara + 1;
	if (nPart <= 0) {
		std::cerr << "Number of segmentations must be greater than 0" << std::endl;
		std::exit(-1);
	}

	std::vector<CMesh*> vSubMeshes;
	std::vector<std::vector<int>*> vMappedIdx;

	for (int i = 0; i < nPart; ++i) {
		vSubMeshes.push_back(new CMesh());
		vMappedIdx.push_back(new std::vector<int>());
	}
	std::vector<int> vPartIdx = MetisMeshPartition(&oriMesh, nPart);
	for (int vIdx = 0; vIdx < totalVertCount; ++vIdx) {
		vMappedIdx[vPartIdx[vIdx]]->push_back(vIdx);
	}

	double paritionTime = time_call_sec([&]() {
		oriMesh.partitionToSubMeshes(vMappedIdx, vSubMeshes);
	});
	std::cout << "Partition finished! Time consumed: " << paritionTime << "s\n";

	char numBuf[10];
	for (int i = 0; i < nPart; ++i) {
		_itoa_s(i + 1, numBuf, 10);
		std::string subMeshName = meshName + ".sub" + std::string(numBuf);
		vSubMeshes[i]->setMeshName(subMeshName);
	}

	std::cout << "- number of partitions: " << nPart << '\n';
	std::cout << "- sub-mesh sizes: ";
	for (int i = 0; i < nPart; ++i) {
		std::cout << vSubMeshes[i]->getMeshName() << ": " << vSubMeshes[i]->vertCount() << " | ";
		vSubMeshes[i]->save(outputPath + vSubMeshes[i]->getMeshName() + ".obj");
	}
	std::cout << '\n';

	for (auto p : vSubMeshes) delete p;
	for (auto p : vMappedIdx) delete p;

#ifdef _DEBUG
	std::system("PAUSE");
#endif
	exit(0);
}