diff --git a/src/mesh/AbstractFace.h b/src/mesh/AbstractFace.h index df8de80..d0ecfe4 100644 --- a/src/mesh/AbstractFace.h +++ b/src/mesh/AbstractFace.h @@ -32,7 +32,7 @@ public: virtual std::vector getEdgeIds() const = 0; - //virtual std::vector getNodeLocations() const = 0; + virtual std::vector getNodeLocations() const = 0; protected: unsigned mId{0}; diff --git a/src/mesh/TriFace.cpp b/src/mesh/TriFace.cpp index a61b3d2..0935477 100644 --- a/src/mesh/TriFace.cpp +++ b/src/mesh/TriFace.cpp @@ -1,6 +1,7 @@ #include "TriFace.h" #include "Edge.h" +#include "Node.h" TriFace::TriFace(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id) : AbstractFace(id), @@ -73,3 +74,8 @@ void TriFace::associateWidthEdges() mEdge1->associateFace(mId); mEdge2->associateFace(mId); } + +std::vector TriFace::getNodeLocations() const +{ + return {mEdge0->getNode0()->getPoint(), mEdge0->getNode1()->getPoint(), mEdge1->getNode1()->getPoint()}; +} diff --git a/src/mesh/TriFace.h b/src/mesh/TriFace.h index 7878117..4121f14 100644 --- a/src/mesh/TriFace.h +++ b/src/mesh/TriFace.h @@ -26,6 +26,8 @@ public: unsigned getEdge2Id () const; std::vector getEdgeIds() const override; + std::vector getNodeLocations() const override; + private: Edge* mEdge0{nullptr}; Edge* mEdge1{nullptr}; diff --git a/src/publishing/plotting/SvgConverter.cpp b/src/publishing/plotting/SvgConverter.cpp index 6b8d565..2066f6b 100644 --- a/src/publishing/plotting/SvgConverter.cpp +++ b/src/publishing/plotting/SvgConverter.cpp @@ -8,6 +8,7 @@ #include "AbstractMesh.h" #include "TriMesh.h" +#include "AbstractFace.h" #include "SvgShapeElements.h" @@ -16,22 +17,44 @@ std::unique_ptr SvgConverter::convert(Scene* scene) auto doc = std::make_unique(); scene->update(); + for(auto item : scene->getItems()) { if (item->getType() == SceneItem::Type::MODEL) { auto mesh = dynamic_cast(item)->getMesh(); + auto transform = item->getTransform(); if (mesh->getType() == AbstractMesh::MeshType::TRI) { for(const auto& face : dynamic_cast(mesh)->getFaces()) { auto svg_tri = std::make_unique(); - // Get node locs for face - // Convert to pixel + std::vector points(3); + unsigned count = 0; - // add polygon to doc + auto face_locs = face->getNodeLocations(); + for(auto& loc : face_locs) + { + const auto x = loc.getX() * transform.getScaleX() + transform.getLocation().getX(); + const auto y = loc.getY() * transform.getScaleY() + transform.getLocation().getY(); + points[count] = {static_cast(x), static_cast(y)}; + count++; + } + svg_tri->setPoints(points); + svg_tri->setFill(item->getColor()); + doc->getRoot()->addChild(std::move(svg_tri)); + + if (scene->shouldShowMeshOutline()) + { + auto mesh_outline = std::make_unique(); + points.push_back(points[0]); + mesh_outline->setPoints(points); + mesh_outline->setStrokeColor({0, 0, 0}); + mesh_outline->setStrokeWidth(0.1); + doc->getRoot()->addChild(std::move(mesh_outline)); + } } } } diff --git a/src/visual_elements/Scene.h b/src/visual_elements/Scene.h index f5880ea..aeb5d22 100644 --- a/src/visual_elements/Scene.h +++ b/src/visual_elements/Scene.h @@ -23,9 +23,21 @@ public: bool isEmpty() const; + bool shouldShowMeshOutline() const + { + return mShowMeshOutline; + } + + void setShowMeshOutline(bool shouldShow) + { + mShowMeshOutline = shouldShow; + } + void update(FontsManager* fontsManager = nullptr); private: void updateNode(AbstractVisualNode* node, FontsManager* fontsManager); std::unique_ptr mRootNode; std::vector mSceneItems; + + bool mShowMeshOutline{false}; }; diff --git a/src/visual_elements/basic_shapes/CircleNode.cpp b/src/visual_elements/basic_shapes/CircleNode.cpp index 7ebf4fd..a6ed40d 100644 --- a/src/visual_elements/basic_shapes/CircleNode.cpp +++ b/src/visual_elements/basic_shapes/CircleNode.cpp @@ -61,6 +61,7 @@ void CircleNode::update(FontsManager* fontsManager) { mBackgroundItem = std::make_unique(std::move(mesh)); mBackgroundItem->setName(mName + "_Model"); + mBackgroundItem->updateUniformColor(mFillColor); } else { diff --git a/src/web/svg/SvgShapeElement.cpp b/src/web/svg/SvgShapeElement.cpp index 669fa01..60d9642 100644 --- a/src/web/svg/SvgShapeElement.cpp +++ b/src/web/svg/SvgShapeElement.cpp @@ -21,7 +21,7 @@ void SvgShapeElement::setFill(const Color& fill) addAttribute(std::move(attr)); } -void SvgShapeElement::setStrokeWidth(unsigned width) +void SvgShapeElement::setStrokeWidth(double width) { auto attr = std::make_unique("stroke-width"); attr->setValue(std::to_string(width)); diff --git a/src/web/svg/SvgShapeElement.h b/src/web/svg/SvgShapeElement.h index a0e34a8..872145d 100644 --- a/src/web/svg/SvgShapeElement.h +++ b/src/web/svg/SvgShapeElement.h @@ -10,7 +10,7 @@ public: void setFill(const Color& fill); - void setStrokeWidth(unsigned width); + void setStrokeWidth(double width); void setStrokeColor(const Color& stroke); diff --git a/src/web/svg/elements/SvgShapeElements.cpp b/src/web/svg/elements/SvgShapeElements.cpp index f8ce7aa..a3091cd 100644 --- a/src/web/svg/elements/SvgShapeElements.cpp +++ b/src/web/svg/elements/SvgShapeElements.cpp @@ -83,3 +83,24 @@ void SvgPolygon::setPoints(const std::vector& locs) addAttribute(std::move(points)); } +SvgPolyline::SvgPolyline() + : SvgShapeElement("polyline") +{ + auto fill = std::make_unique("fill"); + fill->setValue("none"); + addAttribute(std::move(fill)); +} + +void SvgPolyline::setPoints(const std::vector& locs) +{ + auto points = std::make_unique("points"); + + std::stringstream sstr; + for (const auto& loc : locs) + { + sstr << loc.GetX() << "," << loc.GetY() << " "; + } + points->setValue(sstr.str()); + addAttribute(std::move(points)); +} + diff --git a/src/web/svg/elements/SvgShapeElements.h b/src/web/svg/elements/SvgShapeElements.h index 765e827..b77c6fd 100644 --- a/src/web/svg/elements/SvgShapeElements.h +++ b/src/web/svg/elements/SvgShapeElements.h @@ -34,3 +34,11 @@ public: void setPoints(const std::vector& loc); }; + +class SvgPolyline : public SvgShapeElement +{ +public: + SvgPolyline(); + + void setPoints(const std::vector& loc); +}; diff --git a/test/publishing/TestSvgConverter.cpp b/test/publishing/TestSvgConverter.cpp index c90df51..a28a10b 100644 --- a/test/publishing/TestSvgConverter.cpp +++ b/test/publishing/TestSvgConverter.cpp @@ -4,6 +4,7 @@ #include "Scene.h" #include "CircleNode.h" +#include "RectangleNode.h" #include "File.h" @@ -13,12 +14,19 @@ TEST_CASE(TestSvgConverter, "[publishing]") { Scene scene; + scene.setShowMeshOutline(true); CircleNode circle({10, 10}, 20); + circle.setFillColor({255, 0, 0}); scene.addNode(&circle); + //RectangleNode rectangle({10, 10}, 20, 20); + //rectangle.setFillColor({255, 0, 0}); + //scene.addNode(&rectangle); + SvgConverter converter; auto svg_document = converter.convert(&scene); + svg_document->setViewBox(0, 0, 100, 100); SvgWriter writer; auto content = writer.toString(svg_document.get());