src/linetypes/compoundobject.cpp

changeset 183
97b591813c8b
child 186
922662adb72a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/linetypes/compoundobject.cpp	Tue Mar 15 18:52:48 2022 +0200
@@ -0,0 +1,115 @@
+#include "compoundobject.h"
+#include "documentmanager.h"
+#include "invert.h"
+#include "polygoncache.h"
+
+ldraw::CompoundObject::CompoundObject
+(
+	const glm::mat4& transformation,
+	const Color color
+) :
+	ColoredObject{color},
+	transformation{transformation}
+{
+}
+
+QVariant ldraw::CompoundObject::getProperty(Property property) const
+{
+	switch (property)
+	{
+	case Property::Transformation:
+		return QVariant::fromValue(this->transformation);
+	case Property::IsInverted:
+		return this->isInverted;
+	default:
+		return ColoredObject::getProperty(property);
+	}
+}
+
+void ldraw::CompoundObject::setProperty(SetPropertyResult* result, const PropertyKeyValue& pair)
+{
+	LDRAW_OBJECT_HANDLE_SET_PROPERTY(Transformation, {this->transformation = value;});
+	LDRAW_OBJECT_HANDLE_SET_PROPERTY(IsInverted, {this->isInverted = value;});
+	ldraw::ColoredObject::setProperty(result, pair);
+}
+
+glm::vec3 ldraw::CompoundObject::position() const
+{
+	return this->transformation[3];
+}
+
+void ldraw::CompoundObject::invert(GetPolygonsContext *context)
+{
+	const std::optional<Axis> flatDimension = context ? this->flatDimension(context) : std::optional<Axis>{};
+	if (flatDimension.has_value())
+	{
+		glm::mat4 matrix = glm::identity<glm::mat4>();
+		matrix[*flatDimension][*flatDimension] = -1.0f;
+		this->transformation *= matrix;
+	}
+	else
+	{
+		this->isInverted = not this->isInverted;
+	}
+}
+
+
+QDataStream& ldraw::CompoundObject::serialize(QDataStream &stream) const
+{
+	return ColoredObject::serialize(stream) << this->transformation << this->isInverted;
+}
+
+QDataStream& ldraw::CompoundObject::deserialize(QDataStream &stream)
+{
+	return ColoredObject::deserialize(stream) >> this->transformation >> this->isInverted;
+}
+
+/**
+ * @brief Finds out in which dimension the object is flat in. In that dimension all vertices have a value of 0.
+ * If the object is not flat, this does not return a value.
+ * @param model Model to find out flatness of
+ * @param documents Where to look for subfiles
+ * @returns dimension the model is flat in, if such dimension exists, no value otherwise.
+ */
+std::optional<Axis> ldraw::CompoundObject::flatDimension(GetPolygonsContext *context) const
+{
+	// The dimensions that this model is potentially flat in.
+	QVector<Axis> dimensions = {X, Y, Z};
+	std::vector<gl::Polygon> polygons;
+	this->getPolygons(polygons, context);
+	for (const gl::Polygon& polygon : polygons)
+	{
+		for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
+		{
+			const glm::vec3& v_i = polygon.vertices[i];
+			if (not qFuzzyCompare(v_i.x, 0.0f))
+			{
+				dimensions.removeOne(X);
+			}
+			if (not qFuzzyCompare(v_i.y, 0.0f))
+			{
+				dimensions.removeOne(Y);
+			}
+			if (not qFuzzyCompare(v_i.z, 0.0f))
+			{
+				dimensions.removeOne(Z);
+			}
+		}
+		// If there are no more dimensions left, we can exit the loop.
+		if (dimensions.isEmpty())
+		{
+			break;
+		}
+	}
+	if (dimensions.size() == 1)
+	{
+		// The model is flat in one dimension, return that.
+		// If the model is flat in two or three dimensions, it's not really a valid model.
+		return dimensions[0];
+	}
+	else
+	{
+		// The model is not flat.
+		return {};
+	}
+}

mercurial