src/ldObject.h

changeset 1147
a26568aa3cce
parent 1146
bb728c124d47
child 1148
96cb15a7611f
equal deleted inserted replaced
1146:bb728c124d47 1147:a26568aa3cce
1 /*
2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 - 2017 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 #pragma once
20 #include <type_traits>
21 #include "main.h"
22 #include "basics.h"
23 #include "glShared.h"
24 #include "colors.h"
25
26 class Model;
27 class LDDocument;
28
29 /*
30 * Object type codes.
31 */
32 enum LDObjectType
33 {
34 SubfileReference, // Object represents a sub-file reference
35 Quadrilateral, // Object represents a quadrilateral
36 Triangle, // Object represents a triangle
37 EdgeLine, // Object represents a line
38 ConditionalEdge, // Object represents a conditional line
39 Bfc, // Object represents a BFC statement
40 Comment, // Object represents a comment
41 Error, // Object is the result of failed parsing
42 Empty, // Object represents an empty line
43 BezierCurve, // Object represents a Bézier curve
44 _End
45 };
46
47 MAKE_ITERABLE_ENUM(LDObjectType)
48
49 /*
50 * Represents one line of code in an LDraw model file.
51 */
52 class LDObject : public QObject
53 {
54 Q_OBJECT
55
56 public:
57 virtual QString asText() const = 0; // This object as LDraw code
58 LDColor color() const;
59 virtual LDColor defaultColor() const; // What color does the object default to?
60 Model* model() const;
61 LDPolygon* getPolygon();
62 virtual void getVertices (QSet<Vertex>& verts) const;
63 virtual bool hasMatrix() const; // Does this object have a matrix and position? (see LDMatrixObject)
64 qint32 id() const;
65 virtual void invert(); // Inverts this object (winding is reversed)
66 virtual bool isColored() const;
67 bool isHidden() const;
68 virtual bool isScemantic() const; // Does this object have meaning in the part model?
69 bool isSelected() const;
70 int lineNumber() const;
71 void move (Vertex vect);
72 LDObject* next() const;
73 virtual int numVertices() const;
74 virtual QString objectListText() const;
75 LDObject* previous() const;
76 bool previousIsInvertnext(class LDBfc*& ptr);
77 QColor randomColor() const;
78 void setColor (LDColor color);
79 void setHidden (bool value);
80 void setVertex (int i, const Vertex& vert);
81 void swap (LDObject* other);
82 virtual int triangleCount() const;
83 virtual LDObjectType type() const = 0;
84 virtual QString typeName() const = 0;
85 const Vertex& vertex (int i) const;
86
87 static LDObject* fromID(qint32 id);
88
89 signals:
90 void codeChanged(QString before, QString after);
91
92 protected:
93 friend class Model;
94 LDObject (Model* model = nullptr);
95 virtual ~LDObject();
96 void setDocument(Model* model);
97
98 template<typename T>
99 void changeProperty(T* property, const T& value);
100
101 private:
102 bool m_isHidden;
103 bool m_isSelected;
104 Model* _model;
105 qint32 m_id;
106 LDColor m_color;
107 QColor m_randomColor;
108 Vertex m_coords[4];
109 };
110
111 /*
112 * Base class for objects with matrices.
113 */
114 class LDMatrixObject : public LDObject
115 {
116 Vertex m_position;
117
118 public:
119 const Vertex& position() const;
120 void setCoordinate (const Axis ax, double value);
121 void setPosition (const Vertex& a);
122 void setTransformationMatrix (const Matrix& value);
123 const Matrix& transformationMatrix() const;
124
125 protected:
126 LDMatrixObject (Model* model = nullptr);
127 LDMatrixObject (const Matrix& transformationMatrix, const Vertex& pos, Model* model = nullptr);
128
129 private:
130 Matrix m_transformationMatrix;
131 };
132
133 /*
134 * Represents a line in the LDraw file that could not be properly parsed.
135 */
136 class LDError : public LDObject
137 {
138 public:
139 static constexpr LDObjectType SubclassType = LDObjectType::Error;
140
141 virtual LDObjectType type() const override
142 {
143 return SubclassType;
144 }
145
146 virtual QString asText() const override;
147 virtual void invert() override;
148 QString reason() const;
149 QString contents() const;
150 QString fileReferenced() const;
151 void setFileReferenced (QString value);
152 QString objectListText() const override;
153 bool isColored() const override { return false; }
154 QString typeName() const override { return "error"; }
155
156 protected:
157 friend class Model;
158 LDError (Model* model);
159 LDError (QString contents, QString reason, Model* model = nullptr);
160
161 private:
162 QString m_fileReferenced; // If this error was caused by inability to open a file, what file was that?
163 QString m_contents; // The LDraw code that was being parsed
164 QString m_reason;
165 };
166
167 /*
168 * Represents a 0 BFC statement in the LDraw code.
169 */
170 enum class BfcStatement
171 {
172 CertifyCCW,
173 CCW,
174 CertifyCW,
175 CW,
176 NoCertify,
177 InvertNext,
178 Clip,
179 ClipCCW,
180 ClipCW,
181 NoClip,
182 _End
183 };
184
185 MAKE_ITERABLE_ENUM(BfcStatement)
186
187 class LDBfc : public LDObject
188 {
189 public:
190 static constexpr LDObjectType SubclassType = LDObjectType::Bfc;
191
192 virtual LDObjectType type() const override
193 {
194 return SubclassType;
195 }
196
197 virtual QString asText() const override;
198 virtual void invert() override;
199 protected:
200 friend class Model;
201 LDBfc (Model* model);
202
203 public:
204 bool isScemantic() const override { return statement() == BfcStatement::InvertNext; }
205 QString objectListText() const override;
206 BfcStatement statement() const;
207 void setStatement (BfcStatement value);
208 QString statementToString() const;
209 bool isColored() const override { return false; }
210 QString typeName() const override { return "bfc"; }
211
212 static QString statementToString (BfcStatement statement);
213
214 protected:
215 LDBfc (const BfcStatement type, Model* model = nullptr);
216
217 private:
218 BfcStatement m_statement;
219 };
220
221 /*
222 * Represents a single code-1 subfile reference.
223 */
224 class LDSubfileReference : public LDMatrixObject
225 {
226 public:
227 static constexpr LDObjectType SubclassType = LDObjectType::SubfileReference;
228
229 virtual LDObjectType type() const override
230 {
231 return SubclassType;
232 }
233
234 virtual QString asText() const override;
235 virtual void invert() override;
236 LDDocument* fileInfo() const;
237 virtual void getVertices (QSet<Vertex>& verts) const override;
238 void inlineContents(Model& model, bool deep, bool render);
239 QList<LDPolygon> inlinePolygons();
240 QString objectListText() const override;
241 void setFileInfo (LDDocument* fileInfo);
242 int triangleCount() const override;
243 bool hasMatrix() const override { return true; }
244 QString typeName() const override { return "subfilereference"; }
245
246 protected:
247 friend class Model;
248 LDSubfileReference (Model* model);
249 LDSubfileReference(LDDocument* reference, const Matrix& transformationMatrix, const Vertex& position, Model* model = nullptr);
250
251 private:
252 LDDocument* m_fileInfo;
253 };
254
255 /*
256 * Represents a single code-3 triangle in the LDraw code file.
257 */
258 class LDTriangle : public LDObject
259 {
260 public:
261 static constexpr LDObjectType SubclassType = LDObjectType::Triangle;
262
263 virtual LDObjectType type() const override
264 {
265 return SubclassType;
266 }
267
268 virtual QString asText() const override;
269 virtual void invert() override;
270 int triangleCount() const override;
271 int numVertices() const override { return 3; }
272 QString typeName() const override { return "triangle"; }
273
274 protected:
275 friend class Model;
276 LDTriangle (Model* model);
277 LDTriangle (Vertex const& v1, Vertex const& v2, Vertex const& v3, Model* model = nullptr);
278 };
279
280 /*
281 * Represents a single code-4 quadrilateral.
282 */
283 class LDQuadrilateral : public LDObject
284 {
285 public:
286 static constexpr LDObjectType SubclassType = LDObjectType::Quadrilateral;
287
288 virtual LDObjectType type() const override
289 {
290 return SubclassType;
291 }
292
293 QString asText() const override;
294 void invert() override;
295 int triangleCount() const override;
296 int numVertices() const override { return 4; }
297 QString typeName() const override { return "quad"; }
298
299 protected:
300 friend class Model;
301 LDQuadrilateral (Model* model);
302 LDQuadrilateral (const Vertex& v1, const Vertex& v2, const Vertex& v3, const Vertex& v4, Model* model = nullptr);
303 };
304
305 /*
306 * Models a Bézier curve. It is stored as a special comment in the LDraw code file and can be inlined down into line segments.
307 */
308 class LDBezierCurve : public LDObject
309 {
310 public:
311 static constexpr LDObjectType SubclassType = LDObjectType::BezierCurve;
312
313 virtual LDObjectType type() const override
314 {
315 return SubclassType;
316 }
317
318 virtual QString asText() const override;
319 virtual void invert() override;
320 Vertex pointAt (qreal t) const;
321 void rasterize(Model& model, int segments);
322 QVector<LDPolygon> rasterizePolygons (int segments);
323 int numVertices() const override { return 4; }
324 LDColor defaultColor() const override { return EdgeColor; }
325 QString typeName() const override { return "beziercurve"; }
326
327 protected:
328 friend class Model;
329 LDBezierCurve (Model* model);
330 LDBezierCurve (const Vertex& v0, const Vertex& v1, const Vertex& v2, const Vertex& v3, Model* model = nullptr);
331 };
332
333 enum
334 {
335 LowResolution = 16,
336 HighResolution = 48
337 };
338
339 /*
340 * Changes a property in a manner that emits the appropriate signal to notify that the object changed.
341 */
342 template<typename T>
343 void LDObject::changeProperty(T* property, const T& value)
344 {
345 if (*property != value)
346 {
347 QString before = asText();
348 *property = value;
349 emit codeChanged(before, asText());
350 }
351 }

mercurial