예제 #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;
}
예제 #2
0
MeshCoordinates thin_plate_energy_hole_inpainting(CMesh& mesh, const ZGeom::MeshRegion& hole_region, int nIter, double eps)
{
    const vector<int> anchor_verts = ZGeom::vertSurroundingVerts(mesh, hole_region.vert_inside, 2);
    vector<int> submesh_verts;
    int inside_vert_count = (int)hole_region.vert_inside.size();
    int anchor_vert_count = (int)anchor_verts.size();

    vector<int> newVert2oldVert(inside_vert_count);
    for (int i = 0; i < inside_vert_count; ++i) {
        int vi = hole_region.vert_inside[i];
        submesh_verts.push_back(vi);
        newVert2oldVert[i] = vi;
    }
    for (int vi : anchor_verts) submesh_verts.push_back(vi);

    CMesh submesh;
    mesh.getSubMesh(submesh_verts, "hole_mesh", submesh);

    MeshCoordinates faired_sub_coord = thin_plate_energy_fairing(submesh, inside_vert_count);

    MeshCoordinates result(mesh.getVertCoordinates());
    for (int sub_vIdx = 0; sub_vIdx < inside_vert_count; ++sub_vIdx) {
        result.setVertCoord(newVert2oldVert[sub_vIdx], faired_sub_coord[sub_vIdx]);
    }
    return result;
}
예제 #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);
}
예제 #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;
}
예제 #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;
}
예제 #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;
}
예제 #7
0
MeshCoordinates l1_ls_hole_inpainting(CMesh& mesh, const std::vector<ZGeom::MeshRegion>& hole_regions, ParaL1LsInpainting& para)
{
    MeshCoordinates result(mesh.getVertCoordinates());

    if (para.fitting_ring <= 0) 
    {
        vector<int> hole_verts = getMeshRegionsInsideVerts(hole_regions);
        MeshCoordinates faired_coord = l1_ls_inpainting(mesh, hole_verts, para);
        for (int vi : hole_verts)
            result.setVertCoord(vi, faired_coord[vi]);
        return result;
    }

    for (const ZGeom::MeshRegion& mr : hole_regions) 
    {
        const vector<int> anchor_verts = ZGeom::vertSurroundingVerts(mesh, mr.vert_inside, para.fitting_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);
        vector<int> missing_verts;
        int newVertIdx(0);
        for (int vi : mr.vert_inside) {
            submesh_verts.push_back(vi);
            missing_verts.push_back(newVertIdx);
            newVert2oldVert[newVertIdx++] = vi;
        }
        for (int vi : anchor_verts) submesh_verts.push_back(vi);
        CMesh submesh;
        mesh.getSubMesh(submesh_verts, "hole_mesh", submesh);

        MeshCoordinates faired_sub_coord = l1_ls_inpainting(submesh, missing_verts, para);

        for (int sub_vIdx = 0; sub_vIdx < inside_vert_count; ++sub_vIdx) {
            result.setVertCoord(newVert2oldVert[sub_vIdx], faired_sub_coord[sub_vIdx]);
        }
    }
    
    return result;
}
예제 #8
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;
}
예제 #9
0
MeshCoordinates meshHoleDLRS(CMesh& mesh, const std::vector<MeshRegion>& hole_regions, double lambda, int anchor_ring)
{
    MeshCoordinates result(mesh.getVertCoordinates());
    if (anchor_ring <= 0)
    {
        vector<int> hole_verts = getMeshRegionsInsideVerts(hole_regions);
        MeshCoordinates faired_coord = meshDLRS(mesh, lambda);
        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();
        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);

        MeshCoordinates faired_sub_coord = meshDLRS(submesh, lambda);

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

    return result;
}