src/linetypes/compoundobject.cpp

changeset 200
ca23936b455b
parent 199
6988973515d2
child 201
5d201ee4a9c3
equal deleted inserted replaced
199:6988973515d2 200:ca23936b455b
1 #include "compoundobject.h"
2 #include "documentmanager.h"
3 #include "invert.h"
4 #include "polygoncache.h"
5
6 ldraw::CompoundObject::CompoundObject
7 (
8 const glm::mat4& transformation,
9 const Color color
10 ) :
11 ColoredObject{color},
12 transformation{transformation}
13 {
14 }
15
16 QVariant ldraw::CompoundObject::getProperty(Property property) const
17 {
18 switch (property)
19 {
20 case Property::Transformation:
21 return QVariant::fromValue(this->transformation);
22 case Property::IsInverted:
23 return this->isInverted;
24 default:
25 return ColoredObject::getProperty(property);
26 }
27 }
28
29 void ldraw::CompoundObject::setProperty(SetPropertyResult* result, const PropertyKeyValue& pair)
30 {
31 LDRAW_OBJECT_HANDLE_SET_PROPERTY(Transformation, {this->transformation = value;});
32 LDRAW_OBJECT_HANDLE_SET_PROPERTY(IsInverted, {this->isInverted = value;});
33 ldraw::ColoredObject::setProperty(result, pair);
34 }
35
36 glm::vec3 ldraw::CompoundObject::position() const
37 {
38 return this->transformation[3];
39 }
40
41 void ldraw::CompoundObject::invert(GetPolygonsContext *context)
42 {
43 const std::optional<Axis> flatDimension = context ? this->flatDimension(context) : std::optional<Axis>{};
44 if (flatDimension.has_value())
45 {
46 glm::mat4 matrix = glm::identity<glm::mat4>();
47 matrix[*flatDimension][*flatDimension] = -1.0f;
48 this->transformation *= matrix;
49 }
50 else
51 {
52 this->isInverted = not this->isInverted;
53 }
54 }
55
56
57 QDataStream& ldraw::CompoundObject::serialize(QDataStream &stream) const
58 {
59 return ColoredObject::serialize(stream) << this->transformation << this->isInverted;
60 }
61
62 QDataStream& ldraw::CompoundObject::deserialize(QDataStream &stream)
63 {
64 return ColoredObject::deserialize(stream) >> this->transformation >> this->isInverted;
65 }
66
67 /**
68 * @brief Finds out in which dimension the object is flat in. In that dimension all vertices have a value of 0.
69 * If the object is not flat, this does not return a value.
70 * @param model Model to find out flatness of
71 * @param documents Where to look for subfiles
72 * @returns dimension the model is flat in, if such dimension exists, no value otherwise.
73 */
74 std::optional<Axis> ldraw::CompoundObject::flatDimension(GetPolygonsContext *context) const
75 {
76 // The dimensions that this model is potentially flat in.
77 QVector<Axis> dimensions = {X, Y, Z};
78 std::vector<gl::Polygon> polygons;
79 this->getPolygons(polygons, context);
80 for (const gl::Polygon& polygon : polygons)
81 {
82 for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
83 {
84 const glm::vec3& v_i = polygon.vertices[i];
85 if (not qFuzzyCompare(v_i.x, 0.0f))
86 {
87 dimensions.removeOne(X);
88 }
89 if (not qFuzzyCompare(v_i.y, 0.0f))
90 {
91 dimensions.removeOne(Y);
92 }
93 if (not qFuzzyCompare(v_i.z, 0.0f))
94 {
95 dimensions.removeOne(Z);
96 }
97 }
98 // If there are no more dimensions left, we can exit the loop.
99 if (dimensions.isEmpty())
100 {
101 break;
102 }
103 }
104 if (dimensions.size() == 1)
105 {
106 // The model is flat in one dimension, return that.
107 // If the model is flat in two or three dimensions, it's not really a valid model.
108 return dimensions[0];
109 }
110 else
111 {
112 // The model is not flat.
113 return {};
114 }
115 }
116
117 QString ldraw::CompoundObject::transformToBareString() const
118 {
119 return utility::format(
120 "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12",
121 this->transformation[3][0],
122 this->transformation[3][1],
123 this->transformation[3][2],
124 this->transformation[0][0],
125 this->transformation[1][0],
126 this->transformation[2][0],
127 this->transformation[0][1],
128 this->transformation[1][1],
129 this->transformation[2][1],
130 this->transformation[0][2],
131 this->transformation[1][2],
132 this->transformation[2][2]);
133 }

mercurial