Initial scene to svg conversion.
This commit is contained in:
parent
65ac927929
commit
1fc730d413
15 changed files with 164 additions and 28 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class SvgDocument;
|
||||||
|
class Scene;
|
||||||
|
|
||||||
|
class SvgConverter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::unique_ptr<SvgDocument> convert(Scene* scene);
|
||||||
|
};
|
|
@ -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();
|
||||||
|
|
|
@ -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];
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
};
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
28
test/publishing/TestSvgConverter.cpp
Normal file
28
test/publishing/TestSvgConverter.cpp
Normal 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);
|
||||||
|
}
|
|
@ -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());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue