moved inverting code into a new file

Mon, 19 Mar 2018 10:57:13 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 19 Mar 2018 10:57:13 +0200
changeset 1301
4a4e9fb9da76
parent 1300
609b75b026c4
child 1302
e14d7826373a

moved inverting code into a new file

CMakeLists.txt file | annotate | diff | comparison | revisions
src/algorithms/invert.cpp file | annotate | diff | comparison | revisions
src/algorithms/invert.h file | annotate | diff | comparison | revisions
src/toolsets/basictoolset.cpp file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sun Mar 18 23:31:15 2018 +0200
+++ b/CMakeLists.txt	Mon Mar 19 10:57:13 2018 +0200
@@ -57,6 +57,7 @@
 	src/serializer.cpp
 	src/ringFinder.cpp
 	src/version.cpp
+	src/algorithms/invert.cpp
 	src/dialogs/colorselector.cpp
 	src/dialogs/configdialog.cpp
 	src/dialogs/externalprogrampathdialog.cpp
@@ -128,6 +129,7 @@
 	src/ringFinder.h
 	src/serializer.h
 	src/transform.h
+	src/algorithms/invert.h
 	src/dialogs/colorselector.h
 	src/dialogs/configdialog.h
 	src/dialogs/externalprogrampathdialog.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/algorithms/invert.cpp	Mon Mar 19 10:57:13 2018 +0200
@@ -0,0 +1,121 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2017 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 "../linetypes/modelobject.h"
+#include "../lddocument.h"
+
+/*
+ * Returns whether or not the document is flat.
+ * If it is flat, the result is stored in *axis.
+ */
+bool isflat(Model* model, Axis* axis)
+{
+	QVector<Axis> axisSet = {X, Y, Z};
+
+	for (LDObject* subfileObject : model->objects())
+	{
+		for (int i = 0; i < subfileObject->numVertices(); ++i)
+		{
+			Vertex const& v_i = subfileObject->vertex(i);
+
+			if (not qFuzzyCompare(v_i.x(), 0.f))
+				axisSet.removeOne(X);
+
+			if (not qFuzzyCompare(v_i.y(), 0.f))
+				axisSet.removeOne(Y);
+
+			if (not qFuzzyCompare(v_i.z(), 0.f))
+				axisSet.removeOne(Z);
+		}
+
+		if (axisSet.isEmpty())
+			break;
+	}
+
+	if (axisSet.size() == 1)
+	{
+		*axis = axisSet[0];
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+/*
+ * Returns a matrix that causes a flip on the given axis.
+ */
+Matrix flipmatrix(Axis axis)
+{
+	Matrix result = Matrix::identity;
+
+	switch (axis)
+	{
+	case X:
+		result(0, 0) = -1;
+		break;
+
+	case Y:
+		result(1, 1) = -1;
+		break;
+
+	case Z:
+		result(2, 2) = -1;
+		break;
+	}
+
+	return result;
+}
+
+/*
+ * Inverts an LDObject so that its winding is changed.
+ */
+void invert(LDObject* obj, DocumentManager* context)
+{
+	if (obj->numPolygonVertices() > 0)
+	{
+		QVector<Vertex> vertices;
+
+		for (int i = 0; i < obj->numPolygonVertices(); i += 1)
+			vertices.append(obj->vertex(i));
+
+		for (int i = 0; i < vertices.size(); i += 1)
+			obj->setVertex(i, vertices[vertices.size() - 1 - i]);
+	}
+	else if (obj->type() == LDObjectType::SubfileReference)
+	{
+		// Check whether subfile is flat. If it is, flip it on the axis on which it is flat.
+		Model model {context};
+		LDSubfileReference* reference = static_cast<LDSubfileReference*>(obj);
+		reference->fileInfo(context)->inlineContents(model, true, false);
+		Axis flatAxis;
+
+		if (isflat(&model, &flatAxis))
+		{
+			reference->setTransformationMatrix(
+				reference->transformationMatrix() * flipmatrix(flatAxis)
+			);
+		}
+		else
+		{
+			// Subfile is not flat. Resort to invertnext.
+			reference->setInverted(not reference->isInverted());
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/algorithms/invert.h	Mon Mar 19 10:57:13 2018 +0200
@@ -0,0 +1,24 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2017 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"
+
+bool isflat(class Model* model, Axis* axis);
+Matrix flipmatrix(Axis axis);
+void invert(LDObject* obj, class DocumentManager* context);
--- a/src/toolsets/basictoolset.cpp	Sun Mar 18 23:31:15 2018 +0200
+++ b/src/toolsets/basictoolset.cpp	Mon Mar 19 10:57:13 2018 +0200
@@ -37,6 +37,7 @@
 #include "../grid.h"
 #include "../parser.h"
 #include "../widgets/vertexobjecteditor.h"
+#include "../algorithms/invert.h"
 #include "basictoolset.h"
 #include "guiutilities.h"
 
@@ -228,70 +229,8 @@
 
 void BasicToolset::invert()
 {
-	for (LDObject* obj : selectedObjects())
-	{
-		if (obj->numPolygonVertices() > 0)
-		{
-			QVector<Vertex> vertices;
-
-			for (int i = 0; i < obj->numPolygonVertices(); i += 1)
-				vertices.append(obj->vertex(i));
-
-			for (int i = 0; i < vertices.size(); i += 1)
-				obj->setVertex(i, vertices[vertices.size() - 1 - i]);
-		}
-		else if (obj->type() == LDObjectType::SubfileReference)
-		{
-			// Check whether subfile is flat
-			int axisSet = (1 << X) | (1 << Y) | (1 << Z);
-			Model model {currentDocument()->documentManager()};
-			LDSubfileReference* reference = static_cast<LDSubfileReference*>(obj);
-			reference->fileInfo(m_documents)->inlineContents(model, true, false);
-
-			for (LDObject* subobj : model.objects())
-			{
-				for (int i = 0; i < subobj->numVertices(); ++i)
-				{
-					Vertex const& vrt = subobj->vertex (i);
-
-					if (axisSet & (1 << X) and vrt.x() != 0.0)
-						axisSet &= ~(1 << X);
-
-					if (axisSet & (1 << Y) and vrt.y() != 0.0)
-						axisSet &= ~(1 << Y);
-
-					if (axisSet & (1 << Z) and vrt.z() != 0.0)
-						axisSet &= ~(1 << Z);
-				}
-
-				if (axisSet == 0)
-					break;
-			}
-
-			if (axisSet != 0)
-			{
-				// Subfile has all vertices zero on one specific plane, so it is flat.
-				// Let's flip it.
-				Matrix matrixModifier = Matrix::identity;
-
-				if (axisSet & (1 << X))
-					matrixModifier(0, 0) = -1;
-
-				if (axisSet & (1 << Y))
-					matrixModifier(1, 1) = -1;
-
-				if (axisSet & (1 << Z))
-					matrixModifier(2, 2) = -1;
-
-				reference->setTransformationMatrix(reference->transformationMatrix() * matrixModifier);
-			}
-			else
-			{
-				// Subfile is not flat. Resort to invertnext.
-				reference->setInverted(not reference->isInverted());
-			}
-		}
-	}
+	for (LDObject* object : selectedObjects())
+		::invert(object, m_documents);
 }
 
 template<typename T>

mercurial