Refactoring.Added function for exporting to svg

This commit is contained in:
iasonmanolas 2022-07-12 13:07:21 +03:00
parent fd5e9755ab
commit db35df38fc
2 changed files with 110 additions and 21 deletions

View File

@ -329,22 +329,23 @@ void VCGEdgeMesh::updateEigenEdgeAndVertices() {
#endif
}
bool VCGEdgeMesh::copy(VCGEdgeMesh &mesh) {
vcg::tri::Append<VCGEdgeMesh, VCGEdgeMesh>::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<VCGEdgeMesh>::VertexEdge(*this);
bool VCGEdgeMesh::copy(const VCGEdgeMesh &mesh)
{
vcg::tri::Append<VCGEdgeMesh, VCGEdgeMesh>::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<VCGEdgeMesh>::VertexEdge(*this);
return true;
return true;
}
void VCGEdgeMesh::set(const std::vector<double> &vertexPositions, const std::vector<int> &edges)
@ -389,6 +390,90 @@ void VCGEdgeMesh::removeDuplicateVertices(
vcg::tri::UpdateTopology<VCGEdgeMesh>::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<VCGEdgeMesh>::Box(edgeMeshCopy);
const double maxDim = edgeMeshCopy.bbox.Dim()[edgeMeshCopy.bbox.MaxDim()];
vcg::tri::UpdatePosition<VCGEdgeMesh>::Translate(
edgeMeshCopy,
VCGEdgeMesh::CoordType(maxDim / 2.0 - edgeMeshCopy.bbox.Center().X(),
maxDim / 2.0 - edgeMeshCopy.bbox.Center().Y(),
0));
vcg::tri::UpdatePosition<VCGEdgeMesh>::Scale(edgeMeshCopy, PatternSize / maxDim);
// debug
// vcg::tri::UpdateBounding<EdgeMesh>::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 << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl
<< "<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' "
"'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>"
<< std::endl;
// size & background
ss << "<svg height=\"" << ImgSize << "\" width=\"" << ImgSize
<< "\" xmlns=\"http://www.w3.org/2000/svg\" "
"xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
<< std::endl;
ss << "<rect width=\"100%\" height=\"100%\" fill=\"white\"/>" << std::endl;
for (const auto &e : edgeMeshCopy.edge) {
const auto &p0 = e.cP(0);
const auto &p1 = e.cP(1);
ss << "<line "
<< "x1=\"" << ImgPadding + p0.X() << "\" y1=\"" << -ImgPadding - p0.Y() + ImgSize
<< "\" "
<< "x2=\"" << ImgPadding + p1.X() << "\" y2=\"" << -ImgPadding - p1.Y() + ImgSize
<< "\" "
<< "style=\"stroke:rgb(67,160,232);stroke-width:" << StrokeWidth
<< "\" stroke-linecap=\"round\"/>" << std::endl;
}
ss << "</svg>" << 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<VCGEdgeMesh>::PointerUpdater<VertexPointer> 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],

View File

@ -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<double> &vertexPositions, const std::vector<int> &edges);
@ -88,7 +88,7 @@ public:
#ifdef POLYSCOPE_DEFINED
polyscope::CurveNetwork *registerForDrawing(
const std::optional<std::array<double, 3>> &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<size_t> &vertsToMark);
private: