diff --git a/src/graphics/opengl/OpenGlPainter.cpp b/src/graphics/opengl/OpenGlPainter.cpp index e06129e..773a2dc 100644 --- a/src/graphics/opengl/OpenGlPainter.cpp +++ b/src/graphics/opengl/OpenGlPainter.cpp @@ -55,16 +55,15 @@ void OpenGlPainter::paint(DrawingContext* context) glClear(GL_COLOR_BUFFER_BIT); auto scene = context->getSurface()->getScene(); - for(unsigned idx=0; idxgetNumItems(); idx++) + for (const auto item : scene->getItems()) { - auto scene_item = scene->getItem(idx); - if (scene_item->getType() == SceneItem::Type::MODEL) + if (item->getType() == SceneItem::Type::MODEL) { - mMeshPainter->paint(dynamic_cast(scene_item), context); + mMeshPainter->paint(dynamic_cast(item), context); } - else if (scene_item->getType() == SceneItem::Type::TEXT) + else if (item->getType() == SceneItem::Type::TEXT) { - mTextPainter->paint(dynamic_cast(scene_item), context); + mTextPainter->paint(dynamic_cast(item), context); } } diff --git a/src/mesh/AbstractFace.h b/src/mesh/AbstractFace.h index 511d457..df8de80 100644 --- a/src/mesh/AbstractFace.h +++ b/src/mesh/AbstractFace.h @@ -1,5 +1,7 @@ #pragma once +#include "Point.h" + #include #include #include @@ -30,6 +32,8 @@ public: virtual std::vector getEdgeIds() const = 0; + //virtual std::vector getNodeLocations() const = 0; + protected: unsigned mId{0}; std::unordered_map > mVectorAttributes; diff --git a/src/mesh/FaceMesh.cpp b/src/mesh/FaceMesh.cpp index 06c7fa0..177ba7f 100644 --- a/src/mesh/FaceMesh.cpp +++ b/src/mesh/FaceMesh.cpp @@ -21,6 +21,11 @@ void FaceMesh::populate(VecNodes& nodes, VecEdges& edges, VecFaces& faces) resetConnectivity(); } +const VecFaces& FaceMesh::getFaces() const +{ + return mFaces; +} + std::vector FaceMesh::getFaceNodeIds() const { if (mFaces.empty()) diff --git a/src/mesh/FaceMesh.h b/src/mesh/FaceMesh.h index b0b61be..2949243 100644 --- a/src/mesh/FaceMesh.h +++ b/src/mesh/FaceMesh.h @@ -35,6 +35,8 @@ public: void merge(std::unique_ptr mesh); + const VecFaces& getFaces() const; + protected: void resetConnectivity(); diff --git a/src/publishing/CMakeLists.txt b/src/publishing/CMakeLists.txt index d6fee0e..cc59831 100644 --- a/src/publishing/CMakeLists.txt +++ b/src/publishing/CMakeLists.txt @@ -25,15 +25,16 @@ list(APPEND publishing_LIB_INCLUDES pdf/PdfXRefTable.cpp pdf/PdfWriter.cpp plotting/GraphPlotter.h - plotting/SvgConverter.h + plotting/SvgConverter.cpp DocumentConverter.cpp ) add_library(publishing SHARED ${publishing_LIB_INCLUDES} ${publishing_INCLUDES} ${publishing_HEADERS}) target_include_directories(publishing PUBLIC - "${CMAKE_CURRENT_SOURCE_DIR}" - "${CMAKE_CURRENT_SOURCE_DIR}/pdf" + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/pdf + ${CMAKE_CURRENT_SOURCE_DIR}/plotting ) set_target_properties( publishing PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) target_link_libraries( publishing PUBLIC core web graphics visual_elements) diff --git a/src/publishing/plotting/SvgConverter.cpp b/src/publishing/plotting/SvgConverter.cpp index e69de29..6b8d565 100644 --- a/src/publishing/plotting/SvgConverter.cpp +++ b/src/publishing/plotting/SvgConverter.cpp @@ -0,0 +1,42 @@ +#include "SvgConverter.h" + +#include "SvgDocument.h" +#include "Scene.h" + +#include "SceneItem.h" +#include "SceneModel.h" + +#include "AbstractMesh.h" +#include "TriMesh.h" + +#include "SvgShapeElements.h" + +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(); + + 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 + + // add polygon to doc + } + } + } + } + + + return std::move(doc); +} diff --git a/src/publishing/plotting/SvgConverter.h b/src/publishing/plotting/SvgConverter.h index e69de29..2b4abd0 100644 --- a/src/publishing/plotting/SvgConverter.h +++ b/src/publishing/plotting/SvgConverter.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +class SvgDocument; +class Scene; + +class SvgConverter +{ +public: + std::unique_ptr convert(Scene* scene); +}; diff --git a/src/ui_elements/desktop_elements/Window.cpp b/src/ui_elements/desktop_elements/Window.cpp index 01f8b06..3082831 100644 --- a/src/ui_elements/desktop_elements/Window.cpp +++ b/src/ui_elements/desktop_elements/Window.cpp @@ -122,10 +122,9 @@ void Window::doPaint(mt::Screen* screen) { mPlatformWindow->beforePaint(screen); - auto scene = getScene(); - if (scene->getRootNode()->getNumChildren() == 0) + if (auto scene = getScene(); scene->isEmpty()) { - scene->getRootNode()->addChild(mWidget->getRootNode()); + scene->addNode(mWidget->getRootNode()); } mDrawingContext->paint(); diff --git a/src/visual_elements/Scene.cpp b/src/visual_elements/Scene.cpp index b372969..5dd8e79 100644 --- a/src/visual_elements/Scene.cpp +++ b/src/visual_elements/Scene.cpp @@ -12,12 +12,27 @@ Scene::Scene() mRootNode->setName("Scene_RootNode"); } +Scene::~Scene() +{ + +} + void Scene::update(FontsManager* fontsManager) { mSceneItems.clear(); updateNode(mRootNode.get(), fontsManager); } +void Scene::addNode(AbstractVisualNode* node) +{ + mRootNode->addChild(node); +} + +bool Scene::isEmpty() const +{ + return mRootNode->getNumChildren() == 0; +} + void Scene::updateNode(AbstractVisualNode* node, FontsManager* fontsManager) { for (auto child : node->getChildren()) @@ -39,17 +54,7 @@ void Scene::updateNode(AbstractVisualNode* node, FontsManager* fontsManager) } } -RootNode* Scene::getRootNode() const +const std::vector& Scene::getItems() const { - return mRootNode.get(); -} - -unsigned Scene::getNumItems() const -{ - return mSceneItems.size(); -} - -SceneItem* Scene::getItem(std::size_t idx) const -{ - return mSceneItems[idx]; + return mSceneItems; } diff --git a/src/visual_elements/Scene.h b/src/visual_elements/Scene.h index 5c6e95a..f5880ea 100644 --- a/src/visual_elements/Scene.h +++ b/src/visual_elements/Scene.h @@ -15,13 +15,15 @@ class Scene public: Scene(); - void update(FontsManager* fontsManager); + ~Scene(); - unsigned getNumItems() const; + void addNode(AbstractVisualNode* node); - SceneItem* getItem(std::size_t idx) const; + const std::vector& getItems() const; - RootNode* getRootNode() const; + bool isEmpty() const; + + void update(FontsManager* fontsManager = nullptr); private: void updateNode(AbstractVisualNode* node, FontsManager* fontsManager); std::unique_ptr mRootNode; diff --git a/src/web/svg/elements/SvgShapeElements.cpp b/src/web/svg/elements/SvgShapeElements.cpp index 297e7d3..f8ce7aa 100644 --- a/src/web/svg/elements/SvgShapeElements.cpp +++ b/src/web/svg/elements/SvgShapeElements.cpp @@ -1,5 +1,7 @@ #include "SvgShapeElements.h" +#include + SvgCircle::SvgCircle() : SvgShapeElement("circle") { @@ -60,3 +62,24 @@ void SvgRectangle::setHeight(unsigned h) addAttribute(std::move(height)); } + + +SvgPolygon::SvgPolygon() + : SvgShapeElement("polygon") +{ + +} + +void SvgPolygon::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 66545e7..765e827 100644 --- a/src/web/svg/elements/SvgShapeElements.h +++ b/src/web/svg/elements/SvgShapeElements.h @@ -26,3 +26,11 @@ public: void setHeight(unsigned height); }; + +class SvgPolygon : public SvgShapeElement +{ +public: + SvgPolygon(); + + void setPoints(const std::vector& loc); +}; diff --git a/test/publishing/CMakeLists.txt b/test/publishing/CMakeLists.txt index dccf849..766e437 100644 --- a/test/publishing/CMakeLists.txt +++ b/test/publishing/CMakeLists.txt @@ -1,6 +1,7 @@ set(PUBLISHING_UNIT_TEST_FILES publishing/TestPdfWriter.cpp publishing/TestDocumentConverter.cpp + publishing/TestSvgConverter.cpp PARENT_SCOPE ) diff --git a/test/publishing/TestSvgConverter.cpp b/test/publishing/TestSvgConverter.cpp new file mode 100644 index 0000000..c90df51 --- /dev/null +++ b/test/publishing/TestSvgConverter.cpp @@ -0,0 +1,28 @@ +#include "SvgWriter.h" +#include "SvgDocument.h" +#include "SvgConverter.h" +#include "Scene.h" + +#include "CircleNode.h" + +#include "File.h" + +#include "TestFramework.h" +#include "TestUtils.h" + +TEST_CASE(TestSvgConverter, "[publishing]") +{ + Scene scene; + + CircleNode circle({10, 10}, 20); + scene.addNode(&circle); + + SvgConverter converter; + auto svg_document = converter.convert(&scene); + + SvgWriter writer; + auto content = writer.toString(svg_document.get()); + + auto outFile = std::make_unique(TestUtils::getTestOutputDir(__FILE__) / "scene.svg"); + outFile->writeText(content); +} diff --git a/test/web/TestSvgWriter.cpp b/test/web/TestSvgWriter.cpp index 05149c0..5bf42dd 100644 --- a/test/web/TestSvgWriter.cpp +++ b/test/web/TestSvgWriter.cpp @@ -25,6 +25,11 @@ TEST_CASE(TestSvgWriter, "web") rectangle->setFill({0, 0, 255}); document->getRoot()->addChild(std::move(rectangle)); + auto triangle = std::make_unique(); + triangle->setPoints({{10, 10}, {50, 10}, {30, 20}}); + triangle->setFill({0, 255, 0}); + document->getRoot()->addChild(std::move(triangle)); + SvgWriter writer; auto content = writer.toString(document.get());