40 m_selected (false), |
40 m_selected (false), |
41 m_parent (null), |
41 m_parent (null), |
42 m_file (null), |
42 m_file (null), |
43 qObjListEntry (null), |
43 qObjListEntry (null), |
44 m_glinit (false) |
44 m_glinit (false) |
45 { |
45 { // Determine ID |
46 // Determine ID |
|
47 int32 id = 1; // 0 is invalid |
46 int32 id = 1; // 0 is invalid |
48 |
47 |
49 for (LDObject* obj : g_LDObjects) |
48 for (LDObject * obj : g_LDObjects) |
50 if (obj->id() >= id) |
49 if (obj->id() >= id) |
51 id = obj->id() + 1; |
50 id = obj->id() + 1; |
52 |
51 |
53 setID (id); |
52 setID (id); |
54 g_LDObjects << this; |
53 g_LDObjects << this; |
55 } |
54 } |
56 |
55 |
57 // ============================================================================= |
56 // ============================================================================= |
58 // Default implementations for LDObject's virtual methods. These should never be |
57 // Default implementations for LDObject's virtual methods. These should never be |
59 // actually called, for a subclass-less LDObject should never come into existance. |
58 // actually called, for a subclass-less LDObject should never come into existance. |
60 // These exist only to satisfy the linker. |
59 // These exist only to satisfy the linker. |
61 // ----------------------------------------------------------------------------- |
60 // ----------------------------------------------------------------------------- |
62 LDObject::Type LDObject::getType() const { |
61 LDObject::Type LDObject::getType() const |
63 return LDObject::Unidentified; |
62 { return LDObject::Unidentified; |
64 } |
63 } |
65 |
64 |
66 bool LDObject::hasMatrix() const { |
65 bool LDObject::hasMatrix() const |
67 return false; |
66 { return false; |
68 } |
67 } |
69 |
68 |
70 bool LDObject::isColored() const { |
69 bool LDObject::isColored() const |
71 return false; |
70 { return false; |
72 } |
71 } |
73 |
72 |
74 bool LDObject::isScemantic() const { |
73 bool LDObject::isScemantic() const |
75 return false; |
74 { return false; |
76 } |
75 } |
77 |
76 |
78 str LDObject::typeName() const { |
77 str LDObject::typeName() const |
79 return ""; |
78 { return ""; |
80 } |
79 } |
81 |
80 |
82 short LDObject::vertices() const { |
81 short LDObject::vertices() const |
83 return 0; |
82 { return 0; |
84 } |
83 } |
85 |
84 |
86 // ============================================================================= |
85 // ============================================================================= |
87 // ----------------------------------------------------------------------------- |
86 // ----------------------------------------------------------------------------- |
88 void LDObject::setVertexCoord (int i, Axis ax, double value) { |
87 void LDObject::setVertexCoord (int i, Axis ax, double value) |
89 vertex v = getVertex (i); |
88 { vertex v = getVertex (i); |
90 v[ax] = value; |
89 v[ax] = value; |
91 setVertex (i, v); |
90 setVertex (i, v); |
92 } |
91 } |
93 |
92 |
94 LDError::LDError() {} |
93 LDError::LDError() {} |
95 |
94 |
96 // ============================================================================= |
95 // ============================================================================= |
97 // ----------------------------------------------------------------------------- |
96 // ----------------------------------------------------------------------------- |
98 str LDComment::raw() { |
97 str LDComment::raw() |
99 return fmt ("0 %1", text); |
98 { return fmt ("0 %1", text); |
100 } |
99 } |
101 |
100 |
102 // ============================================================================= |
101 // ============================================================================= |
103 // ----------------------------------------------------------------------------- |
102 // ----------------------------------------------------------------------------- |
104 str LDSubfile::raw() { |
103 str LDSubfile::raw() |
105 str val = fmt ("1 %1 %2 ", color(), position()); |
104 { str val = fmt ("1 %1 %2 ", color(), position()); |
106 val += transform().stringRep(); |
105 val += transform().stringRep(); |
107 val += ' '; |
106 val += ' '; |
108 val += fileInfo()->name(); |
107 val += fileInfo()->name(); |
109 return val; |
108 return val; |
110 } |
109 } |
111 |
110 |
112 // ============================================================================= |
111 // ============================================================================= |
113 // ----------------------------------------------------------------------------- |
112 // ----------------------------------------------------------------------------- |
114 str LDLine::raw() { |
113 str LDLine::raw() |
115 str val = fmt ("2 %1", color()); |
114 { str val = fmt ("2 %1", color()); |
116 |
115 |
117 for (ushort i = 0; i < 2; ++i) |
116 for (ushort i = 0; i < 2; ++i) |
118 val += fmt (" %1", getVertex (i)); |
117 val += fmt (" %1", getVertex (i)); |
119 |
118 |
120 return val; |
119 return val; |
121 } |
120 } |
122 |
121 |
123 // ============================================================================= |
122 // ============================================================================= |
124 // ----------------------------------------------------------------------------- |
123 // ----------------------------------------------------------------------------- |
125 str LDTriangle::raw() { |
124 str LDTriangle::raw() |
126 str val = fmt ("3 %1", color()); |
125 { str val = fmt ("3 %1", color()); |
127 |
126 |
128 for (ushort i = 0; i < 3; ++i) |
127 for (ushort i = 0; i < 3; ++i) |
129 val += fmt (" %1", getVertex (i)); |
128 val += fmt (" %1", getVertex (i)); |
130 |
129 |
131 return val; |
130 return val; |
132 } |
131 } |
133 |
132 |
134 // ============================================================================= |
133 // ============================================================================= |
135 // ----------------------------------------------------------------------------- |
134 // ----------------------------------------------------------------------------- |
136 str LDQuad::raw() { |
135 str LDQuad::raw() |
137 str val = fmt ("4 %1", color()); |
136 { str val = fmt ("4 %1", color()); |
138 |
137 |
139 for (ushort i = 0; i < 4; ++i) |
138 for (ushort i = 0; i < 4; ++i) |
140 val += fmt (" %1", getVertex (i)); |
139 val += fmt (" %1", getVertex (i)); |
141 |
140 |
142 return val; |
141 return val; |
143 } |
142 } |
144 |
143 |
145 // ============================================================================= |
144 // ============================================================================= |
146 // ----------------------------------------------------------------------------- |
145 // ----------------------------------------------------------------------------- |
147 str LDCndLine::raw() { |
146 str LDCndLine::raw() |
148 str val = fmt ("5 %1", color()); |
147 { str val = fmt ("5 %1", color()); |
149 |
148 |
150 // Add the coordinates |
149 // Add the coordinates |
151 for (ushort i = 0; i < 4; ++i) |
150 for (ushort i = 0; i < 4; ++i) |
152 val += fmt (" %1", getVertex (i)); |
151 val += fmt (" %1", getVertex (i)); |
153 |
152 |
154 return val; |
153 return val; |
155 } |
154 } |
156 |
155 |
157 // ============================================================================= |
156 // ============================================================================= |
158 // ----------------------------------------------------------------------------- |
157 // ----------------------------------------------------------------------------- |
159 str LDError::raw() { |
158 str LDError::raw() |
160 return contents; |
159 { return contents; |
161 } |
160 } |
162 |
161 |
163 // ============================================================================= |
162 // ============================================================================= |
164 // ----------------------------------------------------------------------------- |
163 // ----------------------------------------------------------------------------- |
165 str LDVertex::raw() { |
164 str LDVertex::raw() |
166 return fmt ("0 !LDFORGE VERTEX %1 %2", color(), pos); |
165 { return fmt ("0 !LDFORGE VERTEX %1 %2", color(), pos); |
167 } |
166 } |
168 |
167 |
169 // ============================================================================= |
168 // ============================================================================= |
170 // ----------------------------------------------------------------------------- |
169 // ----------------------------------------------------------------------------- |
171 str LDEmpty::raw() { |
170 str LDEmpty::raw() |
172 return ""; |
171 { return ""; |
173 } |
172 } |
174 |
173 |
175 // ============================================================================= |
174 // ============================================================================= |
176 // ----------------------------------------------------------------------------- |
175 // ----------------------------------------------------------------------------- |
177 const char* LDBFC::statements[] = { |
176 const char* LDBFC::statements[] = |
178 "CERTIFY CCW", |
177 { "CERTIFY CCW", |
179 "CCW", |
178 "CCW", |
180 "CERTIFY CW", |
179 "CERTIFY CW", |
181 "CW", |
180 "CW", |
182 "NOCERTIFY", |
181 "NOCERTIFY", |
183 "INVERTNEXT", |
182 "INVERTNEXT", |
185 "CLIP CCW", |
184 "CLIP CCW", |
186 "CLIP CW", |
185 "CLIP CW", |
187 "NOCLIP", |
186 "NOCLIP", |
188 }; |
187 }; |
189 |
188 |
190 str LDBFC::raw() { |
189 str LDBFC::raw() |
191 return fmt ("0 BFC %1", LDBFC::statements[type]); |
190 { return fmt ("0 BFC %1", LDBFC::statements[type]); |
192 } |
191 } |
193 |
192 |
194 // ============================================================================= |
193 // ============================================================================= |
195 // ----------------------------------------------------------------------------- |
194 // ----------------------------------------------------------------------------- |
196 List<LDTriangle*> LDQuad::splitToTriangles() { |
195 List<LDTriangle*> LDQuad::splitToTriangles() |
197 // Create the two triangles based on this quadrilateral: |
196 { // Create the two triangles based on this quadrilateral: |
198 // 0---3 0---3 3 |
197 // 0---3 0---3 3 |
199 // | | | / /| |
198 // | | | / /| |
200 // | | ==> | / / | |
199 // | | ==> | / / | |
201 // | | |/ / | |
200 // | | |/ / | |
202 // 1---2 1 1---2 |
201 // 1---2 1 1---2 |
203 LDTriangle* tri1 = new LDTriangle (getVertex (0), getVertex (1), getVertex (3)); |
202 LDTriangle* tri1 = new LDTriangle (getVertex (0), getVertex (1), getVertex (3)); |
204 LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3)); |
203 LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3)); |
205 |
204 |
206 // The triangles also inherit the quad's color |
205 // The triangles also inherit the quad's color |
207 tri1->setColor (color()); |
206 tri1->setColor (color()); |
208 tri2->setColor (color()); |
207 tri2->setColor (color()); |
209 |
208 |
210 List<LDTriangle*> triangles; |
209 List<LDTriangle*> triangles; |
211 triangles << tri1; |
210 triangles << tri1; |
212 triangles << tri2; |
211 triangles << tri2; |
213 return triangles; |
212 return triangles; |
214 } |
213 } |
215 |
214 |
216 // ============================================================================= |
215 // ============================================================================= |
217 // ----------------------------------------------------------------------------- |
216 // ----------------------------------------------------------------------------- |
218 void LDObject::replace (LDObject* other) { |
217 void LDObject::replace (LDObject* other) |
219 long idx = getIndex(); |
218 { long idx = getIndex(); |
220 assert (idx != -1); |
219 assert (idx != -1); |
221 |
220 |
222 // Replace the instance of the old object with the new object |
221 // Replace the instance of the old object with the new object |
223 file()->setObject (idx, other); |
222 file()->setObject (idx, other); |
224 |
223 |
225 // Remove the old object |
224 // Remove the old object |
226 delete this; |
225 delete this; |
227 } |
226 } |
228 |
227 |
229 // ============================================================================= |
228 // ============================================================================= |
230 // ----------------------------------------------------------------------------- |
229 // ----------------------------------------------------------------------------- |
231 void LDObject::swap (LDObject* other) { |
230 void LDObject::swap (LDObject* other) |
232 int i = 0; |
231 { int i = 0; |
233 for (LDObject* obj : file()->objects()) { |
232 |
234 if (obj == this) |
233 for (LDObject * obj : file()->objects()) |
|
234 { if (obj == this) |
235 file()->setObject (i, other); |
235 file()->setObject (i, other); |
|
236 |
236 elif (obj == other) |
237 elif (obj == other) |
237 file()->setObject (i, this); |
238 file()->setObject (i, this); |
238 |
239 |
239 ++i; |
240 ++i; |
240 } |
241 } |
241 |
242 |
242 file()->addToHistory (new SwapHistory (id(), other->id())); |
243 file()->addToHistory (new SwapHistory (id(), other->id())); |
243 } |
244 } |
244 |
245 |
245 // ============================================================================= |
246 // ============================================================================= |
246 // ----------------------------------------------------------------------------- |
247 // ----------------------------------------------------------------------------- |
247 LDLine::LDLine (vertex v1, vertex v2) { |
248 LDLine::LDLine (vertex v1, vertex v2) |
248 setVertex (0, v1); |
249 { setVertex (0, v1); |
249 setVertex (1, v2); |
250 setVertex (1, v2); |
250 } |
251 } |
251 |
252 |
252 // ============================================================================= |
253 // ============================================================================= |
253 // ----------------------------------------------------------------------------- |
254 // ----------------------------------------------------------------------------- |
254 LDObject::~LDObject() { |
255 LDObject::~LDObject() |
255 // Remove this object from the selection array if it is there. |
256 { // Remove this object from the selection array if it is there. |
256 for (ulong i = 0; i < g_win->sel().size(); ++i) |
257 for (ulong i = 0; i < g_win->sel().size(); ++i) |
257 if (g_win->sel() [i] == this) |
258 if (g_win->sel() [i] == this) |
258 g_win->sel().erase (i); |
259 g_win->sel().erase (i); |
259 |
260 |
260 // Delete the GL lists |
261 // Delete the GL lists |
261 GL::deleteLists (this); |
262 GL::deleteLists (this); |
262 |
263 |
263 // Remove this object from the list of LDObjects |
264 // Remove this object from the list of LDObjects |
264 ulong pos = g_LDObjects.find (this); |
265 ulong pos = g_LDObjects.find (this); |
265 |
266 |
266 if (pos < g_LDObjects.size()) |
267 if (pos < g_LDObjects.size()) |
267 g_LDObjects.erase (pos); |
268 g_LDObjects.erase (pos); |
268 } |
269 } |
269 |
270 |
270 // ============================================================================= |
271 // ============================================================================= |
271 // ----------------------------------------------------------------------------- |
272 // ----------------------------------------------------------------------------- |
272 static void transformObject (LDObject* obj, matrix transform, vertex pos, short parentcolor) { |
273 static void transformObject (LDObject* obj, matrix transform, vertex pos, short parentcolor) |
273 switch (obj->getType()) { |
274 { switch (obj->getType()) |
274 case LDObject::Line: |
275 { case LDObject::Line: |
275 case LDObject::CndLine: |
276 case LDObject::CndLine: |
276 case LDObject::Triangle: |
277 case LDObject::Triangle: |
277 case LDObject::Quad: |
278 case LDObject::Quad: |
278 for (short i = 0; i < obj->vertices(); ++i) { |
279 |
279 vertex v = obj->getVertex (i); |
280 for (short i = 0; i < obj->vertices(); ++i) |
280 v.transform (transform, pos); |
281 { vertex v = obj->getVertex (i); |
281 obj->setVertex (i, v); |
282 v.transform (transform, pos); |
282 } |
283 obj->setVertex (i, v); |
283 |
284 } |
284 break; |
285 |
285 |
286 break; |
286 case LDObject::Subfile: |
287 |
287 { |
288 case LDObject::Subfile: |
288 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
289 { LDSubfile* ref = static_cast<LDSubfile*> (obj); |
289 matrix newMatrix = transform * ref->transform(); |
290 matrix newMatrix = transform * ref->transform(); |
290 vertex newpos = ref->position(); |
291 vertex newpos = ref->position(); |
291 |
292 |
292 newpos.transform (transform, pos); |
293 newpos.transform (transform, pos); |
293 ref->setPosition (newpos); |
294 ref->setPosition (newpos); |
294 ref->setTransform (newMatrix); |
295 ref->setTransform (newMatrix); |
295 } |
296 } |
296 break; |
297 break; |
297 |
298 |
298 default: |
299 default: |
299 break; |
300 break; |
300 } |
301 } |
301 |
302 |
302 if (obj->color() == maincolor) |
303 if (obj->color() == maincolor) |
303 obj->setColor (parentcolor); |
304 obj->setColor (parentcolor); |
304 } |
305 } |
305 |
306 |
306 // ============================================================================= |
307 // ============================================================================= |
307 // ----------------------------------------------------------------------------- |
308 // ----------------------------------------------------------------------------- |
308 List<LDObject*> LDSubfile::inlineContents (InlineFlags flags) { |
309 List<LDObject*> LDSubfile::inlineContents (InlineFlags flags) |
309 List<LDObject*> objs = fileInfo()->inlineContents (flags); |
310 { List<LDObject*> objs = fileInfo()->inlineContents (flags); |
310 |
311 |
311 // Transform the objects |
312 // Transform the objects |
312 for (LDObject* obj : objs) { |
313 for (LDObject * obj : objs) |
313 // Set the parent now so we know what inlined this. |
314 { // Set the parent now so we know what inlined this. |
314 obj->setParent (this); |
315 obj->setParent (this); |
315 transformObject (obj, transform(), position(), color()); |
316 transformObject (obj, transform(), position(), color()); |
316 } |
317 } |
317 |
318 |
318 return objs; |
319 return objs; |
319 } |
320 } |
320 |
321 |
321 // ============================================================================= |
322 // ============================================================================= |
322 // ----------------------------------------------------------------------------- |
323 // ----------------------------------------------------------------------------- |
323 long LDObject::getIndex() const { |
324 long LDObject::getIndex() const |
|
325 { |
324 #ifndef RELEASE |
326 #ifndef RELEASE |
325 assert (file() != null); |
327 assert (file() != null); |
326 #endif |
328 #endif |
327 |
329 |
328 for (ulong i = 0; i < file()->numObjs(); ++i) |
330 for (ulong i = 0; i < file()->numObjs(); ++i) |
329 if (file()->obj (i) == this) |
331 if (file()->obj (i) == this) |
330 return i; |
332 return i; |
331 |
333 |
332 return -1; |
334 return -1; |
333 } |
335 } |
334 |
336 |
335 // ============================================================================= |
337 // ============================================================================= |
336 // ----------------------------------------------------------------------------- |
338 // ----------------------------------------------------------------------------- |
337 void LDObject::moveObjects (List<LDObject*> objs, const bool up) { |
339 void LDObject::moveObjects (List<LDObject*> objs, const bool up) |
338 if (objs.size() == 0) |
340 { if (objs.size() == 0) |
339 return; |
341 return; |
340 |
342 |
341 // If we move down, we need to iterate the array in reverse order. |
343 // If we move down, we need to iterate the array in reverse order. |
342 const long start = up ? 0 : (objs.size() - 1); |
344 const long start = up ? 0 : (objs.size() - 1); |
343 const long end = up ? objs.size() : -1; |
345 const long end = up ? objs.size() : -1; |
344 const long incr = up ? 1 : -1; |
346 const long incr = up ? 1 : -1; |
345 List<LDObject*> objsToCompile; |
347 List<LDObject*> objsToCompile; |
346 LDFile* file = objs[0]->file(); |
348 LDFile* file = objs[0]->file(); |
347 |
349 |
348 for (long i = start; i != end; i += incr) { |
350 for (long i = start; i != end; i += incr) |
349 LDObject* obj = objs[i]; |
351 { LDObject* obj = objs[i]; |
350 |
352 |
351 const long idx = obj->getIndex(), |
353 const long idx = obj->getIndex(), |
352 target = idx + (up ? -1 : 1); |
354 target = idx + (up ? -1 : 1); |
353 |
355 |
354 if ((up && idx == 0) || (!up && idx == (long) (file->objects().size() - 1))) { |
356 if ( (up && idx == 0) || (!up && idx == (long) (file->objects().size() - 1))) |
355 // One of the objects hit the extrema. If this happens, this should be the first |
357 { // One of the objects hit the extrema. If this happens, this should be the first |
356 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
358 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
357 // abort the entire operation. |
359 // abort the entire operation. |
358 assert (i == start); |
360 assert (i == start); |
359 return; |
361 return; |
360 } |
362 } |
361 |
363 |
362 objsToCompile << obj; |
364 objsToCompile << obj; |
363 objsToCompile << file->obj (target); |
365 objsToCompile << file->obj (target); |
364 |
366 |
365 obj->swap (file->obj (target)); |
367 obj->swap (file->obj (target)); |
366 } |
368 } |
367 |
369 |
368 objsToCompile.makeUnique(); |
370 objsToCompile.makeUnique(); |
369 |
371 |
370 // The objects need to be recompiled, otherwise their pick lists are left with |
372 // The objects need to be recompiled, otherwise their pick lists are left with |
371 // the wrong index colors which messes up selection. |
373 // the wrong index colors which messes up selection. |
372 for (LDObject* obj : objsToCompile) |
374 for (LDObject * obj : objsToCompile) |
373 g_win->R()->compileObject (obj); |
375 g_win->R()->compileObject (obj); |
374 } |
376 } |
375 |
377 |
376 // ============================================================================= |
378 // ============================================================================= |
377 // ----------------------------------------------------------------------------- |
379 // ----------------------------------------------------------------------------- |
378 str LDObject::typeName (LDObject::Type type) { |
380 str LDObject::typeName (LDObject::Type type) |
379 LDObject* obj = LDObject::getDefault (type); |
381 { LDObject* obj = LDObject::getDefault (type); |
380 str name = obj->typeName(); |
382 str name = obj->typeName(); |
381 delete obj; |
383 delete obj; |
382 return name; |
384 return name; |
383 } |
385 } |
384 |
386 |
385 // ============================================================================= |
387 // ============================================================================= |
386 // ----------------------------------------------------------------------------- |
388 // ----------------------------------------------------------------------------- |
387 str LDObject::objectListContents (const List<LDObject*>& objs) { |
389 str LDObject::objectListContents (const List<LDObject*>& objs) |
388 bool firstDetails = true; |
390 { bool firstDetails = true; |
389 str text = ""; |
391 str text = ""; |
390 |
392 |
391 if (objs.size() == 0) |
393 if (objs.size() == 0) |
392 return "nothing"; // :) |
394 return "nothing"; // :) |
393 |
395 |
394 for (long i = 0; i < LDObject::NumTypes; ++i) { |
396 for (long i = 0; i < LDObject::NumTypes; ++i) |
395 LDObject::Type objType = (LDObject::Type) i; |
397 { LDObject::Type objType = (LDObject::Type) i; |
396 ulong objCount = 0; |
398 ulong objCount = 0; |
397 |
399 |
398 for (LDObject* obj : objs) |
400 for (LDObject * obj : objs) |
399 if (obj->getType() == objType) |
401 if (obj->getType() == objType) |
400 objCount++; |
402 objCount++; |
401 |
403 |
402 if (objCount == 0) |
404 if (objCount == 0) |
403 continue; |
405 continue; |
404 |
406 |
405 if (!firstDetails) |
407 if (!firstDetails) |
406 text += ", "; |
408 text += ", "; |
407 |
409 |
408 str noun = fmt ("%1%2", typeName (objType), plural (objCount)); |
410 str noun = fmt ("%1%2", typeName (objType), plural (objCount)); |
409 |
411 |
410 // Plural of "vertex" is "vertices". Stupid English. |
412 // Plural of "vertex" is "vertices". Stupid English. |
411 if (objType == LDObject::Vertex && objCount != 1) |
413 if (objType == LDObject::Vertex && objCount != 1) |
412 noun = "vertices"; |
414 noun = "vertices"; |
413 |
415 |
414 text += fmt ("%1 %2", objCount, noun); |
416 text += fmt ("%1 %2", objCount, noun); |
415 firstDetails = false; |
417 firstDetails = false; |
416 } |
418 } |
417 |
419 |
418 return text; |
420 return text; |
419 } |
421 } |
420 |
422 |
421 // ============================================================================= |
423 // ============================================================================= |
422 // ----------------------------------------------------------------------------- |
424 // ----------------------------------------------------------------------------- |
423 LDObject* LDObject::topLevelParent() { |
425 LDObject* LDObject::topLevelParent() |
424 if (!parent()) |
426 { if (!parent()) |
425 return this; |
427 return this; |
426 |
428 |
427 LDObject* it = this; |
429 LDObject* it = this; |
428 |
430 |
429 while (it->parent()) |
431 while (it->parent()) |
430 it = it->parent(); |
432 it = it->parent(); |
431 |
433 |
432 return it; |
434 return it; |
433 } |
435 } |
434 |
436 |
435 // ============================================================================= |
437 // ============================================================================= |
436 // ----------------------------------------------------------------------------- |
438 // ----------------------------------------------------------------------------- |
437 LDObject* LDObject::next() const { |
439 LDObject* LDObject::next() const |
438 long idx = getIndex(); |
440 { long idx = getIndex(); |
439 assert (idx != -1); |
441 assert (idx != -1); |
440 |
442 |
441 if (idx == (long) file()->numObjs() - 1) |
443 if (idx == (long) file()->numObjs() - 1) |
442 return null; |
444 return null; |
443 |
445 |
444 return file()->obj (idx + 1); |
446 return file()->obj (idx + 1); |
445 } |
447 } |
446 |
448 |
447 // ============================================================================= |
449 // ============================================================================= |
448 // ----------------------------------------------------------------------------- |
450 // ----------------------------------------------------------------------------- |
449 LDObject* LDObject::prev() const { |
451 LDObject* LDObject::prev() const |
450 long idx = getIndex(); |
452 { long idx = getIndex(); |
451 assert (idx != -1); |
453 assert (idx != -1); |
452 |
454 |
453 if (idx == 0) |
455 if (idx == 0) |
454 return null; |
456 return null; |
455 |
457 |
456 return file()->obj (idx - 1); |
458 return file()->obj (idx - 1); |
457 } |
459 } |
458 |
460 |
459 // ============================================================================= |
461 // ============================================================================= |
460 // ----------------------------------------------------------------------------- |
462 // ----------------------------------------------------------------------------- |
461 void LDObject::move (vertex vect) { (void) vect; } |
463 void LDObject::move (vertex vect) |
462 void LDEmpty::move (vertex vect) { (void) vect; } |
464 { (void) vect; |
463 void LDBFC::move (vertex vect) { (void) vect; } |
465 } |
464 void LDComment::move (vertex vect) { (void) vect; } |
466 void LDEmpty::move (vertex vect) |
465 void LDError::move (vertex vect) { (void) vect; } |
467 { (void) vect; |
466 |
468 } |
467 // ============================================================================= |
469 void LDBFC::move (vertex vect) |
468 // ----------------------------------------------------------------------------- |
470 { (void) vect; |
469 void LDVertex::move (vertex vect) { |
471 } |
470 pos += vect; |
472 void LDComment::move (vertex vect) |
471 } |
473 { (void) vect; |
472 |
474 } |
473 // ============================================================================= |
475 void LDError::move (vertex vect) |
474 // ----------------------------------------------------------------------------- |
476 { (void) vect; |
475 void LDSubfile::move (vertex vect) { |
477 } |
476 setPosition (position() + vect); |
478 |
477 } |
479 // ============================================================================= |
478 |
480 // ----------------------------------------------------------------------------- |
479 // ============================================================================= |
481 void LDVertex::move (vertex vect) |
480 // ----------------------------------------------------------------------------- |
482 { pos += vect; |
481 void LDLine::move (vertex vect) { |
483 } |
482 for (short i = 0; i < 2; ++i) |
484 |
|
485 // ============================================================================= |
|
486 // ----------------------------------------------------------------------------- |
|
487 void LDSubfile::move (vertex vect) |
|
488 { setPosition (position() + vect); |
|
489 } |
|
490 |
|
491 // ============================================================================= |
|
492 // ----------------------------------------------------------------------------- |
|
493 void LDLine::move (vertex vect) |
|
494 { for (short i = 0; i < 2; ++i) |
483 setVertex (i, getVertex (i) + vect); |
495 setVertex (i, getVertex (i) + vect); |
484 } |
496 } |
485 |
497 |
486 // ============================================================================= |
498 // ============================================================================= |
487 // ----------------------------------------------------------------------------- |
499 // ----------------------------------------------------------------------------- |
488 void LDTriangle::move (vertex vect) { |
500 void LDTriangle::move (vertex vect) |
489 for (short i = 0; i < 3; ++i) |
501 { for (short i = 0; i < 3; ++i) |
490 setVertex (i, getVertex (i) + vect); |
502 setVertex (i, getVertex (i) + vect); |
491 } |
503 } |
492 |
504 |
493 // ============================================================================= |
505 // ============================================================================= |
494 // ----------------------------------------------------------------------------- |
506 // ----------------------------------------------------------------------------- |
495 void LDQuad::move (vertex vect) { |
507 void LDQuad::move (vertex vect) |
496 for (short i = 0; i < 4; ++i) |
508 { for (short i = 0; i < 4; ++i) |
497 setVertex (i, getVertex (i) + vect); |
509 setVertex (i, getVertex (i) + vect); |
498 } |
510 } |
499 |
511 |
500 // ============================================================================= |
512 // ============================================================================= |
501 // ----------------------------------------------------------------------------- |
513 // ----------------------------------------------------------------------------- |
502 void LDCndLine::move (vertex vect) { |
514 void LDCndLine::move (vertex vect) |
503 for (short i = 0; i < 4; ++i) |
515 { for (short i = 0; i < 4; ++i) |
504 setVertex (i, getVertex (i) + vect); |
516 setVertex (i, getVertex (i) + vect); |
505 } |
517 } |
506 |
518 |
507 // ============================================================================= |
519 // ============================================================================= |
508 // ----------------------------------------------------------------------------- |
520 // ----------------------------------------------------------------------------- |
509 #define CHECK_FOR_OBJ(N) \ |
521 #define CHECK_FOR_OBJ(N) \ |
510 if (type == LDObject::N) \ |
522 if (type == LDObject::N) \ |
511 return new LD##N; |
523 return new LD##N; |
512 |
524 |
513 LDObject* LDObject::getDefault (const LDObject::Type type) { |
525 LDObject* LDObject::getDefault (const LDObject::Type type) |
514 CHECK_FOR_OBJ (Comment) |
526 { CHECK_FOR_OBJ (Comment) |
515 CHECK_FOR_OBJ (BFC) |
527 CHECK_FOR_OBJ (BFC) |
516 CHECK_FOR_OBJ (Line) |
528 CHECK_FOR_OBJ (Line) |
517 CHECK_FOR_OBJ (CndLine) |
529 CHECK_FOR_OBJ (CndLine) |
518 CHECK_FOR_OBJ (Subfile) |
530 CHECK_FOR_OBJ (Subfile) |
519 CHECK_FOR_OBJ (Triangle) |
531 CHECK_FOR_OBJ (Triangle) |
534 void LDComment::invert() {} |
546 void LDComment::invert() {} |
535 void LDError::invert() {} |
547 void LDError::invert() {} |
536 |
548 |
537 // ============================================================================= |
549 // ============================================================================= |
538 // ----------------------------------------------------------------------------- |
550 // ----------------------------------------------------------------------------- |
539 void LDTriangle::invert() { |
551 void LDTriangle::invert() |
540 // Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1. |
552 { // Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1. |
541 // Thus, we swap 1 and 2. |
553 // Thus, we swap 1 and 2. |
542 vertex tmp = getVertex (1); |
554 vertex tmp = getVertex (1); |
543 setVertex (1, getVertex (2)); |
555 setVertex (1, getVertex (2)); |
544 setVertex (2, tmp); |
556 setVertex (2, tmp); |
545 |
557 |
546 return; |
558 return; |
547 } |
559 } |
548 |
560 |
549 // ============================================================================= |
561 // ============================================================================= |
550 // ----------------------------------------------------------------------------- |
562 // ----------------------------------------------------------------------------- |
551 void LDQuad::invert() { |
563 void LDQuad::invert() |
552 // Quad: 0 -> 1 -> 2 -> 3 |
564 { // Quad: 0 -> 1 -> 2 -> 3 |
553 // rev: 0 -> 3 -> 2 -> 1 |
565 // rev: 0 -> 3 -> 2 -> 1 |
554 // Thus, we swap 1 and 3. |
566 // Thus, we swap 1 and 3. |
555 vertex tmp = getVertex (1); |
567 vertex tmp = getVertex (1); |
556 setVertex (1, getVertex (3)); |
568 setVertex (1, getVertex (3)); |
557 setVertex (3, tmp); |
569 setVertex (3, tmp); |
558 } |
570 } |
559 |
571 |
560 // ============================================================================= |
572 // ============================================================================= |
561 // ----------------------------------------------------------------------------- |
573 // ----------------------------------------------------------------------------- |
562 void LDSubfile::invert() { |
574 void LDSubfile::invert() |
563 // Subfiles are inverted when they're prefixed with |
575 { // Subfiles are inverted when they're prefixed with |
564 // a BFC INVERTNEXT statement. Thus we need to toggle this status. |
576 // a BFC INVERTNEXT statement. Thus we need to toggle this status. |
565 // For flat primitives it's sufficient that the determinant is |
577 // For flat primitives it's sufficient that the determinant is |
566 // flipped but I don't have a method for checking flatness yet. |
578 // flipped but I don't have a method for checking flatness yet. |
567 // Food for thought... |
579 // Food for thought... |
568 |
580 |
569 ulong idx = getIndex(); |
581 ulong idx = getIndex(); |
570 |
582 |
571 if (idx > 0) { |
583 if (idx > 0) |
572 LDBFC* bfc = dynamic_cast<LDBFC*> (prev()); |
584 { LDBFC* bfc = dynamic_cast<LDBFC*> (prev()); |
573 |
585 |
574 if (bfc && bfc->type == LDBFC::InvertNext) { |
586 if (bfc && bfc->type == LDBFC::InvertNext) |
575 // This is prefixed with an invertnext, thus remove it. |
587 { // This is prefixed with an invertnext, thus remove it. |
576 file()->forgetObject (bfc); |
588 file()->forgetObject (bfc); |
577 delete bfc; |
589 delete bfc; |
578 return; |
590 return; |
579 } |
591 } |
580 } |
592 } |
581 |
593 |
582 // Not inverted, thus prefix it with a new invertnext. |
594 // Not inverted, thus prefix it with a new invertnext. |
583 LDBFC* bfc = new LDBFC (LDBFC::InvertNext); |
595 LDBFC* bfc = new LDBFC (LDBFC::InvertNext); |
584 file()->insertObj (idx, bfc); |
596 file()->insertObj (idx, bfc); |
585 } |
597 } |
586 |
598 |
587 // ============================================================================= |
599 // ============================================================================= |
588 // ----------------------------------------------------------------------------- |
600 // ----------------------------------------------------------------------------- |
589 static void invertLine (LDObject* line) { |
601 static void invertLine (LDObject* line) |
590 // For lines, we swap the vertices. I don't think that a |
602 { // For lines, we swap the vertices. I don't think that a |
591 // cond-line's control points need to be swapped, do they? |
603 // cond-line's control points need to be swapped, do they? |
592 vertex tmp = line->getVertex (0); |
604 vertex tmp = line->getVertex (0); |
593 line->setVertex (0, line->getVertex (1)); |
605 line->setVertex (0, line->getVertex (1)); |
594 line->setVertex (1, tmp); |
606 line->setVertex (1, tmp); |
595 } |
607 } |
596 |
608 |
597 void LDLine::invert() { |
609 void LDLine::invert() |
598 invertLine (this); |
610 { invertLine (this); |
599 } |
611 } |
600 |
612 |
601 void LDCndLine::invert() { |
613 void LDCndLine::invert() |
602 invertLine (this); |
614 { invertLine (this); |
603 } |
615 } |
604 |
616 |
605 void LDVertex::invert() {} |
617 void LDVertex::invert() {} |
606 |
618 |
607 // ============================================================================= |
619 // ============================================================================= |
608 // ----------------------------------------------------------------------------- |
620 // ----------------------------------------------------------------------------- |
609 LDLine* LDCndLine::demote() { |
621 LDLine* LDCndLine::demote() |
610 LDLine* repl = new LDLine; |
622 { LDLine* repl = new LDLine; |
611 |
623 |
612 for (int i = 0; i < repl->vertices(); ++i) |
624 for (int i = 0; i < repl->vertices(); ++i) |
613 repl->setVertex (i, getVertex (i)); |
625 repl->setVertex (i, getVertex (i)); |
614 |
626 |
615 repl->setColor (color()); |
627 repl->setColor (color()); |
616 |
628 |
617 replace (repl); |
629 replace (repl); |
618 return repl; |
630 return repl; |
619 } |
631 } |
620 |
632 |
621 // ============================================================================= |
633 // ============================================================================= |
622 // ----------------------------------------------------------------------------- |
634 // ----------------------------------------------------------------------------- |
623 LDObject* LDObject::fromID (int id) { |
635 LDObject* LDObject::fromID (int id) |
624 for (LDObject* obj : g_LDObjects) |
636 { for (LDObject * obj : g_LDObjects) |
625 if (obj->id() == id) |
637 if (obj->id() == id) |
626 return obj; |
638 return obj; |
627 |
639 |
628 return null; |
640 return null; |
629 } |
641 } |
630 |
642 |
631 // ============================================================================= |
643 // ============================================================================= |
632 // ----------------------------------------------------------------------------- |
644 // ----------------------------------------------------------------------------- |
633 str LDOverlay::raw() { |
645 str LDOverlay::raw() |
634 return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", |
646 { return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", |
635 filename(), camera(), x(), y(), width(), height()); |
647 filename(), camera(), x(), y(), width(), height()); |
636 } |
648 } |
637 |
649 |
638 void LDOverlay::move (vertex vect) { |
650 void LDOverlay::move (vertex vect) |
639 Q_UNUSED (vect) |
651 { Q_UNUSED (vect) |
640 } |
652 } |
641 |
653 |
642 void LDOverlay::invert() {} |
654 void LDOverlay::invert() {} |
643 |
655 |
644 // ============================================================================= |
656 // ============================================================================= |
645 // Hook the set accessors of certain properties to this changeProperty function. |
657 // Hook the set accessors of certain properties to this changeProperty function. |
646 // It takes care of history management so we can capture low-level changes, this |
658 // It takes care of history management so we can capture low-level changes, this |
647 // makes history stuff work out of the box. |
659 // makes history stuff work out of the box. |
648 // ----------------------------------------------------------------------------- |
660 // ----------------------------------------------------------------------------- |
649 template<class T> void changeProperty (LDObject* obj, T* ptr, const T& val) { |
661 template<class T> void changeProperty (LDObject* obj, T* ptr, const T& val) |
650 long idx; |
662 { long idx; |
651 |
663 |
652 if (obj->file() && (idx = obj->getIndex()) != -1) { |
664 if (obj->file() && (idx = obj->getIndex()) != -1) |
653 str before = obj->raw(); |
665 { str before = obj->raw(); |
654 *ptr = val; |
666 *ptr = val; |
655 str after = obj->raw(); |
667 str after = obj->raw(); |
656 |
668 |
657 obj->file()->addToHistory (new EditHistory (idx, before, after)); |
669 obj->file()->addToHistory (new EditHistory (idx, before, after)); |
658 } else |
670 } |
|
671 else |
659 *ptr = val; |
672 *ptr = val; |
660 } |
673 } |
661 |
674 |
662 // ============================================================================= |
675 // ============================================================================= |
663 // ----------------------------------------------------------------------------- |
676 // ----------------------------------------------------------------------------- |
664 READ_ACCESSOR (short, LDObject::color) { |
677 READ_ACCESSOR (short, LDObject::color) |
665 return m_color; |
678 { return m_color; |
666 } |
679 } |
667 |
680 |
668 SET_ACCESSOR (short, LDObject::setColor) { |
681 SET_ACCESSOR (short, LDObject::setColor) |
669 changeProperty (this, &m_color, val); |
682 { changeProperty (this, &m_color, val); |
670 } |
683 } |
671 |
684 |
672 // ============================================================================= |
685 // ============================================================================= |
673 // ----------------------------------------------------------------------------- |
686 // ----------------------------------------------------------------------------- |
674 const vertex& LDObject::getVertex (int i) const { |
687 const vertex& LDObject::getVertex (int i) const |
675 return m_coords[i]; |
688 { return m_coords[i]; |
676 } |
689 } |
677 |
690 |
678 void LDObject::setVertex (int i, const vertex& vert) { |
691 void LDObject::setVertex (int i, const vertex& vert) |
679 changeProperty (this, &m_coords[i], vert); |
692 { changeProperty (this, &m_coords[i], vert); |
680 } |
693 } |
681 |
694 |
682 // ============================================================================= |
695 // ============================================================================= |
683 // ----------------------------------------------------------------------------- |
696 // ----------------------------------------------------------------------------- |
684 READ_ACCESSOR (vertex, LDMatrixObject::position) { |
697 READ_ACCESSOR (vertex, LDMatrixObject::position) |
685 return m_position; |
698 { return m_position; |
686 } |
699 } |
687 |
700 |
688 SET_ACCESSOR (vertex, LDMatrixObject::setPosition) { |
701 SET_ACCESSOR (vertex, LDMatrixObject::setPosition) |
689 changeProperty (linkPointer(), &m_position, val); |
702 { changeProperty (linkPointer(), &m_position, val); |
690 } |
703 } |
691 |
704 |
692 // ============================================================================= |
705 // ============================================================================= |
693 // ----------------------------------------------------------------------------- |
706 // ----------------------------------------------------------------------------- |
694 READ_ACCESSOR (matrix, LDMatrixObject::transform) { |
707 READ_ACCESSOR (matrix, LDMatrixObject::transform) |
695 return m_transform; |
708 { return m_transform; |
696 } |
709 } |
697 |
710 |
698 SET_ACCESSOR (matrix, LDMatrixObject::setTransform) { |
711 SET_ACCESSOR (matrix, LDMatrixObject::setTransform) |
699 changeProperty (linkPointer(), &m_transform, val); |
712 { changeProperty (linkPointer(), &m_transform, val); |
700 } |
713 } |