#include "vcgtrimesh.hpp" #include "utilities.hpp" #include "wrap/io_trimesh/import_obj.h" #include "wrap/io_trimesh/import_off.h" #include #include #include bool VCGTriMesh::load(const std::string &filename) { // unsigned int mask = 0; // mask |= nanoply::NanoPlyWrapper::IO_VERTCOORD; // mask |= nanoply::NanoPlyWrapper::IO_VERTNORMAL; // mask |= nanoply::NanoPlyWrapper::IO_VERTCOLOR; // mask |= nanoply::NanoPlyWrapper::IO_EDGEINDEX; // mask |= nanoply::NanoPlyWrapper::IO_FACEINDEX; // if (nanoply::NanoPlyWrapper::LoadModel( // std::filesystem::absolute(filename).string().c_str(), *this, mask) != 0) { if (vcg::tri::io::Importer::Open(*this, std::filesystem::absolute(filename).string().c_str()) != 0) { std::cout << "Could not load tri mesh" << std::endl; return false; } vcg::tri::UpdateTopology::FaceFace(*this); vcg::tri::UpdateTopology::VertexFace(*this); vcg::tri::UpdateNormal::PerVertexNormalized(*this); label = std::filesystem::path(filename).stem(); return true; } Eigen::MatrixX3d VCGTriMesh::getVertices() const { // vcg::tri::Allocator::CompactVertexVector(m); Eigen::MatrixX3d vertices(VN(), 3); for (size_t vi = 0; vi < VN(); vi++) { VCGTriMesh::CoordType vertexCoordinates = vert[vi].cP(); vertices.row(vi) = vertexCoordinates.ToEigenVector(); } return vertices; } Eigen::MatrixX3i VCGTriMesh::getFaces() const { // vcg::tri::Allocator::CompactFaceVector(m); Eigen::MatrixX3i faces(FN(), 3); for (int fi = 0; fi < FN(); fi++) { const VCGTriMesh::FaceType &face = this->face[fi]; const size_t v0 = vcg::tri::Index(*this, face.cV(0)); const size_t v1 = vcg::tri::Index(*this, face.cV(1)); const size_t v2 = vcg::tri::Index(*this, face.cV(2)); faces.row(fi) = Eigen::Vector3i(v0, v1, v2); } return faces; } Eigen::MatrixX2i VCGTriMesh::getEdges() const { // vcg::tri::Allocator::CompactFaceVector(m); Eigen::MatrixX2i edges(EN(), 2); for (int ei = 0; ei < EN(); ei++) { const VCGTriMesh::EdgeType &edge = this->edge[ei]; const size_t v0 = vcg::tri::Index(*this, edge.cV(0)); const size_t v1 = vcg::tri::Index(*this, edge.cV(1)); edges.row(ei) = Eigen::Vector2i(v0, v1); } return edges; } bool VCGTriMesh::save(const std::string plyFilename) { // vcg::tri::Allocator::CompactEveryVector(*this); assert(std::filesystem::path(plyFilename).extension() == ".ply"); // Load the ply file unsigned int mask = 0; mask |= nanoply::NanoPlyWrapper::IO_VERTCOORD; mask |= nanoply::NanoPlyWrapper::IO_VERTCOLOR; mask |= nanoply::NanoPlyWrapper::IO_FACEINDEX; mask |= nanoply::NanoPlyWrapper::IO_FACENORMAL; if (nanoply::NanoPlyWrapper::SaveModel(plyFilename.c_str(), *this, mask, false) != 0) { return false; } return true; } polyscope::SurfaceMesh *VCGTriMesh::registerForDrawing( const std::optional> &desiredColor, const bool &shouldEnable) const { auto vertices = getVertices(); auto faces = getFaces(); initPolyscope(); if (faces.rows() == 0) { auto edges = getEdges(); polyscope::CurveNetwork *polyscopeHandle_mesh( polyscope::registerCurveNetwork(label, vertices, edges)); return nullptr; } polyscope::SurfaceMesh *polyscopeHandle_mesh( polyscope::registerSurfaceMesh(label, vertices, faces)); polyscopeHandle_mesh->setEnabled(shouldEnable); const double drawingRadius = 0.002; polyscopeHandle_mesh->setEdgeWidth(drawingRadius); if (desiredColor.has_value()) { const glm::vec3 desiredColor_glm(desiredColor.value()[0], desiredColor.value()[1], desiredColor.value()[2]); polyscopeHandle_mesh->setSurfaceColor(desiredColor_glm); } return polyscopeHandle_mesh; } VCGTriMesh::VCGTriMesh() {} VCGTriMesh::VCGTriMesh(const std::string &filename) { const std::string extension = std::filesystem::path(filename).extension().string(); if (extension == ".ply") { load(filename); } else if (extension == ".obj") { vcg::tri::io::ImporterOBJ::Info info; vcg::tri::io::ImporterOBJ::Open(*this, filename.c_str(), info); } else if (extension == ".off") { vcg::tri::io::ImporterOFF::Open(*this, filename.c_str()); } else { std::cerr << "Uknown file extension " << extension << ". Could not open " << filename << std::endl; assert(false); } vcg::tri::UpdateTopology::AllocateEdge(*this); vcg::tri::UpdateTopology::FaceFace(*this); vcg::tri::UpdateTopology::VertexFace(*this); vcg::tri::UpdateNormal::PerVertexNormalized(*this); }