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 } }
////////////////////////////////////////////////////////////////////////// // 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); }
void computeMeshesFeaturePoints(const std::vector<std::string>& mesh_filenames, std::string eigen_path, std::string output_path) { ZGeom::MatlabEngineWrapper eng; eng.open(); auto pwd = initial_path<path>(); eng.eval("cd " + pwd.string()); eng.eval("mkdir " + output_path); eng.eval("cd " + output_path); cout << "# Total meshes: " << mesh_filenames.size() << "\n" << endl; CStopWatch timer; timer.startTimer(); int count = 0; for (string mesh_file : mesh_filenames) { count++; cout << count << ": " << mesh_file << endl; try { if (!fileExist(mesh_file)) { throw runtime_error("File not exist!"); } CMesh mesh; mesh.load(mesh_file); string mesh_name = mesh.getMeshName(); string eigen_file_path = eigen_path + "/" + mesh_name + ".eigen.mat"; EigenSystem es; es.loadFromMat(&eng, eigen_file_path); double t_min = 4 * std::log(10.0) / es.getAllEigVals().back(), t_max = 4 * std::log(10.0) / es.getEigVal(1); int nScales = 4; const double tMultiplier = std::pow(t_max / t_min, 1.0 / double(nScales - 1)); std::vector<double> hks_scales(nScales); for (int s = 0; s < nScales; ++s) { hks_scales[s] = t_min * std::pow(tMultiplier, s); } set<int> all_features; for (int s = 0; s < nScales; ++s) { vector<double> values = calHeatKernelSignature(es, hks_scales[s]); vector<int> features = extractMeshExtrema(mesh, values, 2); for (int fi : features) all_features.insert(fi); } string out_file_path = output_path + "/" + mesh_name + ".feature"; ofstream ofs(output_path.c_str()); } catch (runtime_error* e){ cerr << "Fail to process " + mesh_file << ": " << e->what() << endl; } } cout << "\n"; timer.stopTimer("Total time: "); }
void computeMeshesSpectrum(const std::vector<std::string>& mesh_filenames, int eigen_num, std::string output_path) { ZGeom::MatlabEngineWrapper eng; eng.open(); auto pwd = initial_path<path>(); eng.eval("cd " + pwd.string()); eng.eval("mkdir " + output_path); eng.eval("cd " + output_path); cout << "# Total meshes: " << mesh_filenames.size() << "\n" << endl; CStopWatch timer; timer.startTimer(); int count = 0; for (string mesh_file : mesh_filenames) { count++; cout << count << ": " << mesh_file << endl; try { if (!fileExist(mesh_file)) { throw runtime_error("File not exist!"); } CMesh mesh; mesh.load(mesh_file); Laplacian cot_form_lap; cot_form_lap.constructCotFormula(&mesh); EigenSystem es; cot_form_lap.decompose(eigen_num, &eng, es, true); string mesh_name = mesh.getMeshName(); string eigen_file_path = mesh_name + ".eigen.mat"; es.saveToMat(&eng, eigen_file_path); cout << eigen_file_path << " saved!" << endl; } catch (runtime_error* e){ cerr << "Fail to process " + mesh_file << ": " << e->what() << endl; } catch (exception* e) { cerr << "Unknown error in processing " + mesh_file << endl; } } cout << "\n"; timer.stopTimer("Total time: "); }
////////////////////////////////////////////////////////////////////////// // 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); }