Reimplement the axes program as a layer that can be added to PartRenderer

Sun, 12 Jun 2022 23:59:37 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Sun, 12 Jun 2022 23:59:37 +0300
changeset 215
34c6e7bc4ee1
parent 214
8e1fe64ce4e3
child 216
c7241f504117

Reimplement the axes program as a layer that can be added to PartRenderer

CMakeLists.txt file | annotate | diff | comparison | revisions
src/document.h file | annotate | diff | comparison | revisions
src/gl/axesprogram.cpp file | annotate | diff | comparison | revisions
src/gl/axesprogram.h file | annotate | diff | comparison | revisions
src/gl/basicshaderprogram.cpp file | annotate | diff | comparison | revisions
src/gl/basicshaderprogram.h file | annotate | diff | comparison | revisions
src/gl/common.h file | annotate | diff | comparison | revisions
src/gl/partrenderer.cpp file | annotate | diff | comparison | revisions
src/gl/partrenderer.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
src/ui/canvas.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sun Jun 12 20:47:04 2022 +0300
+++ b/CMakeLists.txt	Sun Jun 12 23:59:37 2022 +0300
@@ -39,14 +39,14 @@
 	src/gl/axesprogram.cpp
 	src/gl/basicshaderprogram.cpp
 	src/gl/compiler.cpp
-	src/gl/gridprogram.cpp
+#	src/gl/gridprogram.cpp
 	src/gl/partrenderer.cpp
-	src/gl/vertexprogram.cpp
+#	src/gl/vertexprogram.cpp
 	src/settingseditor/keyboardshortcutseditor.cpp
 	src/settingseditor/librarieseditor.cpp
 	src/settingseditor/settingseditor.cpp
 	src/types/boundingbox.cpp
-	src/ui/canvas.cpp
+#	src/ui/canvas.cpp
 	src/ui/multiplyfactordialog.cpp
 	src/ui/objecteditor.cpp
 	src/widgets/colorbutton.cpp
@@ -77,14 +77,14 @@
 	src/gl/basicshaderprogram.h
 	src/gl/common.h
 	src/gl/compiler.h
-	src/gl/gridprogram.h
+#	src/gl/gridprogram.h
 	src/gl/partrenderer.h
-	src/gl/vertexprogram.h
+#	src/gl/vertexprogram.h
 	src/settingseditor/keyboardshortcutseditor.h
 	src/settingseditor/librarieseditor.h
 	src/settingseditor/settingseditor.h
 	src/types/boundingbox.h
-	src/ui/canvas.h
+#	src/ui/canvas.h
 	src/ui/multiplyfactordialog.h
 	src/ui/objecteditor.h
 	src/widgets/colorbutton.h
--- a/src/document.h	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/document.h	Sun Jun 12 23:59:37 2022 +0300
@@ -20,10 +20,26 @@
 #include <memory>
 #include <QWidget>
 #include <QToolBar>
-#include "ui/canvas.h"
 #include "model.h"
 #include "vertexmap.h"
 
+enum EditingMode
+{
+	SelectMode,
+	DrawMode
+};
+
+Q_DECLARE_METATYPE(EditingMode);
+
+struct DrawState
+{
+	std::vector<glm::vec3> polygon;
+	std::vector<glm::vec3> previewPolygon;
+	glm::vec3 previewPoint;
+	bool isconcave = false;
+	EditingMode mode = SelectMode;
+};
+
 struct AppendToModel
 {
 	ModelElement newElement;
--- a/src/gl/axesprogram.cpp	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/gl/axesprogram.cpp	Sun Jun 12 23:59:37 2022 +0300
@@ -18,24 +18,22 @@
 
 #include "axesprogram.h"
 
-const char vertexShaderSource[] = R"(
+static constexpr char vertexShaderSource[] = R"(
 #version 330 core
 
 layout (location = 0) in vec3 in_position;
 layout (location = 1) in vec3 in_color;
-uniform mat4 view;
-uniform mat4 projection;
-uniform mat4 model;
+uniform mat4 mvp;
 smooth out vec3 ex_color;
 
 void main()
 {
-	gl_Position = projection * view * model * vec4(in_position, 1.0);
+	gl_Position = mvp * vec4(in_position, 1.0);
 	ex_color = in_color;
 }
 )";
 
-const char fragmentShaderSource[] = R"(
+static constexpr char fragmentShaderSource[] = R"(
 #version 330 core
 
 out vec4 color;
@@ -47,73 +45,54 @@
 }
 )";
 
-namespace
+void AxesLayer::initializeGL()
 {
-	struct AxesVertex
+	constexpr struct VertexType
 	{
 		glm::vec3 position;
 		glm::vec3 color;
+	} data[] = {
+		{{10000, 0, 0}, {1, 0, 0}},
+		{{0, 0, 0}, {1, 0, 0}},
+		{{-10000, 0, 0}, {0.5, 0, 0}},
+		{{0, 0, 0}, {0.5, 0, 0}},
+		{{0, 10000, 0}, {0, 1, 0}},
+		{{0, 0, 0}, {0, 1, 0}},
+		{{0, -10000, 0}, {0, 0.5, 0}},
+		{{0, 0, 0}, {0, 0.5, 0}},
+		{{0, 0, 10000}, {0, 0, 1}},
+		{{0, 0, 0}, {0, 0, 1}},
+		{{0, 0, -10000}, {0, 0, 0.5}},
+		{{0, 0, 0}, {0, 0, 0.5}},
 	};
-}
-
-static const AxesVertex data[] =
-{
-	AxesVertex{{10000, 0, 0}, {1, 0, 0}},
-	AxesVertex{{0, 0, 0}, {1, 0, 0}},
-	AxesVertex{{-10000, 0, 0}, {0.5, 0, 0}},
-	AxesVertex{{0, 0, 0}, {0.5, 0, 0}},
-	AxesVertex{{0, 10000, 0}, {0, 1, 0}},
-	AxesVertex{{0, 0, 0}, {0, 1, 0}},
-	AxesVertex{{0, -10000, 0}, {0, 0.5, 0}},
-	AxesVertex{{0, 0, 0}, {0, 0.5, 0}},
-	AxesVertex{{0, 0, 10000}, {0, 0, 1}},
-	AxesVertex{{0, 0, 0}, {0, 0, 1}},
-	AxesVertex{{0, 0, -10000}, {0, 0, 0.5}},
-	AxesVertex{{0, 0, 0}, {0, 0, 0.5}},
-};
-
-const char* AxesProgram::vertexShaderSource() const
-{
-	return ::vertexShaderSource;
-}
-
-const char* AxesProgram::fragmentShaderSource() const
-{
-	return ::fragmentShaderSource;
+	constexpr int stride = sizeof(VertexType);
+	this->shader.initialize(
+		::vertexShaderSource,
+		::fragmentShaderSource,
+		QOpenGLBuffer::StaticDraw,
+		{
+			GLAttributeSpec{
+				.type = GL_FLOAT,
+				.offset = offsetof(VertexType, position),
+				.tuplesize = 3,
+				.stride = stride,
+			},
+			{
+				.type = GL_FLOAT,
+				.offset = offsetof(VertexType, color),
+				.tuplesize = 3,
+				.stride = stride,
+			},
+		});
+	this->shader.bufferData(&data[0], countof(data), sizeof data[0]);
 }
 
-const void* AxesProgram::vertexData() const
-{
-	return ::data;
-}
-
-GLenum AxesProgram::drawMode() const
+void AxesLayer::paintGL()
 {
-	return GL_LINES;
-}
-
-int AxesProgram::vertexSize() const
-{
-	return sizeof data[0];
+	this->shader.draw(GL_LINES);
 }
 
-int AxesProgram::vertexCount() const
-{
-	return countof(data);
-}
-
-void AxesProgram::setupVertexArrays()
+void AxesLayer::mvpMatrixChanged(const glm::mat4& mvpMatrix)
 {
-	for (int i : {0, 1})
-	{
-		this->program->enableAttributeArray(i);
-	}
-	const int stride = this->vertexSize();
-	this->program->setAttributeBuffer(0, GL_FLOAT, offsetof(AxesVertex, position), 3, stride);
-	this->program->setAttributeBuffer(1, GL_FLOAT, offsetof(AxesVertex, color), 3, stride);
+	this->shader.setMvpMatrix(mvpMatrix);
 }
-
-QOpenGLBuffer::UsagePattern AxesProgram::usagePattern() const
-{
-	return QOpenGLBuffer::StaticDraw;
-}
--- a/src/gl/axesprogram.h	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/gl/axesprogram.h	Sun Jun 12 23:59:37 2022 +0300
@@ -2,18 +2,11 @@
 #include "gl/common.h"
 #include "gl/basicshaderprogram.h"
 
-class AxesProgram : public AbstractBasicShaderProgram
+class AxesLayer final : public RenderLayer
 {
-	Q_OBJECT
+	BasicShader shader;
 public:
-	using AbstractBasicShaderProgram::AbstractBasicShaderProgram;
-protected:
-	const char* vertexShaderSource() const override;
-	const char* fragmentShaderSource() const override;
-	const void* vertexData() const override;
-	GLenum drawMode() const override;
-	int vertexSize() const override;
-	int vertexCount() const override;
-	void setupVertexArrays() override;
-	QOpenGLBuffer::UsagePattern usagePattern() const override;
+	void initializeGL() override;
+	void paintGL() override;
+	void mvpMatrixChanged(const glm::mat4& mvpMatrix) override;
 };
--- a/src/gl/basicshaderprogram.cpp	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/gl/basicshaderprogram.cpp	Sun Jun 12 23:59:37 2022 +0300
@@ -18,83 +18,80 @@
 
 #include "basicshaderprogram.h"
 
-AbstractBasicShaderProgram::AbstractBasicShaderProgram(QObject* parent) :
-	QObject{parent},
+BasicShader::BasicShader() :
 	buffer{QOpenGLBuffer::VertexBuffer},
 	vertexShader{QOpenGLShader::Vertex},
 	fragmentShader{QOpenGLShader::Fragment}
 {
 }
 
-void AbstractBasicShaderProgram::initialize()
+BasicShader::~BasicShader()
 {
-	if (not isInitialized)
-	{
-		this->initializeOpenGLFunctions();
-		this->isInitialized = true;
-		this->program.emplace(this);
-		gl::buildShaders(&*this->program, this->vertexShaderSource(), this->fragmentShaderSource());
-		this->program->bind();
-		this->buffer.create();
-		this->buffer.bind();
-		const QOpenGLBuffer::UsagePattern pattern = this->usagePattern();
-		this->buffer.setUsagePattern(pattern);
-		if (pattern == QOpenGLBuffer::StaticDraw)
-		{
-			this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize());
-		}
-		this->vertexArrayObject.create();
-		this->vertexArrayObject.bind();
-		this->setupVertexArrays();
-		this->vertexArrayObject.release();
-		this->buffer.release();
-		this->program->release();
-		this->checkForGLErrors();
+	if (this->isInitialized) {
+		this->teardown();
 	}
 }
 
-void AbstractBasicShaderProgram::setViewMatrix(const glm::mat4& newViewMatrix)
+void BasicShader::initialize(
+	const char* vertexShaderSource,
+	const char* fragmentShaderSource,
+	QOpenGLBuffer::UsagePattern usagePattern,
+	const std::vector<GLAttributeSpec>& attributeSpecs)
 {
-	this->setMatrix("view", newViewMatrix);
+	if (not this->isInitialized)
+	{
+		this->initializeOpenGLFunctions();
+		this->isInitialized = true;
+		this->program = std::make_unique<gl::ShaderProgram>();
+		gl::buildShaders(&*this->program, vertexShaderSource, fragmentShaderSource);
+		this->program->bind();
+		this->buffer.create();
+		this->buffer.bind();
+		this->buffer.setUsagePattern(usagePattern);
+		this->vertexArrayObject.create();
+		this->vertexArrayObject.bind();
+		for (std::size_t i = 0; i < attributeSpecs.size(); ++i) {
+			const auto& spec = attributeSpecs[i];
+			this->program->enableAttributeArray(i);
+			this->program->setAttributeBuffer(i, spec.type, spec.offset, spec.tuplesize, spec.stride);
+		}
+		this->vertexArrayObject.release();
+		this->buffer.release();
+		this->program->release();
+		gl::checkForGLErrors(nullptr);
+	}
 }
 
-void AbstractBasicShaderProgram::setProjectionMatrix(const glm::mat4& newProjectionMatrix)
-{
-	this->setMatrix("projection", newProjectionMatrix);
-}
-
-void AbstractBasicShaderProgram::setModelMatrix(const glm::mat4& newModelMatrix)
-{
-	this->setMatrix("model", newModelMatrix);
-}
-
-void AbstractBasicShaderProgram::setMatrix(const char* name, const glm::mat4& matrix)
+void BasicShader::setMvpMatrix(const glm::mat4& newMvpMatrix)
 {
 	Q_ASSERT(this->isInitialized);
 	this->program->bind();
-	this->program->setUniformMatrix(name, matrix);
+	this->program->setUniformMatrix("mvp", newMvpMatrix);
 	this->program->release();
-	this->checkForGLErrors();
+	gl::checkForGLErrors(nullptr);
 }
 
-void AbstractBasicShaderProgram::draw()
+void BasicShader::bufferData(const void* data, std::size_t count, std::size_t size)
+{
+	this->buffer.bind();
+	this->buffer.allocate(data, count * size);
+	this->buffer.release();
+	this->vertexCount = count;
+}
+
+void BasicShader::draw(GLenum drawMode)
 {
 	this->program->bind();
 	this->vertexArrayObject.bind();
-	glDrawArrays(this->drawMode(), 0, this->vertexCount());
+	glDrawArrays(drawMode, 0, this->vertexCount);
 	this->vertexArrayObject.release();
 	this->program->release();
-	this->checkForGLErrors();
+	gl::checkForGLErrors(nullptr);
 }
 
-void AbstractBasicShaderProgram::teardown()
+void BasicShader::teardown()
 {
 	this->vertexArrayObject.destroy();
 	this->buffer.destroy();
 	this->program.reset();
 }
-
-void AbstractBasicShaderProgram::checkForGLErrors()
-{
-	gl::checkForGLErrors(qobject_cast<QWidget*>(this->parent()));
-}
--- a/src/gl/basicshaderprogram.h	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/gl/basicshaderprogram.h	Sun Jun 12 23:59:37 2022 +0300
@@ -1,47 +1,36 @@
 #pragma once
 #include "common.h"
 
-/**
- * @brief Base class for basic shader programs
- *
- * A basic program is a collection of a single VAO with a single VBO,
- * a vertex shader and a fragment shader. This program deals with these
- * components, leaving the program-specific details to the subclasses.
- */
-class AbstractBasicShaderProgram : public QObject, protected QOpenGLFunctions
+struct GLAttributeSpec
 {
-	Q_OBJECT
-public:
-	AbstractBasicShaderProgram(QObject* parent = nullptr);
-	~AbstractBasicShaderProgram() = default;
-	void initialize();
-	Q_SLOT void setViewMatrix(const glm::mat4& newViewMatrix);
-	Q_SLOT void setProjectionMatrix(const glm::mat4& newProjectionMatrix);
-	Q_SLOT void setModelMatrix(const glm::mat4& newModelMatrix);
-	void draw();
-	void teardown();
-protected:
-	void setMatrix(const char* name, const glm::mat4& matrix);
-	void checkForGLErrors();
-	/// \returns the source code of the vertex shader
-	virtual const char* vertexShaderSource() const = 0;
-	/// \returns the source code of the fragment shader
-	virtual const char* fragmentShaderSource() const = 0;
-	/// \returns the vertex data for the VBO
-	virtual const void* vertexData() const = 0;
-	/// \returns the size of a single vertex in bytes
-	virtual int vertexSize() const = 0;
-	/// \returns the amount of vertices in the data
-	virtual int vertexCount() const = 0;
-	/// Called during initialization to set up the VAO. Set up your vertex array attributes here.
-	virtual void setupVertexArrays() = 0;
-	// \returns what kind of elements are drawn (GL_QUADS, GL_TRIANGLES, GL_LINES, etc)
-	virtual GLenum drawMode() const = 0;
-	virtual QOpenGLBuffer::UsagePattern usagePattern() const = 0;
+	GLenum type;
+	int offset;
+	int tuplesize;
+	int stride;
+};
+
+//! @brief A collection of a single VAO with a single VBO,
+//! a vertex shader and a fragment shader.
+class BasicShader final : protected QOpenGLFunctions
+{
 	bool isInitialized = false;
 	QOpenGLBuffer buffer;
 	QOpenGLShader vertexShader;
 	QOpenGLShader fragmentShader;
-	std::optional<gl::ShaderProgram> program{std::nullopt};
+	std::unique_ptr<gl::ShaderProgram> program = nullptr;
 	QOpenGLVertexArrayObject vertexArrayObject;
+	std::size_t vertexCount = 0;
+public:
+	BasicShader();
+	~BasicShader();
+	Q_DISABLE_COPY(BasicShader)
+	void initialize(
+		const char* vertexShaderSource,
+		const char* fragmentShaderSource,
+		QOpenGLBuffer::UsagePattern usagePattern,
+		const std::vector<GLAttributeSpec>& attributeSpecs);
+	void setMvpMatrix(const glm::mat4& newMvpMatrix);
+	void bufferData(const void* data, std::size_t count, std::size_t size);
+	void draw(GLenum drawMode);
+	void teardown();
 };
--- a/src/gl/common.h	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/gl/common.h	Sun Jun 12 23:59:37 2022 +0300
@@ -29,6 +29,15 @@
 #include "colors.h"
 #include "model.h"
 
+class RenderLayer
+{
+public:
+	virtual void initializeGL(){}
+	virtual void paintGL(){}
+	virtual void overpaint(QPainter*){}
+	virtual void mvpMatrixChanged(const glm::mat4& mvpMatrix) = 0;
+};
+
 namespace gl
 {
 	class ShaderProgram;
--- a/src/gl/partrenderer.cpp	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/gl/partrenderer.cpp	Sun Jun 12 23:59:37 2022 +0300
@@ -46,6 +46,18 @@
 		this->needBuild = true;
 	});
 	connect(model, &Model::rowsRemoved, [&]{ this->needBuild = true; });
+	const auto updateLayerMvpMatrix = [this]{
+		const glm::mat4 newMvpMatrix = this->projectionMatrix * this->viewMatrix * this->modelMatrix;
+		for (RenderLayer* layer : this->activeRenderLayers) {
+			layer->mvpMatrixChanged(newMvpMatrix);
+		}
+		for (RenderLayer* layer : this->inactiveRenderLayers) {
+			layer->mvpMatrixChanged(newMvpMatrix);
+		}
+	};
+	connect(this, &PartRenderer::modelMatrixChanged, updateLayerMvpMatrix);
+	connect(this, &PartRenderer::viewMatrixChanged, updateLayerMvpMatrix);
+	connect(this, &PartRenderer::projectionMatrixChanged, updateLayerMvpMatrix);
 }
 
 PartRenderer::~PartRenderer()
@@ -69,6 +81,12 @@
 		abort();
 	}
 	gl::initializeModelShaders(&this->shaders);
+	for (RenderLayer* layer : this->activeRenderLayers) {
+		layer->initializeGL();
+	}
+	for (RenderLayer* layer : this->inactiveRenderLayers) {
+		layer->initializeGL();
+	}
 	connect(this->model, &Model::dataChanged, this, &PartRenderer::build);
 	this->initialized = true;
 	this->modelQuaternion = glm::angleAxis(glm::radians(30.0f), glm::vec3{-1, 0, 0});
@@ -111,6 +129,9 @@
 	glEnable(GL_DEPTH_TEST);
 	glShadeModel(GL_SMOOTH);
 	this->renderScene();
+	for (RenderLayer* layer : this->activeRenderLayers) {
+		layer->paintGL();
+	}
 }
 
 void PartRenderer::renderScene()
@@ -296,6 +317,23 @@
 	this->update();
 }
 
+void PartRenderer::addRenderLayer(RenderLayer* layer)
+{
+	this->activeRenderLayers.push_back(layer);
+	this->update();
+}
+
+void PartRenderer::setLayerEnabled(RenderLayer* layer, bool enabled)
+{
+	auto& from = enabled ? this->inactiveRenderLayers : this->activeRenderLayers;
+	auto& to = enabled ? this->activeRenderLayers : this->inactiveRenderLayers;
+	auto it = std::find(from.begin(), from.end(), layer);
+	if (it != from.end()) {
+		from.erase(it);
+		to.push_back(layer);
+	}
+}
+
 /**
  * @brief Converts the specified on the screen into the 3D world. The point is unprojected twice into 3D and the
  * intersection of the resulting line with the specified plane is returned. If the intersection point lies behind
--- a/src/gl/partrenderer.h	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/gl/partrenderer.h	Sun Jun 12 23:59:37 2022 +0300
@@ -18,6 +18,8 @@
 	~PartRenderer() override;
 	void setRenderPreferences(const gl::RenderPreferences& newPreferences);
 	ModelId getHighlightedObject() const;
+	void addRenderLayer(RenderLayer* layer);
+	void setLayerEnabled(RenderLayer* layer, bool enabled);
 protected:
 	ModelId pick(QPoint where);
 	void initializeGL() override;
@@ -58,4 +60,6 @@
 	bool needBuild = true;
 	void renderVao(const gl::ArrayClass arrayClass);
 	void checkForGLErrors();
+	std::vector<RenderLayer*> activeRenderLayers;
+	std::vector<RenderLayer*> inactiveRenderLayers;
 };
--- a/src/main.cpp	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/main.cpp	Sun Jun 12 23:59:37 2022 +0300
@@ -7,7 +7,8 @@
 #include "mainwindow.h"
 #include "ui_mainwindow.h"
 #include "version.h"
-#include "ui/canvas.h"
+#include "gl/axesprogram.h"
+#include "gl/partrenderer.h"
 #include "document.h"
 #include "settingseditor/settingseditor.h"
 #include "widgets/colorselectdialog.h"
@@ -31,6 +32,19 @@
 	}
 };
 
+class ModelData : public QObject
+{
+	Q_OBJECT
+public:
+	ModelData(QObject* parent) : QObject {parent} {}
+	std::unique_ptr<PartRenderer> canvas;
+	std::unique_ptr<QItemSelectionModel> itemSelectionModel;
+	std::unique_ptr<EditTools> tools;
+	std::unique_ptr<AxesLayer> axesLayer;
+	Model* model;
+};
+#include "main.moc"
+
 static void doQtRegistrations()
 {
 	QCoreApplication::setApplicationName(::appName);
@@ -51,18 +65,6 @@
 	}
 };
 
-class ModelData : public QObject
-{
-	Q_OBJECT
-public:
-	ModelData(QObject* parent) : QObject {parent} {}
-	std::unique_ptr<Canvas> canvas;
-	std::unique_ptr<QItemSelectionModel> itemSelectionModel;
-	std::unique_ptr<EditTools> tools;
-	Model* model;
-};
-#include "main.moc"
-
 static constexpr MemberData<Ui_MainWindow, QAction*, gl::RenderStyle> renderStyleButtons[] = {
 	{ offsetof(Ui_MainWindow, actionRenderStyleNormal), gl::RenderStyle::Normal },
 	{ offsetof(Ui_MainWindow, actionRenderStyleBfc), gl::RenderStyle::BfcRedGreen },
@@ -236,6 +238,7 @@
 	forModel(documents, [&renderPreferences](const void*, const ModelData* data){
 		if (data->canvas != nullptr) {
 			data->canvas->setRenderPreferences(*renderPreferences);
+			data->canvas->setLayerEnabled(data->axesLayer.get(), renderPreferences->drawAxes);
 		}
 	});
 	for (auto data : ::renderStyleButtons) {
@@ -391,13 +394,18 @@
 		if (model != nullptr) {
 			ModelData* data = new ModelData(&documents);
 			data->tools = std::make_unique<EditTools>(model, colorTable);
-			data->canvas = std::make_unique<Canvas>(model, data->tools.get(), &documents, colorTable);
+			data->canvas = std::make_unique<PartRenderer>(model, &documents, colorTable);
 			data->itemSelectionModel = std::make_unique<QItemSelectionModel>(model);
+			data->axesLayer = std::make_unique<AxesLayer>();
 			data->model = model;
+			data->canvas->addRenderLayer(data->axesLayer.get());
+			data->canvas->setLayerEnabled(data->axesLayer.get(), settings.drawAxes());
+			documents.setModelPayload(modelId, data);
 			QObject::connect(
 				data->tools.get(),
 				&EditTools::modelAction,
 				std::bind(executeAction, model, std::placeholders::_1));
+#if 0
 			QObject::connect(data->itemSelectionModel.get(), &QItemSelectionModel::selectionChanged,
 				[modelId, &documents](
 				const QItemSelection& selected,
@@ -415,6 +423,7 @@
 					data->canvas->handleSelectionChange(resolve(selected), resolve(deselected));
 				}
 			});
+#endif
 			data->canvas->setRenderPreferences(renderPreferences);
 			QObject::connect(
 				data->tools.get(),
@@ -451,11 +460,13 @@
 		}
 	});
 	QObject::connect(ui.actionQuit, &QAction::triggered, &mainWindow, &QMainWindow::close);
+#if 0
 	QObject::connect(ui.actionAdjustGridToView, &QAction::triggered, [&]{
 		if (ModelData* data = currentModelData(&ui, &documents)) {
 			adjustGridToView(data->canvas.get());
 		}
 	});
+#endif
 	QObject::connect(ui.actionClose, &QAction::triggered, [&ui, &documents]{
 		if (ModelData* data = currentModelData(&ui, &documents)) {
 			// TODO
--- a/src/mainwindow.h	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/mainwindow.h	Sun Jun 12 23:59:37 2022 +0300
@@ -25,4 +25,3 @@
 #include "documentmanager.h"
 #include "libraries.h"
 #include "uiutilities.h"
-#include "ui/canvas.h"
--- a/src/ui/canvas.h	Sun Jun 12 20:47:04 2022 +0300
+++ b/src/ui/canvas.h	Sun Jun 12 23:59:37 2022 +0300
@@ -9,22 +9,6 @@
 
 class EditTools;
 
-enum EditingMode
-{
-	SelectMode,
-	DrawMode
-};
-
-Q_DECLARE_METATYPE(EditingMode);
-
-struct DrawState
-{
-	std::vector<glm::vec3> polygon;
-	std::vector<glm::vec3> previewPolygon;
-	glm::vec3 previewPoint;
-	bool isconcave = false;
-	EditingMode mode = SelectMode;
-};
 class Canvas : public PartRenderer
 {
 	Q_OBJECT

mercurial