Add simple mesh viewer
This commit is contained in:
parent
fcd90b5db4
commit
8a41337e2d
19 changed files with 275 additions and 2 deletions
|
@ -9,6 +9,9 @@ list(APPEND client_HEADERS
|
||||||
image_editor/ImageViewWidget.h
|
image_editor/ImageViewWidget.h
|
||||||
canvas/CanvasView.h
|
canvas/CanvasView.h
|
||||||
canvas/CanvasController.h
|
canvas/CanvasController.h
|
||||||
|
mesh_viewer/MeshViewerView.h
|
||||||
|
mesh_viewer/MeshViewerController.h
|
||||||
|
mesh_viewer/MeshViewerCanvas.h
|
||||||
web_client/WebClientView.h)
|
web_client/WebClientView.h)
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +23,9 @@ list(APPEND client_LIB_INCLUDES
|
||||||
audio_editor/AudioEditorView.cpp
|
audio_editor/AudioEditorView.cpp
|
||||||
image_editor/ImageEditorView.cpp
|
image_editor/ImageEditorView.cpp
|
||||||
image_editor/ImageViewWidget.cpp
|
image_editor/ImageViewWidget.cpp
|
||||||
|
mesh_viewer/MeshViewerView.cpp
|
||||||
|
mesh_viewer/MeshViewerController.cpp
|
||||||
|
mesh_viewer/MeshViewerCanvas.cpp
|
||||||
canvas/CanvasView.cpp
|
canvas/CanvasView.cpp
|
||||||
canvas/CanvasController.cpp
|
canvas/CanvasController.cpp
|
||||||
web_client/WebClientView.cpp
|
web_client/WebClientView.cpp
|
||||||
|
@ -42,6 +48,7 @@ target_include_directories(sample_gui PUBLIC
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/image_editor"
|
"${CMAKE_CURRENT_SOURCE_DIR}/image_editor"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/web_client"
|
"${CMAKE_CURRENT_SOURCE_DIR}/web_client"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/canvas"
|
"${CMAKE_CURRENT_SOURCE_DIR}/canvas"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/mesh_viewer"
|
||||||
)
|
)
|
||||||
target_link_libraries(sample_gui PUBLIC client windows console core network database geometry audio web)
|
target_link_libraries(sample_gui PUBLIC client windows console core network database geometry audio web)
|
||||||
set_property(TARGET sample_gui PROPERTY FOLDER apps)
|
set_property(TARGET sample_gui PROPERTY FOLDER apps)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "ImageEditorView.h"
|
#include "ImageEditorView.h"
|
||||||
#include "WebClientView.h"
|
#include "WebClientView.h"
|
||||||
#include "CanvasView.h"
|
#include "CanvasView.h"
|
||||||
|
#include "MeshViewerView.h"
|
||||||
|
|
||||||
#include "TabbedPanelWidget.h"
|
#include "TabbedPanelWidget.h"
|
||||||
#include "TopBar.h"
|
#include "TopBar.h"
|
||||||
|
@ -54,6 +55,10 @@ void MediaTool::initializeViews()
|
||||||
canvas->setName("CanvasView");
|
canvas->setName("CanvasView");
|
||||||
tabbedPanel->addPanel(std::move(canvas), "Canvas");
|
tabbedPanel->addPanel(std::move(canvas), "Canvas");
|
||||||
|
|
||||||
|
auto mesh = MeshViewerView::Create();
|
||||||
|
mesh->setName("MeshViewer");
|
||||||
|
tabbedPanel->addPanel(std::move(mesh), "Mesh Viewer");
|
||||||
|
|
||||||
auto topBar = TopBar::Create();
|
auto topBar = TopBar::Create();
|
||||||
auto statusBar = StatusBar::Create();
|
auto statusBar = StatusBar::Create();
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
CanvasView::CanvasView()
|
CanvasView::CanvasView()
|
||||||
: mController(CanvasController::Create())
|
: mController(CanvasController::Create())
|
||||||
{
|
{
|
||||||
|
std::cout << "Creatin canvas" << std::endl;
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
ImageViewWidget::ImageViewWidget()
|
ImageViewWidget::ImageViewWidget()
|
||||||
{
|
{
|
||||||
|
std::cout << "Creating image view widget" << std::endl;
|
||||||
mName = "ImageViewWidget";
|
mName = "ImageViewWidget";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
0
apps/sample-gui/mesh_viewer/MeshViewerCanvas.cpp
Normal file
0
apps/sample-gui/mesh_viewer/MeshViewerCanvas.cpp
Normal file
0
apps/sample-gui/mesh_viewer/MeshViewerCanvas.h
Normal file
0
apps/sample-gui/mesh_viewer/MeshViewerCanvas.h
Normal file
0
apps/sample-gui/mesh_viewer/MeshViewerController.cpp
Normal file
0
apps/sample-gui/mesh_viewer/MeshViewerController.cpp
Normal file
0
apps/sample-gui/mesh_viewer/MeshViewerController.h
Normal file
0
apps/sample-gui/mesh_viewer/MeshViewerController.h
Normal file
65
apps/sample-gui/mesh_viewer/MeshViewerView.cpp
Normal file
65
apps/sample-gui/mesh_viewer/MeshViewerView.cpp
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#include "MeshViewerView.h"
|
||||||
|
|
||||||
|
#include "MeshNode.h"
|
||||||
|
#include "TransformNode.h"
|
||||||
|
#include "AbstractMesh.h"
|
||||||
|
#include "MeshPrimitives.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
std::unique_ptr<MeshViewerView> MeshViewerView::Create()
|
||||||
|
{
|
||||||
|
return std::make_unique<MeshViewerView>();
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshViewerView::~MeshViewerView()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshViewerView::MeshViewerView()
|
||||||
|
{
|
||||||
|
mName = "MeshViewerView";
|
||||||
|
mBackgroundColor = {204, 204, 255};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshViewerView::doPaint(const PaintEvent* event)
|
||||||
|
{
|
||||||
|
if (!mVisible)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mMeshNode)
|
||||||
|
{
|
||||||
|
mMeshNode = std::make_unique<MeshNode>(mLocation);
|
||||||
|
mMeshNode->setName(mName + "_MeshNode");
|
||||||
|
|
||||||
|
mMeshNode->setWidth(mSize.mWidth);
|
||||||
|
mMeshNode->setHeight(mSize.mHeight);
|
||||||
|
|
||||||
|
mMeshNode->setFillColor(mBackgroundColor);
|
||||||
|
|
||||||
|
mRootNode->addChild(mMeshNode.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTransformDirty)
|
||||||
|
{
|
||||||
|
mMeshNode->setLocation(mLocation);
|
||||||
|
mMeshNode->setWidth(mSize.mWidth);
|
||||||
|
mMeshNode->setHeight(mSize.mHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMaterialDirty)
|
||||||
|
{
|
||||||
|
mMeshNode->setFillColor(mBackgroundColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mMesh)
|
||||||
|
{
|
||||||
|
auto mesh = MeshPrimitives::buildRectangleAsTriMesh();
|
||||||
|
mMesh = std::move(mesh);
|
||||||
|
|
||||||
|
mMeshNode->setMesh(mMesh.get());
|
||||||
|
}
|
||||||
|
}
|
19
apps/sample-gui/mesh_viewer/MeshViewerView.h
Normal file
19
apps/sample-gui/mesh_viewer/MeshViewerView.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Widget.h"
|
||||||
|
|
||||||
|
class MeshNode;
|
||||||
|
class AbstractMesh;
|
||||||
|
|
||||||
|
class MeshViewerView : public Widget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MeshViewerView();
|
||||||
|
~MeshViewerView();
|
||||||
|
static std::unique_ptr<MeshViewerView> Create();
|
||||||
|
void doPaint(const PaintEvent* event) override;
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::unique_ptr<AbstractMesh> mMesh;
|
||||||
|
std::unique_ptr<MeshNode> mMeshNode;
|
||||||
|
};
|
|
@ -121,10 +121,16 @@ void OpenGlMeshPainter::paint(SceneModel* model, DrawingContext* context)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
indices = dynamic_cast<TriMesh*>(model->getMesh())->getFaceNodeIds();
|
indices = dynamic_cast<TriMesh*>(model->getMesh())->getFaceNodeIds();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto model_color = model->getColor().getAsVectorDouble();
|
auto model_color = model->getColor().getAsVectorDouble();
|
||||||
std::vector<float> color = {float(model_color[0]), float(model_color[1]), float(model_color[2]), float(model_color[3])};
|
std::vector<float> color = {float(model_color[0]), float(model_color[1]), float(model_color[2]), float(model_color[3])};
|
||||||
|
|
||||||
paint(vertices, indices, color, line_mesh);
|
paint(vertices, indices, color, line_mesh);
|
||||||
|
|
||||||
|
if (model->getShowOutline())
|
||||||
|
{
|
||||||
|
auto edge_indices = dynamic_cast<TriMesh*>(model->getMesh())->getEdgeNodeIds();
|
||||||
|
paint(vertices, edge_indices, {0, 0, 0, 1}, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,11 @@ public:
|
||||||
|
|
||||||
void transform(const Transform& transform);
|
void transform(const Transform& transform);
|
||||||
|
|
||||||
|
unsigned getNumNodes() const
|
||||||
|
{
|
||||||
|
return mNodes.size();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
|
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
|
||||||
VecNodes mNodes;
|
VecNodes mNodes;
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "Edge.h"
|
#include "Edge.h"
|
||||||
#include "AbstractFace.h"
|
#include "AbstractFace.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
FaceMesh::~FaceMesh()
|
FaceMesh::~FaceMesh()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -64,18 +66,21 @@ void FaceMesh::resetIds()
|
||||||
for (auto& node : mNodes)
|
for (auto& node : mNodes)
|
||||||
{
|
{
|
||||||
node->setIndex(count);
|
node->setIndex(count);
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
for (auto& edge : mEdges)
|
for (auto& edge : mEdges)
|
||||||
{
|
{
|
||||||
edge->setIndex(count);
|
edge->setIndex(count);
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
for (auto& face : mFaces)
|
for (auto& face : mFaces)
|
||||||
{
|
{
|
||||||
face->setIndex(count);
|
face->setIndex(count);
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +137,17 @@ void FaceMesh::replaceIfOverlapping(FaceMesh* mesh, Edge* target_edge) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned> FaceMesh::getEdgeNodeIds() const
|
||||||
|
{
|
||||||
|
std::vector<unsigned> ids(2*mEdges.size());
|
||||||
|
for(std::size_t idx=0; idx<mEdges.size(); idx++)
|
||||||
|
{
|
||||||
|
ids[2*idx] = mEdges[idx]->getNode0Id();
|
||||||
|
ids[2*idx + 1] = mEdges[idx]->getNode1Id();
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
void FaceMesh::merge(std::unique_ptr<FaceMesh> mesh)
|
void FaceMesh::merge(std::unique_ptr<FaceMesh> mesh)
|
||||||
{
|
{
|
||||||
if (mesh->getType() != getType())
|
if (mesh->getType() != getType())
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
|
|
||||||
std::vector<unsigned> getFaceNodeIds() const;
|
std::vector<unsigned> getFaceNodeIds() const;
|
||||||
|
|
||||||
|
std::vector<unsigned> getEdgeNodeIds() const;
|
||||||
|
|
||||||
void addConstantFaceVectorAttribute(const std::string& tag, const std::vector<double>& values);
|
void addConstantFaceVectorAttribute(const std::string& tag, const std::vector<double>& values);
|
||||||
|
|
||||||
std::vector<std::vector<double> > getFaceVectorAttributes(const std::string& tag);
|
std::vector<std::vector<double> > getFaceVectorAttributes(const std::string& tag);
|
||||||
|
|
|
@ -2,6 +2,7 @@ list(APPEND visual_elements_LIB_INCLUDES
|
||||||
GeometryNode.cpp
|
GeometryNode.cpp
|
||||||
RectangleNode.cpp
|
RectangleNode.cpp
|
||||||
MaterialNode.cpp
|
MaterialNode.cpp
|
||||||
|
MeshNode.cpp
|
||||||
TextNode.cpp
|
TextNode.cpp
|
||||||
Scene.cpp
|
Scene.cpp
|
||||||
SceneModel.cpp
|
SceneModel.cpp
|
||||||
|
|
90
src/visual_elements/MeshNode.cpp
Normal file
90
src/visual_elements/MeshNode.cpp
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#include "MeshNode.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
MeshNode::MeshNode(const DiscretePoint& location)
|
||||||
|
: MaterialNode(location)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshNode::setWidth(unsigned width)
|
||||||
|
{
|
||||||
|
if (mWidth != width)
|
||||||
|
{
|
||||||
|
mTransformIsDirty = true;
|
||||||
|
mWidth = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshNode::setHeight(unsigned height)
|
||||||
|
{
|
||||||
|
if (mHeight != height)
|
||||||
|
{
|
||||||
|
mTransformIsDirty = true;
|
||||||
|
mHeight = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshNode::setMesh(AbstractMesh* mesh)
|
||||||
|
{
|
||||||
|
mWorkingMesh = mesh;
|
||||||
|
mMeshIsDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneItem* MeshNode::getSceneItem(std::size_t idx) const
|
||||||
|
{
|
||||||
|
return mModel.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned MeshNode::getNumSceneItems() const
|
||||||
|
{
|
||||||
|
if (mWorkingMesh)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshNode::update(FontsManager* fontsManager)
|
||||||
|
{
|
||||||
|
if (!mModel || mMeshIsDirty)
|
||||||
|
{
|
||||||
|
if (!mModel)
|
||||||
|
{
|
||||||
|
mModel = std::make_unique<SceneModel>(nullptr);
|
||||||
|
mModel->setName(mName + "_MeshModel");
|
||||||
|
mModel->setShowOutline(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWorkingMesh)
|
||||||
|
{
|
||||||
|
mModel->updateMesh(mWorkingMesh);
|
||||||
|
mMeshIsDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWorkingMesh && mMeshIsDirty)
|
||||||
|
{
|
||||||
|
std::cout << "Updating mesh with " << mWorkingMesh->getNumNodes() << std::endl;
|
||||||
|
mModel->updateMesh(mWorkingMesh);
|
||||||
|
mMeshIsDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTransformIsDirty)
|
||||||
|
{
|
||||||
|
auto size = mHeight > mWidth ? mWidth : mHeight;
|
||||||
|
mModel->updateTransform({mLocation, static_cast<double>(size), static_cast<double>(size)});
|
||||||
|
mTransformIsDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMaterialIsDirty)
|
||||||
|
{
|
||||||
|
mModel->updateUniformColor(mFillColor);
|
||||||
|
mMaterialIsDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
28
src/visual_elements/MeshNode.h
Normal file
28
src/visual_elements/MeshNode.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MaterialNode.h"
|
||||||
|
|
||||||
|
class AbstractMesh;
|
||||||
|
|
||||||
|
class MeshNode : public MaterialNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MeshNode(const DiscretePoint& location);
|
||||||
|
void setMesh(AbstractMesh* mesh);
|
||||||
|
|
||||||
|
SceneItem* getSceneItem(std::size_t idx) const override;
|
||||||
|
unsigned getNumSceneItems() const override;
|
||||||
|
|
||||||
|
void setWidth(unsigned width);
|
||||||
|
void setHeight(unsigned height);
|
||||||
|
|
||||||
|
void update(FontsManager* fontsManager) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mMeshIsDirty{true};
|
||||||
|
AbstractMesh* mWorkingMesh{nullptr};
|
||||||
|
|
||||||
|
unsigned mWidth{1};
|
||||||
|
unsigned mHeight{1};
|
||||||
|
std::unique_ptr<SceneModel> mModel;
|
||||||
|
};
|
|
@ -11,7 +11,14 @@ SceneModel::SceneModel(std::unique_ptr<AbstractMesh> mesh)
|
||||||
|
|
||||||
AbstractMesh* SceneModel::getMesh() const
|
AbstractMesh* SceneModel::getMesh() const
|
||||||
{
|
{
|
||||||
|
if (mMesh)
|
||||||
|
{
|
||||||
return mMesh.get();
|
return mMesh.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return mRawMesh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneModel::updateMesh(std::unique_ptr<AbstractMesh> mesh)
|
void SceneModel::updateMesh(std::unique_ptr<AbstractMesh> mesh)
|
||||||
|
@ -20,6 +27,12 @@ void SceneModel::updateMesh(std::unique_ptr<AbstractMesh> mesh)
|
||||||
mMeshIsDirty = true;
|
mMeshIsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneModel::updateMesh(AbstractMesh* mesh)
|
||||||
|
{
|
||||||
|
mRawMesh = mesh;
|
||||||
|
mMeshIsDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
SceneItem::Type SceneModel::getType() const
|
SceneItem::Type SceneModel::getType() const
|
||||||
{
|
{
|
||||||
return SceneItem::Type::MODEL;
|
return SceneItem::Type::MODEL;
|
||||||
|
|
|
@ -19,13 +19,27 @@ public:
|
||||||
AbstractMesh* getMesh() const;
|
AbstractMesh* getMesh() const;
|
||||||
|
|
||||||
void updateMesh(std::unique_ptr<AbstractMesh> mesh);
|
void updateMesh(std::unique_ptr<AbstractMesh> mesh);
|
||||||
|
void updateMesh(AbstractMesh* mesh);
|
||||||
|
|
||||||
|
void setShowOutline(bool showOutline)
|
||||||
|
{
|
||||||
|
mShowOutline = showOutline;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getShowOutline() const
|
||||||
|
{
|
||||||
|
return mShowOutline;
|
||||||
|
}
|
||||||
|
|
||||||
Type getType() const override;
|
Type getType() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
AbstractMesh* mRawMesh{nullptr};
|
||||||
std::unique_ptr<AbstractMesh> mMesh;
|
std::unique_ptr<AbstractMesh> mMesh;
|
||||||
std::unique_ptr<Texture> mColorMap;
|
std::unique_ptr<Texture> mColorMap;
|
||||||
|
|
||||||
bool mMeshIsDirty{true};
|
bool mMeshIsDirty{true};
|
||||||
bool mColorMapIsDirty{true};
|
bool mColorMapIsDirty{true};
|
||||||
|
bool mShowOutline{false};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue