More refactor and renaming

Tue, 11 Apr 2023 11:11:28 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Tue, 11 Apr 2023 11:11:28 +0300
changeset 374
75efc3ba5a56
parent 373
e34d6a30b96d
child 375
21a5ecbe34e4

More refactor and renaming
Added a test function that makes recolors stuff red

src/documentmanager.cpp file | annotate | diff | comparison | revisions
src/geometry.h file | annotate | diff | comparison | revisions
src/gl/compiler.cpp file | annotate | diff | comparison | revisions
src/invert.cpp file | annotate | diff | comparison | revisions
src/invert.h file | annotate | diff | comparison | revisions
src/layers/edittools.cpp file | annotate | diff | comparison | revisions
src/layers/edittools.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/mainwindow.ui file | annotate | diff | comparison | revisions
src/model.cpp file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
src/polygoncache.cpp file | annotate | diff | comparison | revisions
src/triangulate.cpp file | annotate | diff | comparison | revisions
src/vertexmap.cpp file | annotate | diff | comparison | revisions
--- a/src/documentmanager.cpp	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/documentmanager.cpp	Tue Apr 11 11:11:28 2023 +0300
@@ -364,7 +364,7 @@
 	for (const QString& line : model->toPlainText().split("\n")) {
 		const opt<ParsedLine> parsed = parse(line);
 		if (parsed.has_value() and std::holds_alternative<LineType1>(*parsed)) {
-			result.insert(std::get<LineType1>(*parsed).value.name);
+			result.insert(std::get<LineType1>(*parsed).value.element.name);
 		}
 	}
 	return result;
--- a/src/geometry.h	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/geometry.h	Tue Apr 11 11:11:28 2023 +0300
@@ -57,18 +57,6 @@
 	glm::vec2 p1, p2;
 };
 
-// get polygon type from amount of points
-template<int N>
-struct PolygonType {};
-template<>
-struct PolygonType<2> { using type = LineSegment; };
-template<>
-struct PolygonType<3> { using type = Triangle; };
-template<>
-struct PolygonType<4> { using type = Quadrilateral; };
-template<int N>
-using Polygon = typename PolygonType<N>::type;
-
 /**
  * @brief Computes a line from two points
  * @param point_1
@@ -131,11 +119,6 @@
 };
 unscaled_matrix unscale_matrix(const glm::mat4& matrix);
 
-struct NPolygon
-{
-	std::vector<glm::vec3> points;
-};
-
 inline constexpr bool isclose(const glm::vec3& a, const glm::vec3& b)
 {
 	return qFuzzyCompare(a.x, b.x)
--- a/src/gl/compiler.cpp	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/gl/compiler.cpp	Tue Apr 11 11:11:28 2023 +0300
@@ -114,33 +114,34 @@
 )";
 
 template<typename Fn>
-constexpr void pointsToRender(const PolygonElement& element, Fn func)
+constexpr void pointsToRender(const PlainPolygonElement& element, Fn func)
 {
-	visitPolygon<void>(
-		[&func](const LineSegment& edge)
-		{
-			func(edge.p1, glm::vec3{});
-			func(edge.p2, glm::vec3{});
-		},
-		[&func](const Triangle& tri)
-		{
-			func(tri.p1, normalVector({tri.p3, tri.p1, tri.p2}));
-			func(tri.p2, normalVector({tri.p1, tri.p2, tri.p3}));
-			func(tri.p3, normalVector({tri.p2, tri.p3, tri.p1}));
-		},
-		[&func](const Quadrilateral& quad)
-		{
-			func(quad.p1, normalVector({quad.p4, quad.p1, quad.p2}));
-			func(quad.p2, normalVector({quad.p1, quad.p2, quad.p3}));
-			func(quad.p3, normalVector({quad.p2, quad.p3, quad.p4}));
-			func(quad.p4, normalVector({quad.p3, quad.p4, quad.p1}));
-		},
-		[&func](const ConditionalEdge& cedge)
-		{
-			func(cedge.p1, glm::vec3{});
-			func(cedge.p2, glm::vec3{});
-		},
-		element);
+	if (const LineSegment* edge = std::get_if<LineSegment>(&element))
+	{
+		func(edge->p1, glm::vec3{});
+		func(edge->p2, glm::vec3{});
+	}
+	else if (std::holds_alternative<Triangle>(element))
+	{
+		const Triangle& tri = std::get<Triangle>(element);
+		func(tri.p1, normalVector({tri.p3, tri.p1, tri.p2}));
+		func(tri.p2, normalVector(tri));
+		func(tri.p3, normalVector({tri.p2, tri.p3, tri.p1}));
+	}
+	else if (std::holds_alternative<Quadrilateral>(element))
+	{
+		const Quadrilateral& quad = std::get<Quadrilateral>(element);
+		func(quad.p1, normalVector({quad.p4, quad.p1, quad.p2}));
+		func(quad.p2, normalVector({quad.p1, quad.p2, quad.p3}));
+		func(quad.p3, normalVector({quad.p2, quad.p3, quad.p4}));
+		func(quad.p4, normalVector({quad.p3, quad.p4, quad.p1}));
+	}
+	else
+	{
+		const ConditionalEdge& conditional_edge = std::get<ConditionalEdge>(element);
+		func(conditional_edge.p1, glm::vec3{});
+		func(conditional_edge.p2, glm::vec3{});
+	}
 }
 
 void gl::buildShaders(
@@ -211,7 +212,7 @@
 	}
 }
 
-static constexpr gl::ArrayClass classifyPolygon(const PolygonElement& element)
+static constexpr gl::ArrayClass classifyPolygon(const PlainPolygonElement& element)
 {
 	return visitPolygon<gl::ArrayClass>(
 		[](const LineSegment&) { return gl::ArrayClass::Lines; },
@@ -267,7 +268,7 @@
 	{
 		visitPoints([&result](const glm::vec3& p) {
 			addPointToBox(result, p);
-		}, polygon);
+		}, polygon.element);
 	});
 	return result;
 }
@@ -287,10 +288,10 @@
 	}
 	iterateModelPolygons(model, context, [&](const WithId<PolygonElement>& polygon)
 	{
-		const int index = static_cast<int>(classifyPolygon(polygon));
+		const int index = static_cast<int>(classifyPolygon(polygon.element));
 		std::vector<gl::ModelShaders::Vertex>& vertexBuffer = shaders->shaderObjects[index].cachedData;
 		const QColor color = getColorForPolygon(polygon, preferences, colorTable);
-		pointsToRender(polygon, [&](const glm::vec3& point, const glm::vec3& normal){
+		pointsToRender(polygon.element, [&](const glm::vec3& point, const glm::vec3& normal){
 			gl::ModelShaders::Vertex& vertex = vertexBuffer.emplace_back();
 			vertex.position = point;
 			vertex.normal = normal;
--- a/src/invert.cpp	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/invert.cpp	Tue Apr 11 11:11:28 2023 +0300
@@ -36,7 +36,7 @@
 /*
  * Inverts the winding of a polygon.
  */
-void gl::invert(PolygonElement& polygon)
+void gl::invert(PlainPolygonElement& polygon)
 {
 	visitPolygon<void>(
 		[](LineSegment&) {},
--- a/src/invert.h	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/invert.h	Tue Apr 11 11:11:28 2023 +0300
@@ -51,7 +51,7 @@
 
 namespace gl
 {
-	void invert(PolygonElement &polygon);
+	void invert(PlainPolygonElement& polygon);
 }
 
 using gl::invert;
--- a/src/layers/edittools.cpp	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/layers/edittools.cpp	Tue Apr 11 11:11:28 2023 +0300
@@ -35,15 +35,15 @@
 {
 }
 
-void EditTools::setEditMode(EditingMode newMode)
+void EditTools::setEditMode(editing_mode_e newMode)
 {
 	this->mode = newMode;
 	switch (this->mode) {
-	case SelectMode:
+	case editing_mode_e::select:
 		Q_EMIT this->suggestCursor(Qt::ArrowCursor);
 		break;
-	case DrawMode:
-	case CircleMode:
+	case editing_mode_e::draw:
+	case editing_mode_e::circle:
 		Q_EMIT this->suggestCursor(Qt::CrossCursor);
 		break;
 	}
@@ -108,18 +108,18 @@
 	std::vector<std::vector<glm::vec3>> result;
 	if (const AppendToModel* append = std::get_if<AppendToModel>(&action)) {
 		const ModelElement& newElement = append->newElement;
-		if (const LineSegment* seg = std::get_if<Colored<LineSegment>>(&newElement)) {
-			result.push_back({seg->p1, seg->p2});
+		if (const Colored<LineSegment>* seg = std::get_if<Colored<LineSegment>>(&newElement)) {
+			result.push_back({seg->element.p1, seg->element.p2});
 		}
-		else if (const Triangle* tri = std::get_if<Colored<Triangle>>(&newElement)) {
-			result.push_back({tri->p1, tri->p2, tri->p3});
+		else if (const Colored<Triangle>* tri = std::get_if<Colored<Triangle>>(&newElement)) {
+			result.push_back({tri->element.p1, tri->element.p2, tri->element.p3});
 		}
-		else if (const Quadrilateral* quad = std::get_if<Colored<Quadrilateral>>(&newElement)) {
-			result.push_back({quad->p1, quad->p2, quad->p3, quad->p4});
+		else if (const Colored<Quadrilateral>* quad = std::get_if<Colored<Quadrilateral>>(&newElement)) {
+			result.push_back({quad->element.p1, quad->element.p2, quad->element.p3, quad->element.p4});
 		}
-		else if (const CircularPrimitive* circ = std::get_if<Colored<CircularPrimitive>>(&newElement)) {
+		else if (const Colored<CircularPrimitive>* circ = std::get_if<Colored<CircularPrimitive>>(&newElement)) {
 			// rasterize the circle down to polygons, and append them to the result.
-			rasterize(*circ, [&](const PlainPolygonElement& poly, const ColorIndex color){
+			rasterize(circ->element, [&](const PlainPolygonElement& poly, const ColorIndex color){
 				AppendToModel append{elementFromPolygonAndColor(poly, color)};
 				const auto& subpoints = polygonsToBeInserted(append);
 				std::copy(subpoints.begin(), subpoints.end(), std::back_inserter(result));
@@ -183,12 +183,12 @@
 const std::vector<ModelAction> EditTools::modelActions() const
 {
 	switch(this->mode) {
-	case SelectMode:
+	case editing_mode_e::select:
 		return {};
-	case DrawMode:
-		return drawModeActions();
-	case CircleMode:
-		return circleModeActions();
+	case editing_mode_e::draw:
+		return this->drawModeActions();
+	case editing_mode_e::circle:
+		return this->circleModeActions();
 	}
 }
 
@@ -217,7 +217,7 @@
 	for (const glm::vec3& point : this->inputPolygon) {
 		drawWorldPoint(painter, point, this->renderer);
 	}
-	if (this->mode == CircleMode and this->inputPolygon.polygonSize() >= 2) {
+	if (this->mode == editing_mode_e::circle and this->inputPolygon.polygonSize() >= 2) {
 		const glm::vec3 circleOrigin = this->inputPolygon[0];
 		const QPointF originScreen = this->renderer->modelToScreenCoordinates(circleOrigin);
 		const auto extremity = [this, &originScreen](const glm::vec3& p){
@@ -282,7 +282,7 @@
 	}
 }
 
-EditingMode EditTools::currentEditingMode() const
+editing_mode_e EditTools::currentEditingMode() const
 {
 	return this->mode;
 }
@@ -290,13 +290,13 @@
 void EditTools::mouseClick(const QMouseEvent* event)
 {
 	switch(this->mode) {
-	case SelectMode:
+	case editing_mode_e::select:
 		if (event->button() == Qt::LeftButton) {
 			const std::int32_t highlighted = this->renderer->pick(event->pos());
 			Q_EMIT this->select({highlighted}, false);
 		}
 		break;
-	case DrawMode:
+	case editing_mode_e::draw:
 		if (event->button() == Qt::LeftButton and this->worldPosition.has_value()) {
 			if (this->inputPolygon.currentPointOnExistingPoint()) {
 				this->closeShape();
@@ -306,7 +306,7 @@
 			}
 		}
 		break;
-	case CircleMode:
+	case editing_mode_e::circle:
 		if (event->button() == Qt::LeftButton) {
 			if (this->inputPolygon.bufferSize() == 3) {
 				this->closeShape();
@@ -370,10 +370,10 @@
 bool EditTools::usePolygon() const
 {
 	switch (this->mode) {
-	case SelectMode:
+	case editing_mode_e::select:
 		return false;
-	case DrawMode:
-	case CircleMode:
+	case editing_mode_e::draw:
+	case editing_mode_e::circle:
 		return true;
 	}
 	return {};
--- a/src/layers/edittools.h	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/layers/edittools.h	Tue Apr 11 11:11:28 2023 +0300
@@ -25,14 +25,14 @@
 #include "src/gl/common.h"
 #include "src/inputvertices.h"
 
-enum EditingMode
+enum class editing_mode_e
 {
-	SelectMode,
-	DrawMode,
-	CircleMode
+	select,
+	draw,
+	circle
 };
 
-Q_DECLARE_METATYPE(EditingMode)
+Q_DECLARE_METATYPE(editing_mode_e)
 
 Q_DECLARE_METATYPE(ModelAction)
 
@@ -40,7 +40,7 @@
 {
 	Q_OBJECT
 	InputVertices inputPolygon;
-	EditingMode mode = SelectMode;
+	editing_mode_e mode = editing_mode_e::select;
 	glm::mat4 mvpMatrix;
 	glm::mat4 gridMatrix{1};
 	Plane gridPlane;
@@ -55,8 +55,8 @@
 	~EditTools() override;
 	void applyToVertices(VertexMap::ApplyFunction fn) const;
 	[[nodiscard]] const QSet<ModelId> selectedObjects() const;
-	[[nodiscard]] EditingMode currentEditingMode() const;
-	Q_SLOT void setEditMode(EditingMode mode);
+	[[nodiscard]] editing_mode_e currentEditingMode() const;
+	Q_SLOT void setEditMode(editing_mode_e mode);
 	Q_SLOT void setGridMatrix(const glm::mat4& gridMatrix);
 	Q_SLOT void setCircleToolOptions(const CircleToolOptions& options);
 Q_SIGNALS:
--- a/src/main.cpp	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/main.cpp	Tue Apr 11 11:11:28 2023 +0300
@@ -238,7 +238,7 @@
 		QAction* action = new QAction{editingModeInfo.name, parent};
 		action->setCheckable(true);
 		action->setEnabled(false);
-		action->setData(static_cast<EditingMode>(i));
+		action->setData(QVariant::fromValue(static_cast<editing_mode_e>(i)));
 		action->setToolTip(editingModeInfo.tooltip);
 		action->setIcon(QPixmap{editingModeInfo.icon});
 		ui->editingModesToolBar->addAction(action);
@@ -371,7 +371,7 @@
 			&EditTools::suggestCursor,
 			data->canvas.get(),
 			&QWidget::setCursor);
-		data->tools->setEditMode(SelectMode);
+		data->tools->setEditMode(editing_mode_e::select);
 		const QFileInfo fileInfo{*state->documents.modelPath(modelId)};
 		auto* const subWindow = createSubWindow<ModelSubWindow>(state->mainWindow.mdiArea, modelId);
 		subWindow->setMinimumSize({96, 96});
@@ -468,13 +468,13 @@
 	}
 }
 
-static void checkEditingModeAction(MainState* state, const EditingMode mode)
+static void checkEditingModeAction(MainState* state, const editing_mode_e mode)
 {
 	const bool hasDocument = currentModelData(&state->mainWindow, &state->documents) != nullptr;
 	for (QAction* action : state->mainWindow.editingModesToolBar->actions())
 	{
 		action->setEnabled(hasDocument);
-		action->setChecked(hasDocument and action->data().value<EditingMode>() == mode);
+		action->setChecked(hasDocument and action->data().value<editing_mode_e>() == mode);
 	}
 }
 
@@ -502,6 +502,18 @@
 	update_model_grid_matrix(state);
 }
 
+static void replace_color_in_selected_code(QTextCursor* cursor, const ColorIndex color)
+{
+	const auto pattern = R"(^(\s*(?:1|2|3|4|5)\s+)\d+)";
+	static const QRegularExpression regular_expression{pattern, QRegularExpression::MultilineOption};
+	QString text = cursor->selectedText();
+	// Qt has decided to be "smart" and uses strange unicode characters instead of newlines
+	text.replace("\u2029", "\n");
+	text.replace(regular_expression, QStringLiteral(R"(\1%1)").arg(color.index));
+	cursor->removeSelectedText();
+	cursor->insertText(text);
+}
+
 int main(int argc, char *argv[])
 {
 	doQtRegistrations();
@@ -609,7 +621,7 @@
 		{
 			if (ModelData* data = currentModelData(&state.mainWindow, &state.documents))
 			{
-				const EditingMode mode = action->data().value<EditingMode>();
+				const editing_mode_e mode = action->data().value<editing_mode_e>();
 				data->tools->setEditMode(mode);
 				checkEditingModeAction(&state, mode);
 			}
@@ -631,7 +643,7 @@
 		}
 		else
 		{
-			checkEditingModeAction(&state, EditingMode::SelectMode);
+			checkEditingModeAction(&state, editing_mode_e::select);
 		}
 		state.mainWindow.modelEdit->setEnabled(modelSubWindow != nullptr);
 	});
@@ -713,6 +725,14 @@
 			set_grid_scale(&state, 0.1f);
 		}
 	);
+	QObject::connect(
+		state.mainWindow.action_make_stuff_red,
+		&QAction::triggered,
+		[&state]{
+			QTextCursor cursor = state.mainWindow.modelEdit->textCursor();
+			replace_color_in_selected_code(&cursor, ColorIndex{4});
+		}
+	);
 	restoreSettings(&state);
 	updateRenderPreferences(&state.mainWindow, &state.renderPreferences, &state.documents);
 	const int result = app.exec();
--- a/src/mainwindow.ui	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/mainwindow.ui	Tue Apr 11 11:11:28 2023 +0300
@@ -334,6 +334,7 @@
    <addaction name="actionCopy"/>
    <addaction name="actionPaste"/>
    <addaction name="actionSelectAll"/>
+   <addaction name="action_make_stuff_red"/>
   </widget>
   <action name="actionQuit">
    <property name="icon">
@@ -624,6 +625,11 @@
     <string>Ctrl+Y</string>
    </property>
   </action>
+  <action name="action_make_stuff_red">
+   <property name="text">
+    <string>Make stuff red</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
--- a/src/model.cpp	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/model.cpp	Tue Apr 11 11:11:28 2023 +0300
@@ -115,44 +115,44 @@
 			QString result;
 			result += QStringLiteral("1 %1 %2 %3")
 				.arg(ref.color.index)
-				.arg(transformToString(ref.transformation))
-				.arg(ref.name);
+				.arg(transformToString(ref.element.transformation))
+				.arg(ref.element.name);
 			return result;
 		},
 		[](const Colored<LineSegment>& seg) {
 			return QStringLiteral("2 %1 %2 %3")
 				.arg(seg.color.index)
-				.arg(vertexToString(seg.p1))
-				.arg(vertexToString(seg.p2));
+				.arg(vertexToString(seg.element.p1))
+				.arg(vertexToString(seg.element.p2));
 		},
 		[](const Colored<Triangle>& triangle) {
 			return QStringLiteral("3 %1 %2 %3 %4")
 				.arg(triangle.color.index)
-				.arg(vertexToString(triangle.p1))
-				.arg(vertexToString(triangle.p2))
-				.arg(vertexToString(triangle.p3));
+				.arg(vertexToString(triangle.element.p1))
+				.arg(vertexToString(triangle.element.p2))
+				.arg(vertexToString(triangle.element.p3));
 		},
 		[](const Colored<Quadrilateral>& quad) {
 			return QStringLiteral("4 %1 %2 %3 %4 %5")
 				.arg(quad.color.index)
-				.arg(vertexToString(quad.p1))
-				.arg(vertexToString(quad.p2))
-				.arg(vertexToString(quad.p3))
-				.arg(vertexToString(quad.p4));
+				.arg(vertexToString(quad.element.p1))
+				.arg(vertexToString(quad.element.p2))
+				.arg(vertexToString(quad.element.p3))
+				.arg(vertexToString(quad.element.p4));
 		},
 		[](const Colored<ConditionalEdge>& cedge) {
 			return QStringLiteral("5 %1 %2 %3 %4 %5")
 				.arg(cedge.color.index)
-				.arg(vertexToString(cedge.p1))
-				.arg(vertexToString(cedge.p2))
-				.arg(vertexToString(cedge.c1))
-				.arg(vertexToString(cedge.c2));
+				.arg(vertexToString(cedge.element.p1))
+				.arg(vertexToString(cedge.element.p2))
+				.arg(vertexToString(cedge.element.c1))
+				.arg(vertexToString(cedge.element.c2));
 		},
 		[](const Colored<CircularPrimitive>& circ) {
 			return QStringLiteral("1 %1 %2 %3")
 				.arg(circ.color.index)
-				.arg(transformToString(circ.transformation))
-				.arg(circularPrimitiveFilePath(circ));
+				.arg(transformToString(circ.element.transformation))
+				.arg(circularPrimitiveFilePath(circ.element));
 		},
 		[](const Comment& comment) {
 			return "0 " + comment.text;
--- a/src/model.h	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/model.h	Tue Apr 11 11:11:28 2023 +0300
@@ -30,8 +30,9 @@
 };
 
 template<typename T>
-struct Colored : T
+struct Colored
 {
+	T element;
 	ldraw::Color color;
 };
 
--- a/src/polygoncache.cpp	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/polygoncache.cpp	Tue Apr 11 11:11:28 2023 +0300
@@ -10,13 +10,13 @@
 }
 
 static PolygonElement transformed(
-	PolygonElement element,
+	PolygonElement coloredElement,
 	const glm::mat4& transform)
 {
 	visitPoints([&transform](glm::vec3& p) {
 		p = transform * glm::vec4{p, 1};
-	}, element);
-	return element;
+	}, coloredElement.element);
+	return coloredElement;
 }
 
 PolygonCache* findPolygonCacheForModel(QTextDocument* model, DocumentManager* context)
@@ -59,13 +59,13 @@
 	Fn2&& reserve)
 {
 	const bool needInverting = 0
-		^ (glm::determinant(ref.transformation) < 0)
+		^ (glm::determinant(ref.element.transformation) < 0)
 		^ (context->invertnext);
 	reserve(polygons.size());
 	for (const PolygonElement& cacheElement : polygons) {
-		PolygonElement polygon = transformed(cacheElement, ref.transformation);
+		PolygonElement polygon = transformed(cacheElement, ref.element.transformation);
 		if (needInverting) {
-			gl::invert(polygon);
+			gl::invert(polygon.element);
 		}
 		if (polygon.color == MAIN_COLOR) {
 			polygon.color = ref.color;
@@ -106,19 +106,19 @@
 			}
 		},
 		[&](const LineType2& line2) {
-			add(2, {line2.value, line2.value.color});
+			add(2, {line2.value.element, line2.value.color});
 		},
 		[&](const LineType3& line3) {
-			add(3, {line3.value, line3.value.color});
+			add(3, {line3.value.element, line3.value.color});
 		},
 		[&](const LineType4& line4) {
-			add(4, {line4.value, line4.value.color});
+			add(4, {line4.value.element, line4.value.color});
 		},
 		[&](const LineType5& line5) {
-			add(5, {line5.value, line5.value.color});
+			add(5, {line5.value.element, line5.value.color});
 		},
 		[&add, context, &reserve](const LineType1& line1) {
-			QTextDocument* const dependency = findDependency(line1.value, context);
+			QTextDocument* const dependency = findDependency(line1.value.element, context);
 			if (PolygonCache* cache = (dependency != nullptr)
 				? findPolygonCacheForModel(dependency, context->documents)
 				: nullptr
@@ -153,7 +153,7 @@
 	const auto add = [&result, &winding, &i](int lineno, const PolygonElement& poly){
 		result.push_back({poly, i});
 		if (lineno != 1 and winding == winding_e::clockwise) {
-			gl::invert(result.back());
+			gl::invert(result.back().element);
 		}
 	};
 	const auto reserve = [&result](std::size_t incomingsize){
--- a/src/triangulate.cpp	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/triangulate.cpp	Tue Apr 11 11:11:28 2023 +0300
@@ -151,10 +151,11 @@
 		}
 		for (std::size_t i = 0; i < indices.size(); i += 3) {
 			if (not mergedTriangles.cutTriangles.contains({i})) {
-				Triangle tri = triangle(
-				*(begin + indices[i]),
-				*(begin + indices[i + 1]),
-				*(begin + indices[i + 2]));
+				Triangle tri = Triangle{
+					.p1 = *(begin + indices[i]),
+					.p2 = *(begin + indices[i + 1]),
+					.p3 = *(begin + indices[i + 2]),
+				};
 				result.push_back(tri);
 			}
 		}
--- a/src/vertexmap.cpp	Mon Apr 10 14:46:36 2023 +0300
+++ b/src/vertexmap.cpp	Tue Apr 11 11:11:28 2023 +0300
@@ -22,51 +22,50 @@
 	const glm::vec3& b;
 };
 
-inline void edges(const ModelElement& element, std::function<void(Edge&&)> fn)
+static void edges(const PlainPolygonElement& element, std::function<void(Edge&&)> fn)
 {
 	std::visit<void>(overloaded{
-		[fn](const Colored<LineSegment>& edge) {
+		[fn](const LineSegment& edge) {
 			fn(Edge{edge.p1, edge.p2});
 		},
-		[fn](const Colored<Triangle>& triangle) {
+		[fn](const Triangle& triangle) {
 			fn(Edge{triangle.p1, triangle.p2});
 			fn(Edge{triangle.p2, triangle.p3});
 			fn(Edge{triangle.p3, triangle.p1});
 		},
-		[fn](const Colored<Quadrilateral>& quad) {
+		[fn](const Quadrilateral& quad) {
 			fn(Edge{quad.p1, quad.p2});
 			fn(Edge{quad.p2, quad.p3});
 			fn(Edge{quad.p3, quad.p4});
 			fn(Edge{quad.p4, quad.p1});
 		},
-		[fn](const Colored<ConditionalEdge>& cedge) {
+		[fn](const ConditionalEdge& cedge) {
 			fn(Edge{cedge.p1, cedge.p2});
 		},
-		[](const ModelElement&&){}
 	}, element);
 }
 
 inline void points(
-	const ModelElement& element,
+	const PlainPolygonElement& element,
 	std::function<void(const glm::vec3&)> fn)
 {
 	std::visit<void>(overloaded{
-		[fn](const Colored<LineSegment>& edge) {
+		[fn](const LineSegment& edge) {
 			fn(edge.p1);
 			fn(edge.p2);
 		},
-		[fn](const Colored<Triangle>& triangle) {
+		[fn](const Triangle& triangle) {
 			fn(triangle.p1);
 			fn(triangle.p2);
 			fn(triangle.p3);
 		},
-		[fn](const Colored<Quadrilateral>& quad) {
+		[fn](const Quadrilateral& quad) {
 			fn(quad.p1);
 			fn(quad.p2);
 			fn(quad.p3);
 			fn(quad.p4);
 		},
-		[fn](const Colored<ConditionalEdge>& cedge) {
+		[fn](const ConditionalEdge& cedge) {
 			fn(cedge.p1);
 			fn(cedge.p2);
 			fn(cedge.c1);

mercurial