added vertex rendering

Fri, 27 Apr 2018 16:27:14 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Fri, 27 Apr 2018 16:27:14 +0300
changeset 1385
2f18c0da749d
parent 1384
4c134708be05

added vertex rendering

CMakeLists.txt file | annotate | diff | comparison | revisions
src/canvas.cpp file | annotate | diff | comparison | revisions
src/canvas.h file | annotate | diff | comparison | revisions
src/editmodes/selectMode.cpp file | annotate | diff | comparison | revisions
src/glShared.h file | annotate | diff | comparison | revisions
src/glcompiler.cpp file | annotate | diff | comparison | revisions
src/glcompiler.h file | annotate | diff | comparison | revisions
src/glrenderer.cpp file | annotate | diff | comparison | revisions
src/glrenderer.h file | annotate | diff | comparison | revisions
src/linetypes/modelobject.h file | annotate | diff | comparison | revisions
src/vertexcompiler.cpp file | annotate | diff | comparison | revisions
src/vertexcompiler.h file | annotate | diff | comparison | revisions
src/vertexselection.cpp file | annotate | diff | comparison | revisions
src/vertexselection.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Wed Apr 25 18:55:15 2018 +0300
+++ b/CMakeLists.txt	Fri Apr 27 16:27:14 2018 +0300
@@ -58,6 +58,8 @@
 	src/serializer.cpp
 	src/ringFinder.cpp
 	src/version.cpp
+	src/vertexcompiler.cpp
+	src/vertexselection.cpp
 	src/algorithms/geometry.cpp
 	src/algorithms/invert.cpp
 	src/dialogs/colorselector.cpp
@@ -127,6 +129,8 @@
 	src/ringFinder.h
 	src/serializer.h
 	src/version.h
+	src/vertexcompiler.h
+	src/vertexselection.h
 	src/algorithms/geometry.h
 	src/algorithms/invert.h
 	src/dialogs/colorselector.h
--- a/src/canvas.cpp	Wed Apr 25 18:55:15 2018 +0300
+++ b/src/canvas.cpp	Fri Apr 27 16:27:14 2018 +0300
@@ -21,16 +21,19 @@
 #include "grid.h"
 #include "lddocument.h"
 #include "primitives.h"
+#include "vertexcompiler.h"
 #include "algorithms/geometry.h"
 #include "generics/ring.h"
 
 Canvas::Canvas(LDDocument* document, QWidget* parent) :
     GLRenderer {document, parent},
     m_document {*document},
+	m_vertexCompiler {new VertexCompiler {document, nullptr, this}},
     m_currentEditMode {AbstractEditMode::createByType (this, EditModeType::Select)} {}
 
 Canvas::~Canvas()
 {
+	delete this->m_vertexCompiler;
 	delete m_currentEditMode;
 }
 
@@ -61,6 +64,36 @@
 	}
 }
 
+void Canvas::initializeGL()
+{
+	GLRenderer::initializeGL();
+	this->m_vertexCompiler->initialize();
+}
+
+void Canvas::drawScene()
+{
+	GLRenderer::drawScene();
+
+	if (not isDrawingSelectionScene())
+	{
+		GLuint surfacesVbo = this->m_vertexCompiler->vbo(VertexCompiler::Surfaces);
+		GLuint colorsVbo = this->m_vertexCompiler->vbo(VertexCompiler::Colors);
+		GLuint normalsVbo = this->m_vertexCompiler->vbo(VertexCompiler::Normals);
+		GLsizei count = this->m_vertexCompiler->vboSize(VertexCompiler::Surfaces) / 3;
+
+		if (count > 0)
+		{
+			glBindBuffer(GL_ARRAY_BUFFER, surfacesVbo);
+			glVertexPointer(3, GL_FLOAT, 0, nullptr);
+			glBindBuffer(GL_ARRAY_BUFFER, colorsVbo);
+			glColorPointer(4, GL_FLOAT, 0, nullptr);
+			glBindBuffer(GL_ARRAY_BUFFER, normalsVbo);
+			glNormalPointer(GL_FLOAT, 0, nullptr);
+			glDrawArrays(GL_TRIANGLES, 0, count);
+		}
+	}
+}
+
 /*
  * Assuming we're currently viewing from a fixed camera, draw a backdrop into it. Currently this means drawing the grid.
  */
--- a/src/canvas.h	Wed Apr 25 18:55:15 2018 +0300
+++ b/src/canvas.h	Fri Apr 27 16:27:14 2018 +0300
@@ -47,8 +47,10 @@
 	void contextMenuEvent(QContextMenuEvent* event) override;
 	void dragEnterEvent(QDragEnterEvent* event) override;
 	void drawFixedCameraBackdrop() override;
+	void drawScene() override;
 	void dropEvent(QDropEvent* event) override;
 	bool freeCameraAllowed() const override;
+	void initializeGL() override;
 	void keyReleaseEvent(QKeyEvent* event) override;
 	void mouseDoubleClickEvent(QMouseEvent* event) override;
 	void mouseMoveEvent(QMouseEvent* event) override;
@@ -58,6 +60,7 @@
 
 private:
 	LDDocument& m_document;
+	class VertexCompiler* m_vertexCompiler;
 	AbstractEditMode* m_currentEditMode = nullptr;
 	Vertex m_position3D;
 	double m_depthValues[6] = {0};
--- a/src/editmodes/selectMode.cpp	Wed Apr 25 18:55:15 2018 +0300
+++ b/src/editmodes/selectMode.cpp	Fri Apr 27 16:27:14 2018 +0300
@@ -103,6 +103,7 @@
 	else
 		mode = QItemSelectionModel::ClearAndSelect;
 
+#warning fix crash here
 	model->select(renderer()->pick(area), mode);
 }
 
--- a/src/glShared.h	Wed Apr 25 18:55:15 2018 +0300
+++ b/src/glShared.h	Fri Apr 27 16:27:14 2018 +0300
@@ -78,6 +78,7 @@
 	BfcFrontColors,
 	BfcBackColors,
 	RandomColors,
+	BlackColors,
 	Normals,
 	InvertedNormals,
 	_End
--- a/src/glcompiler.cpp	Wed Apr 25 18:55:15 2018 +0300
+++ b/src/glcompiler.cpp	Fri Apr 27 16:27:14 2018 +0300
@@ -168,6 +168,10 @@
 		// Use the constant red color for BFC back colors
 		return {208, 64, 64};
 
+	case VboSubclass::BlackColors:
+		// Use a constant black color for black colors.
+		return Qt::black;
+
 	case VboSubclass::PickColors:
 		// For the picking scene, use unique picking colors provided by the model.
 		return m_renderer->model()->pickingColorForObject(polygonOwnerIndex);
--- a/src/glcompiler.h	Wed Apr 25 18:55:15 2018 +0300
+++ b/src/glcompiler.h	Fri Apr 27 16:27:14 2018 +0300
@@ -67,7 +67,7 @@
 	Q_SLOT void compileObject (const QModelIndex &index);
 	QColor getColorForPolygon(
 		LDPolygon& poly,
-		const QModelIndex& polygonOwnerIndex,
+		const QModelIndex& polygonOwnereIndex,
 		VboSubclass complement
 	);
 	QColor indexColorForID (qint32 id) const;
--- a/src/glrenderer.cpp	Wed Apr 25 18:55:15 2018 +0300
+++ b/src/glrenderer.cpp	Fri Apr 27 16:27:14 2018 +0300
@@ -356,6 +356,68 @@
 		camera.rendererResized(width, height);
 }
 
+void GLRenderer::drawSelectionScene(VboSubclass subclass)
+{
+	this->drawVbos(VboClass::Triangles, subclass);
+	this->drawVbos(VboClass::Quads, subclass);
+	this->drawVbos(VboClass::Lines, subclass);
+	this->drawVbos(VboClass::ConditionalLines, subclass);
+}
+
+void GLRenderer::drawScene()
+{
+	if (m_isDrawingSelectionScene)
+	{
+		this->drawSelectionScene();
+	}
+	else
+	{
+		if (config::bfcRedGreenView())
+		{
+			glEnable(GL_CULL_FACE);
+			glCullFace(GL_BACK);
+			drawVbos(VboClass::Triangles, VboSubclass::BfcFrontColors);
+			drawVbos(VboClass::Quads, VboSubclass::BfcFrontColors);
+			glCullFace(GL_FRONT);
+			drawVbos(VboClass::Triangles, VboSubclass::BfcBackColors);
+			drawVbos(VboClass::Quads, VboSubclass::BfcBackColors);
+			glDisable(GL_CULL_FACE);
+		}
+		else
+		{
+			VboSubclass colors;
+
+			if (config::randomColors())
+				colors = VboSubclass::RandomColors;
+			else
+				colors = VboSubclass::RegularColors;
+
+			drawVbos(VboClass::Triangles, colors);
+			drawVbos(VboClass::Quads, colors);
+		}
+
+		drawVbos(VboClass::Lines, VboSubclass::RegularColors);
+
+		if (config::useLineStipple())
+			glEnable(GL_LINE_STIPPLE);
+
+		drawVbos(VboClass::ConditionalLines, VboSubclass::RegularColors);
+		glDisable(GL_LINE_STIPPLE);
+
+		if (config::drawAxes())
+		{
+			glDisableClientState(GL_NORMAL_ARRAY);
+			glBindBuffer(GL_ARRAY_BUFFER, m_axesVbo);
+			glVertexPointer(3, GL_FLOAT, 0, NULL);
+			glBindBuffer(GL_ARRAY_BUFFER, m_axesVbo);
+			glColorPointer(3, GL_FLOAT, 0, NULL);
+			glDrawArrays(GL_LINES, 0, 6);
+			glEnableClientState(GL_NORMAL_ARRAY);
+			CHECK_GL_ERROR();
+		}
+	}
+}
+
 // =============================================================================
 //
 void GLRenderer::drawGLScene()
@@ -400,61 +462,7 @@
 	glEnableClientState (GL_NORMAL_ARRAY);
 	glEnableClientState (GL_VERTEX_ARRAY);
 	glEnableClientState (GL_COLOR_ARRAY);
-
-	if (m_isDrawingSelectionScene)
-	{
-		drawVbos (VboClass::Triangles, VboSubclass::PickColors);
-		drawVbos (VboClass::Quads, VboSubclass::PickColors);
-		drawVbos (VboClass::Lines, VboSubclass::PickColors);
-		drawVbos (VboClass::ConditionalLines, VboSubclass::PickColors);
-	}
-	else
-	{
-		if (config::bfcRedGreenView())
-		{
-			glEnable (GL_CULL_FACE);
-			glCullFace (GL_BACK);
-			drawVbos (VboClass::Triangles, VboSubclass::BfcFrontColors);
-			drawVbos (VboClass::Quads, VboSubclass::BfcFrontColors);
-			glCullFace (GL_FRONT);
-			drawVbos (VboClass::Triangles, VboSubclass::BfcBackColors);
-			drawVbos (VboClass::Quads, VboSubclass::BfcBackColors);
-			glDisable (GL_CULL_FACE);
-		}
-		else
-		{
-			VboSubclass colors;
-
-			if (config::randomColors())
-				colors = VboSubclass::RandomColors;
-			else
-				colors = VboSubclass::RegularColors;
-
-			drawVbos (VboClass::Triangles, colors);
-			drawVbos (VboClass::Quads, colors);
-		}
-
-		drawVbos (VboClass::Lines, VboSubclass::RegularColors);
-
-		if (config::useLineStipple())
-			glEnable (GL_LINE_STIPPLE);
-
-		drawVbos (VboClass::ConditionalLines, VboSubclass::RegularColors);
-		glDisable (GL_LINE_STIPPLE);
-
-		if (config::drawAxes())
-		{
-			glDisableClientState (GL_NORMAL_ARRAY);
-			glBindBuffer (GL_ARRAY_BUFFER, m_axesVbo);
-			glVertexPointer (3, GL_FLOAT, 0, NULL);
-			glBindBuffer (GL_ARRAY_BUFFER, m_axesVbo);
-			glColorPointer (3, GL_FLOAT, 0, NULL);
-			glDrawArrays (GL_LINES, 0, 6);
-			glEnableClientState (GL_NORMAL_ARRAY);
-			CHECK_GL_ERROR();
-		}
-	}
-
+	this->drawScene();
 	glPopMatrix();
 	glBindBuffer (GL_ARRAY_BUFFER, 0);
 	glDisableClientState (GL_VERTEX_ARRAY);
--- a/src/glrenderer.h	Wed Apr 25 18:55:15 2018 +0300
+++ b/src/glrenderer.h	Fri Apr 27 16:27:14 2018 +0300
@@ -107,6 +107,8 @@
 
 	QColor backgroundColor() const;
 	virtual bool freeCameraAllowed() const;
+	virtual void drawScene();
+	void drawSelectionScene(VboSubclass subclass = VboSubclass::PickColors);
 	bool isDrawingSelectionScene() const;
 	Qt::MouseButtons lastButtons() const;
 	bool mouseHasMoved() const;
--- a/src/linetypes/modelobject.h	Wed Apr 25 18:55:15 2018 +0300
+++ b/src/linetypes/modelobject.h	Fri Apr 27 16:27:14 2018 +0300
@@ -89,6 +89,7 @@
 	static LDObject* newFromType(LDObjectType type);
 
 signals:
+	void aboutToBeModified();
 	void modified(const LDObjectState& before, const LDObjectState& after);
 
 protected:
@@ -233,6 +234,7 @@
 	if (*property != value)
 	{
 		Serializer::Archive before = Serializer::store(this);
+		emit aboutToBeModified();
 		*property = value;
 		emit modified(before, Serializer::store(this));
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vertexcompiler.cpp	Fri Apr 27 16:27:14 2018 +0300
@@ -0,0 +1,267 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 Teemu Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "vertexcompiler.h"
+#include "vertexselection.h"
+#include "model.h"
+
+static const Vertex sphere[] = {
+	{1, 0, 0}, {0.7071, 0.7071, 0}, {0.7071, 0, 0.7071},
+	{0, 0.7071, 0.7071}, {0, 0, 1}, {0.7071, 0, 0.7071},
+	{0.7071, 0.7071, 0}, {0, 0.7071, 0.7071}, {0.7071, 0, 0.7071},
+	{0, 1, 0}, {0, 0.7071, 0.7071}, {0.7071, 0.7071, 0},
+	{0.7071, 0, -0.7071}, {0.7071, 0.7071, 0}, {1, 0, 0},
+	{0.7071, 0, -0.7071}, {0, 0, -1}, {0, 0.7071, -0.7071},
+	{0.7071, 0, -0.7071}, {0, 0.7071, -0.7071}, {0.7071, 0.7071, 0},
+	{0.7071, 0.7071, 0}, {0, 0.7071, -0.7071}, {0, 1, 0},
+	{-0.7071, 0, 0.7071}, {-0.7071, 0.7071, 0}, {-1, 0, 0},
+	{-0.7071, 0, 0.7071}, {0, 0, 1}, {0, 0.7071, 0.7071},
+	{-0.7071, 0, 0.7071}, {0, 0.7071, 0.7071}, {-0.7071, 0.7071, 0},
+	{-0.7071, 0.7071, 0}, {0, 0.7071, 0.7071}, {0, 1, 0},
+	{-1, 0, 0}, {-0.7071, 0.7071, 0}, {-0.7071, 0, -0.7071},
+	{0, 0.7071, -0.7071}, {0, 0, -1}, {-0.7071, 0, -0.7071},
+	{-0.7071, 0.7071, 0}, {0, 0.7071, -0.7071}, {-0.7071, 0, -0.7071},
+	{0, 1, 0}, {0, 0.7071, -0.7071}, {-0.7071, 0.7071, 0},
+	{-0.7071, 0, -0.7071}, {0, 0, -1}, {0, -0.7071, -0.7071},
+	{0, -1, 0}, {0, -0.7071, 0.7071}, {-0.7071, -0.7071, 0},
+	{0.7071, -0.7071, 0}, {0, -0.7071, -0.7071}, {0.7071, 0, -0.7071},
+	{-1, 0, 0}, {-0.7071, -0.7071, 0}, {-0.7071, 0, 0.7071},
+	{-0.7071, -0.7071, 0}, {0, -0.7071, -0.7071}, {0, -1, 0},
+	{0, -1, 0}, {0, -0.7071, -0.7071}, {0.7071, -0.7071, 0},
+	{0.7071, 0, 0.7071}, {0, -0.7071, 0.7071}, {0.7071, -0.7071, 0},
+	{-0.7071, 0, -0.7071}, {-0.7071, -0.7071, 0}, {-1, 0, 0},
+	{1, 0, 0}, {0.7071, -0.7071, 0}, {0.7071, 0, -0.7071},
+	{0.7071, 0, 0.7071}, {0, 0, 1}, {0, -0.7071, 0.7071},
+	{-0.7071, 0, -0.7071}, {0, -0.7071, -0.7071}, {-0.7071, -0.7071, 0},
+	{0.7071, -0.7071, 0}, {0, -0.7071, 0.7071}, {0, -1, 0},
+	{0.7071, 0, 0.7071}, {0.7071, -0.7071, 0}, {1, 0, 0},
+	{-0.7071, -0.7071, 0}, {0, -0.7071, 0.7071}, {-0.7071, 0, 0.7071},
+	{0, -0.7071, -0.7071}, {0, 0, -1}, {0.7071, 0, -0.7071},
+	{0, -0.7071, 0.7071}, {0, 0, 1}, {-0.7071, 0, 0.7071},
+};
+
+static const float sphereSize = 0.5;
+static const QColor sphereColor {192, 192, 255};
+
+VertexCompiler::VertexCompiler(Model* model, VertexSelection* selection, QObject* parent) :
+	QObject {parent},
+	model {model}
+{
+	connect(model, &Model::objectAdded, this, &VertexCompiler::handleNewObject);
+	connect(model, &Model::aboutToRemoveObject, this, &VertexCompiler::handleRemovedObject);
+
+	if (selection != nullptr)
+	{
+		this->connect(
+			selection,
+			&VertexSelection::vertexSelected,
+			this,
+			&VertexCompiler::updateVertex
+		);
+		this->connect(
+			selection,
+			&VertexSelection::vertexDeselected,
+			this,
+			&VertexCompiler::updateVertex
+		);
+	}
+}
+
+VertexCompiler::~VertexCompiler()
+{
+	if (this->initialized)
+	{
+		GLuint buffers[NumVbos];
+
+		for (int i = 0; i < countof(this->vbos); i += 1)
+			buffers[i] = this->vbos[i].buffer;
+
+		this->glDeleteBuffers(countof(buffers), &buffers[0]);
+	}
+}
+
+void VertexCompiler::handleNewObject(const QModelIndex &index)
+{
+	LDObject* object = this->model->lookup(index);
+	this->addVerticesFromObject(object);
+	connect(object, &LDObject::aboutToBeModified, this, &VertexCompiler::handlePreModifiedObject);
+	connect(object, &LDObject::modified, this, &VertexCompiler::handleModifiedObject);
+}
+
+void VertexCompiler::handleRemovedObject(const QModelIndex &index)
+{
+	LDObject* object = this->model->lookup(index);
+	this->removeVerticesFromObject(object);
+}
+
+void VertexCompiler::handlePreModifiedObject()
+{
+	removeVerticesFromObject(qobject_cast<LDObject*>(this->sender()));
+}
+
+void VertexCompiler::handleModifiedObject()
+{
+	addVerticesFromObject(qobject_cast<LDObject*>(this->sender()));
+}
+
+void VertexCompiler::initialize()
+{
+	if (not this->initialized)
+	{
+		this->initializeOpenGLFunctions();
+		this->initialized = true;
+		GLuint buffers[NumVbos];
+		this->glGenBuffers(countof(buffers), &buffers[0]);
+
+		for (int i = 0; i < countof(this->vbos); i += 1)
+			this->vbos[i].buffer = buffers[i];
+	}
+}
+
+void VertexCompiler::addVerticesFromObject(LDObject* object)
+{
+	for (int i = 0; i < object->numPolygonVertices(); i += 1)
+		this->addVertex(object->vertex(i));
+
+	this->needCompile = true;
+}
+
+void VertexCompiler::removeVerticesFromObject(LDObject* object)
+{
+	for (int i = 0; i < object->numPolygonVertices(); i += 1)
+		this->removeVertex(object->vertex(i));
+
+	this->needCompile = true;
+}
+
+void VertexCompiler::addVertex(const Vertex& vertex)
+{
+	auto iterator = this->vertices.find(vertex);
+
+	if (iterator == this->vertices.end())
+		this->vertices.insert(vertex, 1);
+	else
+		iterator.value() += 1;
+}
+
+void VertexCompiler::removeVertex(const Vertex& vertex)
+{
+	auto iterator = this->vertices.find(vertex);
+
+	if (iterator != this->vertices.end())
+	{
+		if (iterator.value() > 1)
+			iterator.value() -= 1;
+		else
+			this->vertices.erase(iterator);
+	}
+}
+
+void VertexCompiler::updateVertex(const Vertex&)
+{
+	this->needCompile = true;
+}
+
+/*
+ * Returns the GL buffer for the given vbo.
+ */
+GLuint VertexCompiler::vbo(Vbo vboIndex)
+{
+	if (this->needCompile)
+	{
+		this->compile();
+		this->upload();
+		this->needCompile = false;
+	}
+
+	return this->vbos[vboIndex].buffer;
+}
+
+/*
+ * Returns the size of the given vbo.
+ */
+size_t VertexCompiler::vboSize(Vbo vboIndex) const
+{
+	return this->vbos[vboIndex].data.size();
+}
+
+/*
+ * Clears the vertex scene.
+ */
+void VertexCompiler::clear()
+{
+	for (auto& vbo : this->vbos)
+		vbo.data.clear();
+}
+
+/*
+ * Builds the vertex scene
+ */
+void VertexCompiler::compile()
+{
+	this->clear();
+	QMapIterator<Vertex, unsigned int> iterator {this->vertices};
+
+	while (iterator.hasNext())
+	{
+		iterator.next();
+		this->compileVertex(iterator.key());
+	}
+}
+
+/*
+ * Adds a little sphere into the scene to represent the given vertex.
+ */
+void VertexCompiler::compileVertex(const Vertex& vertex)
+{
+	for (int i = 0; i < countof(::sphere); i += 1)
+	{
+		// Y and Z inverted like the rest of the scene
+		Vertex spherePoint = {
+			::sphere[i][X] * ::sphereSize + vertex.x,
+			::sphere[i][Y] * ::sphereSize - vertex.y,
+			::sphere[i][Z] * ::sphereSize - vertex.z
+		};
+		this->vbos[Surfaces].data << spherePoint.x << spherePoint.y << spherePoint.z;
+		// The points of the sphere are position vectors, which in this case are also unit normals.
+		this->vbos[Normals].data << ::sphere[i][X] << ::sphere[i][Y] << ::sphere[i][Z];
+		this->vbos[Colors].data
+			<< ::sphereColor.redF()
+			<< ::sphereColor.greenF()
+			<< ::sphereColor.blueF()
+			<< ::sphereColor.alphaF();
+	}
+}
+
+/*
+ * Uploads VBO data to the graphics card.
+ */
+void VertexCompiler::upload()
+{
+	for (const auto& vbo : this->vbos)
+	{
+		glBindBuffer(GL_ARRAY_BUFFER, vbo.buffer);
+		glBufferData(
+			GL_ARRAY_BUFFER,
+			countof(vbo.data) * sizeof(GLfloat),
+			vbo.data.constData(),
+			GL_STATIC_DRAW
+		);
+	}
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vertexcompiler.h	Fri Apr 27 16:27:14 2018 +0300
@@ -0,0 +1,69 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 Teemu Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include "main.h"
+#include "glShared.h"
+
+class Model;
+class VertexSelection;
+
+/*
+ * Compiles a scene that contains a small sphere for every vertex.
+ */
+class VertexCompiler : public QObject, protected QOpenGLFunctions
+{
+	Q_OBJECT
+
+public:
+	enum Vbo { Surfaces, Normals, Colors, PickColors, VboCount };
+
+	VertexCompiler(Model* model, VertexSelection* selection, QObject* parent = nullptr);
+	~VertexCompiler();
+
+	void initialize();
+	GLuint vbo(Vbo vboIndex);
+	size_t vboSize(Vbo vboIndex) const;
+
+private:
+	bool initialized = false;
+	bool needCompile = true;
+	struct
+	{
+		GLuint buffer;
+		QVector<float> data;
+	} vbos[VboCount];
+	QMap<Vertex, unsigned int> vertices;
+	Model* model;
+
+	void addVertex(const Vertex& vertex);
+	void addVerticesFromObject(LDObject* object);
+	void clear();
+	void compile();
+	void compileVertex(const Vertex& vertex);
+	void removeVertex(const Vertex& vertex);
+	void removeVerticesFromObject(LDObject* object);
+	void upload();
+
+private slots:
+	void handleNewObject(const QModelIndex& index);
+	void handlePreModifiedObject();
+	void handleRemovedObject(const QModelIndex& index);
+	void handleModifiedObject();
+	void updateVertex(const Vertex& vertex);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vertexselection.cpp	Fri Apr 27 16:27:14 2018 +0300
@@ -0,0 +1,41 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 Teemu Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "vertexselection.h"
+
+VertexSelection::VertexSelection(QObject *parent) : QObject(parent) {}
+
+void VertexSelection::select(const Vertex& vertex)
+{
+	if (not this->selectedVertices.contains(vertex))
+	{
+		this->selectedVertices.insert(vertex);
+		emit this->vertexSelected(vertex);
+	}
+}
+
+void VertexSelection::deselect(const Vertex& vertex)
+{
+	auto iterator = this->selectedVertices.find(vertex);
+
+	if (iterator != this->selectedVertices.end())
+	{
+		this->selectedVertices.erase(iterator);
+		emit this->vertexDeselected(vertex);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vertexselection.h	Fri Apr 27 16:27:14 2018 +0300
@@ -0,0 +1,37 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 Teemu Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include "main.h"
+
+class VertexSelection : public QObject
+{
+	Q_OBJECT
+public:
+	VertexSelection(QObject* parent = nullptr);
+
+	void select(const Vertex& vertex);
+	void deselect(const Vertex& vertex);
+
+signals:
+	void vertexSelected(const Vertex& vertex);
+	void vertexDeselected(const Vertex& vertex);
+
+private:
+	QSet<Vertex> selectedVertices;
+};

mercurial