src/invert.cpp

changeset 19
ed9685f44ab3
child 21
0133e565e072
equal deleted inserted replaced
18:918b6c0f8b5b 19:ed9685f44ab3
1 /*
2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 - 2018 Teemu Piippo
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "main.h"
20 #include "model.h"
21 #include "matrix.h"
22 #include "gl/common.h"
23
24 #if 0
25 /*
26 * Returns whether or not the document is flat.
27 * If it is flat, the result is stored in *axis.
28 */
29 bool isflat(Model* model, Axis* flatDimension)
30 {
31 // The dimensions that this model is potentially flat in.
32 QVector<Axis> dimensions = {X, Y, Z};
33
34 // Iterate through everything in the subfile. If there is any vertex with a coordinate not at
35 // zero, the subfile is not flat in that dimension.
36 for (LDObject* subfileObject : model->objects())
37 {
38 for (int i = 0; i < subfileObject->numVertices(); ++i)
39 {
40 Vertex const& v_i = subfileObject->vertex(i);
41
42 if (not qFuzzyCompare(v_i.x, 0.0))
43 dimensions.removeOne(X);
44
45 if (not qFuzzyCompare(v_i.y, 0.0))
46 dimensions.removeOne(Y);
47
48 if (not qFuzzyCompare(v_i.z, 0.0))
49 dimensions.removeOne(Z);
50 }
51
52 // If there are no more dimensions left, we can exit the loop.
53 if (dimensions.isEmpty())
54 break;
55 }
56
57 if (dimensions.size() == 1)
58 {
59 // The model is flat in one dimension, return that.
60 // If the model is flat in two or three dimensions, it's not really a valid model.
61 *flatDimension = dimensions[0];
62 return true;
63 }
64 else
65 {
66 // The model is not flat.
67 return false;
68 }
69 }
70 #endif
71
72 /*
73 * Returns a matrix that causes a flip on the given dimension.
74 */
75 Matrix4x4 flipmatrix(Axis dimension)
76 {
77 Matrix4x4 result = identity4x4;
78 switch (dimension)
79 {
80 case X:
81 result(0, 0) = -1;
82 break;
83 case Y:
84 result(1, 1) = -1;
85 break;
86 case Z:
87 result(2, 2) = -1;
88 break;
89 }
90 return result;
91 }
92
93 #if 0
94 /*
95 * Inverts an LDObject so that its winding is changed.
96 */
97 void invert(LDObject* obj, DocumentManager* context)
98 {
99 if (obj->numPolygonVertices() > 0)
100 {
101 // Object is vertex based, so change the order of the vertices.
102 QVector<Vertex> vertices;
103 vertices.resize(obj->numPolygonVertices());
104
105 for (int i = 0; i < vertices.size(); i += 1)
106 vertices[vertices.size() - 1 - i] = obj->vertex(i);
107
108 for (int i = 0; i < vertices.size(); i += 1)
109 obj->setVertex(i, vertices[i]);
110 }
111 else if (obj->type() == LDObjectType::SubfileReference)
112 {
113 // Check whether subfile is flat. If it is, flip it on the axis on which it is flat.
114 Model model {context};
115 LDSubfileReference* reference = static_cast<LDSubfileReference*>(obj);
116 reference->fileInfo(context)->inlineContents(model, true, false);
117 Axis flatDimension;
118
119 if (::isflat(&model, &flatDimension))
120 {
121 reference->setTransformationMatrix(
122 reference->transformationMatrix() * ::flipmatrix(flatDimension)
123 );
124 }
125 else
126 {
127 // Subfile is not flat. Resort to invertnext.
128 reference->setInverted(not reference->isInverted());
129 }
130 }
131 else if (obj->type() == LDObjectType::CircularPrimitive)
132 {
133 auto primitive = static_cast<LDCircularPrimitive*>(obj);
134
135 if (primitive->isFlat())
136 primitive->setTransformationMatrix(primitive->transformationMatrix() * ::flipmatrix(Y));
137 else
138 primitive->setInverted(not primitive->isInverted());
139 }
140 }
141 #endif
142
143 /*
144 * Inverts the winding of a polygon.
145 */
146 void invertPolygon(gl::Polygon& polygon)
147 {
148 switch (polygon.numPolygonVertices())
149 {
150 case 2:
151 case 3:
152 std::swap(polygon.vertices[0], polygon.vertices[1]);
153 break;
154
155 case 4:
156 std::swap(polygon.vertices[1], polygon.vertices[3]);
157 break;
158 }
159 }

mercurial