# HG changeset patch
# User Teemu Piippo <teemu@hecknology.net>
# Date 1646427606 -7200
# Node ID 47cb50cfa9adc6ebf4f5d00087617be6a6938d61
# Parent  2f79053c2e9a03e10c93cc9526227bf4005db9b6
add missing files

diff -r 2f79053c2e9a -r 47cb50cfa9ad src/ldrawalgorithm.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldrawalgorithm.cpp	Fri Mar 04 23:00:06 2022 +0200
@@ -0,0 +1,74 @@
+#include "ldrawalgorithm.h"
+#include "linetypes/quadrilateral.h"
+#include "linetypes/triangle.h"
+
+void ldraw::invert(ModelEditor& editor, ldraw::id_t id)
+{
+	editor.modifyObject(id, [](ldraw::Object* object){
+		object->invert();
+	});
+}
+
+static std::array<geom::Triangle, 2> splitTriangles(ldraw::Diagonal diagonal, const std::array<glm::vec3, 4>& points)
+{
+	std::array<geom::Triangle, 2> result;
+	switch (diagonal)
+	{
+	case ldraw::Diagonal::Diagonal_13:
+		result = {geom::Triangle{points[0], points[1], points[2]}, {points[0], points[2], points[3]}};
+		break;
+	case ldraw::Diagonal::Diagonal_24:
+		result = {geom::Triangle{points[0], points[1], points[3]}, {points[1], points[2], points[3]}};
+		break;
+	}
+	return result;
+}
+
+auto ldraw::splitQuadrilateral(
+	ModelEditor& editor,
+	ldraw::quadrilateralid_t quadrilateral_id,
+	ldraw::Diagonal splitType
+) -> std::optional<std::pair<ldraw::triangleid_t, ldraw::triangleid_t>>
+{
+	std::optional<std::pair<ldraw::triangleid_t, ldraw::triangleid_t>> result;
+	const auto resolved = editor.model().get2(quadrilateral_id);
+	if (resolved.object != nullptr)
+	{
+		const ldraw::Color color = resolved.object->colorIndex;
+		const std::array<geom::Triangle, 2> split = splitTriangles(splitType, resolved.object->points);
+		const int position = resolved.index.row();
+		editor.remove(position);
+		result = std::make_pair(
+			editor.insert<ldraw::Triangle>(position, split[0].points, color),
+			editor.insert<ldraw::Triangle>(position, split[1].points, color));
+	}
+	return result;
+}
+
+/**
+ * @brief Modifies the !LDRAW_ORG line so that it becomes unofficial
+ */
+void ldraw::makeUnofficial(ModelEditor& editor)
+{
+	if (editor.model().size() >= 4)
+	{
+		const ldraw::Object* ldrawOrgLine = editor.model()[3];
+		if (isA<ldraw::MetaCommand>(ldrawOrgLine))
+		{
+			const QString& body = ldrawOrgLine->getProperty<ldraw::Property::Text>();
+			if (body.startsWith("!LDRAW_ORG ") and not body.startsWith("!LDRAW_ORG Unofficial_"))
+			{
+				// Add Unofficial_ to part type
+				QStringList tokens = body.split(" ");
+				tokens[1] = "Unofficial_" + tokens[1];
+				// Remove the UPDATE tag if it's there
+				if (tokens.size() >= 4 && tokens[2] == "UPDATE")
+				{
+					tokens.removeAt(3);
+					tokens.removeAt(2);
+				}
+				editor.setObjectProperty<ldraw::Property::Text>(ldrawOrgLine->id, tokens.join(" "));
+			}
+		}
+	}
+}
\ No newline at end of file
diff -r 2f79053c2e9a -r 47cb50cfa9ad src/ldrawalgorithm.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldrawalgorithm.h	Fri Mar 04 23:00:06 2022 +0200
@@ -0,0 +1,22 @@
+#pragma once
+#include "modeleditor.h"
+
+namespace ldraw
+{
+	/// Determines how quadrilaterals are split into triangles
+	enum class Diagonal
+	{
+		Diagonal_13,
+		Diagonal_24
+	};
+
+	// Splits the specified quadrilateral into triangles.
+	// If it is not a quadrilateral then no action is performed
+	auto splitQuadrilateral(ModelEditor& editor,
+		quadrilateralid_t quadrilateral_id,
+		Diagonal splitType = Diagonal::Diagonal_13
+	) -> std::optional<std::pair<triangleid_t, triangleid_t>>;
+
+	void invert(ModelEditor& editor, ldraw::id_t id);
+	void makeUnofficial(ModelEditor &editor);
+}