From db35df38fc61fa1a2b2b187ec36f3b4d88f3fc79 Mon Sep 17 00:00:00 2001 From: iasonmanolas Date: Tue, 12 Jul 2022 13:07:21 +0300 Subject: [PATCH] Refactoring.Added function for exporting to svg --- edgemesh.cpp | 124 +++++++++++++++++++++++++++++++++++++++++++-------- edgemesh.hpp | 7 ++- 2 files changed, 110 insertions(+), 21 deletions(-) diff --git a/edgemesh.cpp b/edgemesh.cpp index 87b0df2..cb5c36b 100755 --- a/edgemesh.cpp +++ b/edgemesh.cpp @@ -329,22 +329,23 @@ void VCGEdgeMesh::updateEigenEdgeAndVertices() { #endif } -bool VCGEdgeMesh::copy(VCGEdgeMesh &mesh) { - vcg::tri::Append::MeshCopy(*this, mesh); - label = mesh.getLabel(); - eigenEdges = mesh.getEigenEdges(); - // assert(eigenEdges.rows() != 0); - // if (eigenEdges.rows() == 0) { - // getEdges(eigenEdges); - // } - eigenVertices = mesh.getEigenVertices(); - // assert(eigenVertices.rows() != 0); - // if (eigenVertices.rows() == 0) { - // getVertices(eigenVertices); - // } - vcg::tri::UpdateTopology::VertexEdge(*this); +bool VCGEdgeMesh::copy(const VCGEdgeMesh &mesh) +{ + vcg::tri::Append::MeshCopyConst(*this, mesh); + label = mesh.getLabel(); + eigenEdges = mesh.getEigenEdges(); + // assert(eigenEdges.rows() != 0); + // if (eigenEdges.rows() == 0) { + // getEdges(eigenEdges); + // } + eigenVertices = mesh.getEigenVertices(); + // assert(eigenVertices.rows() != 0); + // if (eigenVertices.rows() == 0) { + // getVertices(eigenVertices); + // } + vcg::tri::UpdateTopology::VertexEdge(*this); - return true; + return true; } void VCGEdgeMesh::set(const std::vector &vertexPositions, const std::vector &edges) @@ -389,6 +390,90 @@ void VCGEdgeMesh::removeDuplicateVertices( vcg::tri::UpdateTopology::VertexEdge(*this); } +std::string VCGEdgeMesh::ToSvgText(const VCGEdgeMesh &edgeMesh) +{ + // Measures in mm (?) + constexpr double ImgPadding = 5; + //constexpr double PatternSize = 200 * 19.230769231; + //constexpr double PatternSize = 200 * 17.913461538; + constexpr double PatternSize = 1000; + constexpr double ImgSize = 2 * ImgPadding + PatternSize; + + constexpr double StrokeWidth = 5; + VCGEdgeMesh edgeMeshCopy; + edgeMeshCopy.copy(edgeMesh); + + vcg::tri::UpdateBounding::Box(edgeMeshCopy); + const double maxDim = edgeMeshCopy.bbox.Dim()[edgeMeshCopy.bbox.MaxDim()]; + vcg::tri::UpdatePosition::Translate( + edgeMeshCopy, + VCGEdgeMesh::CoordType(maxDim / 2.0 - edgeMeshCopy.bbox.Center().X(), + maxDim / 2.0 - edgeMeshCopy.bbox.Center().Y(), + 0)); + vcg::tri::UpdatePosition::Scale(edgeMeshCopy, PatternSize / maxDim); + + // debug + // vcg::tri::UpdateBounding::Box(em); + // std::cout << "pattern size " + // << em.bbox.min.X() << " " + // << em.bbox.max.X() << " " + // << em.bbox.min.Y() << " " + // << em.bbox.max.Y() << " " << std::endl; + + std::stringstream ss; + + // svg header + ss << "" << std::endl + << "" + << std::endl; + + // size & background + ss << "" + << std::endl; + ss << "" << std::endl; + + for (const auto &e : edgeMeshCopy.edge) { + const auto &p0 = e.cP(0); + const auto &p1 = e.cP(1); + ss << "" << std::endl; + } + + ss << "" << std::endl; + return ss.str(); +} + +void VCGEdgeMesh::writeToSvg(const std::filesystem::path &writeToPath) const +{ + // retrieve filepath for saving svg + const std::filesystem::path svgPath = [=]() { + if (writeToPath.empty()) { + return std::filesystem::current_path().append(getLabel()).concat(".svg"); + } + return std::filesystem::absolute(writeToPath); + }(); + // save to svg file + std::cout << "saving to " << svgPath << std::endl; + + std::ofstream ofs(svgPath); + if (!ofs.is_open()) { + std::cout << "unable to save to " << svgPath << std::endl; + assert(false); + return; + } + + ofs << ToSvgText(*this); + ofs.close(); +} + void VCGEdgeMesh::deleteDanglingVertices() { vcg::tri::Allocator::PointerUpdater pu; deleteDanglingVertices(pu); @@ -440,9 +525,10 @@ void VCGEdgeMesh::computeEdges(Eigen::MatrixX2i &edges) } } -void VCGEdgeMesh::printVertexCoordinates(const size_t &vi) const { - std::cout << "vi:" << vi << " " << vert[vi].cP()[0] << " " << vert[vi].cP()[1] - << " " << vert[vi].cP()[2] << std::endl; +void VCGEdgeMesh::printVertexCoordinates(const size_t &vi) const +{ + std::cout << "vi:" << vi << " " << vert[vi].cP()[0] << " " << vert[vi].cP()[1] << " " + << vert[vi].cP()[2] << std::endl; } #ifdef POLYSCOPE_DEFINED @@ -478,7 +564,7 @@ polyscope::CurveNetwork *VCGEdgeMesh::registerForDrawing( && polyscopeHandle_edgeMesh->nNodes() == getEigenVertices().rows()); polyscopeHandle_edgeMesh->setEnabled(shouldEnable); - polyscopeHandle_edgeMesh->setRadius(drawingRadius, true); + polyscopeHandle_edgeMesh->setRadius(drawingRadius, false); if (desiredColor.has_value()) { const glm::vec3 desiredColor_glm(desiredColor.value()[0], desiredColor.value()[1], diff --git a/edgemesh.hpp b/edgemesh.hpp index 7a0f333..9862526 100755 --- a/edgemesh.hpp +++ b/edgemesh.hpp @@ -55,7 +55,7 @@ public: * https://stackoverflow.com/questions/2354210/can-a-class-member-function-template-be-virtual * use type erasure (?) * */ - bool copy(VCGEdgeMesh &mesh); + bool copy(const VCGEdgeMesh &mesh); void set(const std::vector &vertexPositions, const std::vector &edges); @@ -88,7 +88,7 @@ public: #ifdef POLYSCOPE_DEFINED polyscope::CurveNetwork *registerForDrawing( const std::optional> &desiredColor = std::nullopt, - const double &desiredRadius = 0.002, + const double &desiredRadius = 0.001, const bool &shouldEnable = true); void unregister() const; void drawInitialFrames(polyscope::CurveNetwork *polyscopeHandle_initialMesh) const; @@ -110,6 +110,9 @@ public: } } + static std::string ToSvgText(const VCGEdgeMesh &edgeMesh); + void writeToSvg(const std::filesystem::path &writeToPath = std::filesystem::path()) const; + void markVertices(const std::vector &vertsToMark); private: