Add simple mesh viewer

This commit is contained in:
James Grogan 2022-11-18 17:05:33 +00:00
parent fcd90b5db4
commit 8a41337e2d
19 changed files with 275 additions and 2 deletions

View file

@ -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)

View file

@ -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();

View file

@ -16,6 +16,7 @@
CanvasView::CanvasView() CanvasView::CanvasView()
: mController(CanvasController::Create()) : mController(CanvasController::Create())
{ {
std::cout << "Creatin canvas" << std::endl;
initialize(); initialize();
} }

View file

@ -7,6 +7,7 @@
ImageViewWidget::ImageViewWidget() ImageViewWidget::ImageViewWidget()
{ {
std::cout << "Creating image view widget" << std::endl;
mName = "ImageViewWidget"; mName = "ImageViewWidget";
} }

View 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());
}
}

View 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;
};

View file

@ -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);
}
} }

View file

@ -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;

View file

@ -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())

View file

@ -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);

View file

@ -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

View 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;
}
}

View 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;
};

View file

@ -11,7 +11,14 @@ SceneModel::SceneModel(std::unique_ptr<AbstractMesh> mesh)
AbstractMesh* SceneModel::getMesh() const AbstractMesh* SceneModel::getMesh() const
{ {
return mMesh.get(); if (mMesh)
{
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;

View file

@ -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};
}; };