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
|
||||
canvas/CanvasView.h
|
||||
canvas/CanvasController.h
|
||||
mesh_viewer/MeshViewerView.h
|
||||
mesh_viewer/MeshViewerController.h
|
||||
mesh_viewer/MeshViewerCanvas.h
|
||||
web_client/WebClientView.h)
|
||||
|
||||
|
||||
|
@ -20,6 +23,9 @@ list(APPEND client_LIB_INCLUDES
|
|||
audio_editor/AudioEditorView.cpp
|
||||
image_editor/ImageEditorView.cpp
|
||||
image_editor/ImageViewWidget.cpp
|
||||
mesh_viewer/MeshViewerView.cpp
|
||||
mesh_viewer/MeshViewerController.cpp
|
||||
mesh_viewer/MeshViewerCanvas.cpp
|
||||
canvas/CanvasView.cpp
|
||||
canvas/CanvasController.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}/web_client"
|
||||
"${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)
|
||||
set_property(TARGET sample_gui PROPERTY FOLDER apps)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "ImageEditorView.h"
|
||||
#include "WebClientView.h"
|
||||
#include "CanvasView.h"
|
||||
#include "MeshViewerView.h"
|
||||
|
||||
#include "TabbedPanelWidget.h"
|
||||
#include "TopBar.h"
|
||||
|
@ -54,6 +55,10 @@ void MediaTool::initializeViews()
|
|||
canvas->setName("CanvasView");
|
||||
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 statusBar = StatusBar::Create();
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
CanvasView::CanvasView()
|
||||
: mController(CanvasController::Create())
|
||||
{
|
||||
std::cout << "Creatin canvas" << std::endl;
|
||||
initialize();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
ImageViewWidget::ImageViewWidget()
|
||||
{
|
||||
std::cout << "Creating image view widget" << std::endl;
|
||||
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
|
||||
{
|
||||
indices = dynamic_cast<TriMesh*>(model->getMesh())->getFaceNodeIds();
|
||||
|
||||
}
|
||||
|
||||
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])};
|
||||
|
||||
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);
|
||||
|
||||
unsigned getNumNodes() const
|
||||
{
|
||||
return mNodes.size();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unordered_map<std::string, std::vector<double> > mVectorAttributes;
|
||||
VecNodes mNodes;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "Edge.h"
|
||||
#include "AbstractFace.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
FaceMesh::~FaceMesh()
|
||||
{
|
||||
|
||||
|
@ -64,18 +66,21 @@ void FaceMesh::resetIds()
|
|||
for (auto& node : mNodes)
|
||||
{
|
||||
node->setIndex(count);
|
||||
count++;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
for (auto& edge : mEdges)
|
||||
{
|
||||
edge->setIndex(count);
|
||||
count++;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
for (auto& face : mFaces)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (mesh->getType() != getType())
|
||||
|
|
|
@ -27,6 +27,8 @@ public:
|
|||
|
||||
std::vector<unsigned> getFaceNodeIds() const;
|
||||
|
||||
std::vector<unsigned> getEdgeNodeIds() const;
|
||||
|
||||
void addConstantFaceVectorAttribute(const std::string& tag, const std::vector<double>& values);
|
||||
|
||||
std::vector<std::vector<double> > getFaceVectorAttributes(const std::string& tag);
|
||||
|
|
|
@ -2,6 +2,7 @@ list(APPEND visual_elements_LIB_INCLUDES
|
|||
GeometryNode.cpp
|
||||
RectangleNode.cpp
|
||||
MaterialNode.cpp
|
||||
MeshNode.cpp
|
||||
TextNode.cpp
|
||||
Scene.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;
|
||||
};
|
|
@ -10,9 +10,16 @@ SceneModel::SceneModel(std::unique_ptr<AbstractMesh> mesh)
|
|||
}
|
||||
|
||||
AbstractMesh* SceneModel::getMesh() const
|
||||
{
|
||||
if (mMesh)
|
||||
{
|
||||
return mMesh.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
return mRawMesh;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneModel::updateMesh(std::unique_ptr<AbstractMesh> mesh)
|
||||
{
|
||||
|
@ -20,6 +27,12 @@ void SceneModel::updateMesh(std::unique_ptr<AbstractMesh> mesh)
|
|||
mMeshIsDirty = true;
|
||||
}
|
||||
|
||||
void SceneModel::updateMesh(AbstractMesh* mesh)
|
||||
{
|
||||
mRawMesh = mesh;
|
||||
mMeshIsDirty = true;
|
||||
}
|
||||
|
||||
SceneItem::Type SceneModel::getType() const
|
||||
{
|
||||
return SceneItem::Type::MODEL;
|
||||
|
|
|
@ -19,13 +19,27 @@ public:
|
|||
AbstractMesh* getMesh() const;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
|
||||
AbstractMesh* mRawMesh{nullptr};
|
||||
std::unique_ptr<AbstractMesh> mMesh;
|
||||
std::unique_ptr<Texture> mColorMap;
|
||||
|
||||
bool mMeshIsDirty{true};
|
||||
bool mColorMapIsDirty{true};
|
||||
bool mShowOutline{false};
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue