Initial scene to svg conversion.

This commit is contained in:
James Grogan 2022-12-08 08:48:18 +00:00
parent 65ac927929
commit 1fc730d413
15 changed files with 164 additions and 28 deletions

View file

@ -55,16 +55,15 @@ void OpenGlPainter::paint(DrawingContext* context)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
auto scene = context->getSurface()->getScene(); auto scene = context->getSurface()->getScene();
for(unsigned idx=0; idx<scene->getNumItems(); idx++) for (const auto item : scene->getItems())
{ {
auto scene_item = scene->getItem(idx); if (item->getType() == SceneItem::Type::MODEL)
if (scene_item->getType() == SceneItem::Type::MODEL)
{ {
mMeshPainter->paint(dynamic_cast<SceneModel*>(scene_item), context); mMeshPainter->paint(dynamic_cast<SceneModel*>(item), context);
} }
else if (scene_item->getType() == SceneItem::Type::TEXT) else if (item->getType() == SceneItem::Type::TEXT)
{ {
mTextPainter->paint(dynamic_cast<SceneText*>(scene_item), context); mTextPainter->paint(dynamic_cast<SceneText*>(item), context);
} }
} }

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "Point.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
@ -30,6 +32,8 @@ public:
virtual std::vector<unsigned> getEdgeIds() const = 0; virtual std::vector<unsigned> getEdgeIds() const = 0;
//virtual std::vector<Point> getNodeLocations() const = 0;
protected: protected:
unsigned mId{0}; unsigned mId{0};
std::unordered_map<std::string, std::vector<double> > mVectorAttributes; std::unordered_map<std::string, std::vector<double> > mVectorAttributes;

View file

@ -21,6 +21,11 @@ void FaceMesh::populate(VecNodes& nodes, VecEdges& edges, VecFaces& faces)
resetConnectivity(); resetConnectivity();
} }
const VecFaces& FaceMesh::getFaces() const
{
return mFaces;
}
std::vector<unsigned> FaceMesh::getFaceNodeIds() const std::vector<unsigned> FaceMesh::getFaceNodeIds() const
{ {
if (mFaces.empty()) if (mFaces.empty())

View file

@ -35,6 +35,8 @@ public:
void merge(std::unique_ptr<FaceMesh> mesh); void merge(std::unique_ptr<FaceMesh> mesh);
const VecFaces& getFaces() const;
protected: protected:
void resetConnectivity(); void resetConnectivity();

View file

@ -25,15 +25,16 @@ list(APPEND publishing_LIB_INCLUDES
pdf/PdfXRefTable.cpp pdf/PdfXRefTable.cpp
pdf/PdfWriter.cpp pdf/PdfWriter.cpp
plotting/GraphPlotter.h plotting/GraphPlotter.h
plotting/SvgConverter.h plotting/SvgConverter.cpp
DocumentConverter.cpp DocumentConverter.cpp
) )
add_library(publishing SHARED ${publishing_LIB_INCLUDES} ${publishing_INCLUDES} ${publishing_HEADERS}) add_library(publishing SHARED ${publishing_LIB_INCLUDES} ${publishing_INCLUDES} ${publishing_HEADERS})
target_include_directories(publishing PUBLIC target_include_directories(publishing PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/pdf" ${CMAKE_CURRENT_SOURCE_DIR}/pdf
${CMAKE_CURRENT_SOURCE_DIR}/plotting
) )
set_target_properties( publishing PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) set_target_properties( publishing PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )
target_link_libraries( publishing PUBLIC core web graphics visual_elements) target_link_libraries( publishing PUBLIC core web graphics visual_elements)

View file

@ -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<SvgDocument> SvgConverter::convert(Scene* scene)
{
auto doc = std::make_unique<SvgDocument>();
scene->update();
for(auto item : scene->getItems())
{
if (item->getType() == SceneItem::Type::MODEL)
{
auto mesh = dynamic_cast<SceneModel*>(item)->getMesh();
if (mesh->getType() == AbstractMesh::MeshType::TRI)
{
for(const auto& face : dynamic_cast<TriMesh*>(mesh)->getFaces())
{
auto svg_tri = std::make_unique<SvgPolygon>();
// Get node locs for face
// Convert to pixel
// add polygon to doc
}
}
}
}
return std::move(doc);
}

View file

@ -0,0 +1,12 @@
#pragma once
#include <memory>
class SvgDocument;
class Scene;
class SvgConverter
{
public:
std::unique_ptr<SvgDocument> convert(Scene* scene);
};

View file

@ -122,10 +122,9 @@ void Window::doPaint(mt::Screen* screen)
{ {
mPlatformWindow->beforePaint(screen); mPlatformWindow->beforePaint(screen);
auto scene = getScene(); if (auto scene = getScene(); scene->isEmpty())
if (scene->getRootNode()->getNumChildren() == 0)
{ {
scene->getRootNode()->addChild(mWidget->getRootNode()); scene->addNode(mWidget->getRootNode());
} }
mDrawingContext->paint(); mDrawingContext->paint();

View file

@ -12,12 +12,27 @@ Scene::Scene()
mRootNode->setName("Scene_RootNode"); mRootNode->setName("Scene_RootNode");
} }
Scene::~Scene()
{
}
void Scene::update(FontsManager* fontsManager) void Scene::update(FontsManager* fontsManager)
{ {
mSceneItems.clear(); mSceneItems.clear();
updateNode(mRootNode.get(), fontsManager); 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) void Scene::updateNode(AbstractVisualNode* node, FontsManager* fontsManager)
{ {
for (auto child : node->getChildren()) for (auto child : node->getChildren())
@ -39,17 +54,7 @@ void Scene::updateNode(AbstractVisualNode* node, FontsManager* fontsManager)
} }
} }
RootNode* Scene::getRootNode() const const std::vector<SceneItem*>& Scene::getItems() const
{ {
return mRootNode.get(); return mSceneItems;
}
unsigned Scene::getNumItems() const
{
return mSceneItems.size();
}
SceneItem* Scene::getItem(std::size_t idx) const
{
return mSceneItems[idx];
} }

View file

@ -15,13 +15,15 @@ class Scene
public: public:
Scene(); Scene();
void update(FontsManager* fontsManager); ~Scene();
unsigned getNumItems() const; void addNode(AbstractVisualNode* node);
SceneItem* getItem(std::size_t idx) const; const std::vector<SceneItem*>& getItems() const;
RootNode* getRootNode() const; bool isEmpty() const;
void update(FontsManager* fontsManager = nullptr);
private: private:
void updateNode(AbstractVisualNode* node, FontsManager* fontsManager); void updateNode(AbstractVisualNode* node, FontsManager* fontsManager);
std::unique_ptr<RootNode> mRootNode; std::unique_ptr<RootNode> mRootNode;

View file

@ -1,5 +1,7 @@
#include "SvgShapeElements.h" #include "SvgShapeElements.h"
#include <sstream>
SvgCircle::SvgCircle() SvgCircle::SvgCircle()
: SvgShapeElement("circle") : SvgShapeElement("circle")
{ {
@ -60,3 +62,24 @@ void SvgRectangle::setHeight(unsigned h)
addAttribute(std::move(height)); addAttribute(std::move(height));
} }
SvgPolygon::SvgPolygon()
: SvgShapeElement("polygon")
{
}
void SvgPolygon::setPoints(const std::vector<DiscretePoint>& locs)
{
auto points = std::make_unique<XmlAttribute>("points");
std::stringstream sstr;
for (const auto& loc : locs)
{
sstr << loc.GetX() << "," << loc.GetY() << " ";
}
points->setValue(sstr.str());
addAttribute(std::move(points));
}

View file

@ -26,3 +26,11 @@ public:
void setHeight(unsigned height); void setHeight(unsigned height);
}; };
class SvgPolygon : public SvgShapeElement
{
public:
SvgPolygon();
void setPoints(const std::vector<DiscretePoint>& loc);
};

View file

@ -1,6 +1,7 @@
set(PUBLISHING_UNIT_TEST_FILES set(PUBLISHING_UNIT_TEST_FILES
publishing/TestPdfWriter.cpp publishing/TestPdfWriter.cpp
publishing/TestDocumentConverter.cpp publishing/TestDocumentConverter.cpp
publishing/TestSvgConverter.cpp
PARENT_SCOPE PARENT_SCOPE
) )

View file

@ -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<File>(TestUtils::getTestOutputDir(__FILE__) / "scene.svg");
outFile->writeText(content);
}

View file

@ -25,6 +25,11 @@ TEST_CASE(TestSvgWriter, "web")
rectangle->setFill({0, 0, 255}); rectangle->setFill({0, 0, 255});
document->getRoot()->addChild(std::move(rectangle)); document->getRoot()->addChild(std::move(rectangle));
auto triangle = std::make_unique<SvgPolygon>();
triangle->setPoints({{10, 10}, {50, 10}, {30, 20}});
triangle->setFill({0, 255, 0});
document->getRoot()->addChild(std::move(triangle));
SvgWriter writer; SvgWriter writer;
auto content = writer.toString(document.get()); auto content = writer.toString(document.get());