34 |
34 |
35 // ============================================================================= |
35 // ============================================================================= |
36 // LDObject constructors |
36 // LDObject constructors |
37 // ----------------------------------------------------------------------------- |
37 // ----------------------------------------------------------------------------- |
38 LDObject::LDObject() : |
38 LDObject::LDObject() : |
39 m_hidden (false), |
39 m_Hidden (false), |
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 { |
46 memset (m_coords, 0, sizeof m_coords); |
46 memset (m_coords, 0, sizeof m_coords); |
47 |
47 |
48 // Determine ID |
48 // Determine ID |
49 int32 id = 1; // 0 is invalid |
49 int32 id = 1; // 0 is invalid |
50 |
50 |
51 for (LDObject* obj : g_LDObjects) |
51 for (LDObject* obj : g_LDObjects) |
52 if (obj->id() >= id) |
52 if (obj->getID() >= id) |
53 id = obj->id() + 1; |
53 id = obj->getID() + 1; |
54 |
54 |
55 setID (id); |
55 setID (id); |
56 g_LDObjects << this; |
56 g_LDObjects << this; |
57 } |
57 } |
58 |
58 |
102 } |
102 } |
103 |
103 |
104 // ============================================================================= |
104 // ============================================================================= |
105 // ----------------------------------------------------------------------------- |
105 // ----------------------------------------------------------------------------- |
106 str LDSubfile::raw() |
106 str LDSubfile::raw() |
107 { str val = fmt ("1 %1 %2 ", color(), position()); |
107 { str val = fmt ("1 %1 %2 ", getColor(), position()); |
108 val += transform().stringRep(); |
108 val += getTransform().stringRep(); |
109 val += ' '; |
109 val += ' '; |
110 val += fileInfo()->name(); |
110 val += getFileInfo()->getName(); |
111 return val; |
111 return val; |
112 } |
112 } |
113 |
113 |
114 // ============================================================================= |
114 // ============================================================================= |
115 // ----------------------------------------------------------------------------- |
115 // ----------------------------------------------------------------------------- |
116 str LDLine::raw() |
116 str LDLine::raw() |
117 { str val = fmt ("2 %1", color()); |
117 { str val = fmt ("2 %1", getColor()); |
118 |
118 |
119 for (int i = 0; i < 2; ++i) |
119 for (int i = 0; i < 2; ++i) |
120 val += fmt (" %1", getVertex (i)); |
120 val += fmt (" %1", getVertex (i)); |
121 |
121 |
122 return val; |
122 return val; |
123 } |
123 } |
124 |
124 |
125 // ============================================================================= |
125 // ============================================================================= |
126 // ----------------------------------------------------------------------------- |
126 // ----------------------------------------------------------------------------- |
127 str LDTriangle::raw() |
127 str LDTriangle::raw() |
128 { str val = fmt ("3 %1", color()); |
128 { str val = fmt ("3 %1", getColor()); |
129 |
129 |
130 for (int i = 0; i < 3; ++i) |
130 for (int i = 0; i < 3; ++i) |
131 val += fmt (" %1", getVertex (i)); |
131 val += fmt (" %1", getVertex (i)); |
132 |
132 |
133 return val; |
133 return val; |
134 } |
134 } |
135 |
135 |
136 // ============================================================================= |
136 // ============================================================================= |
137 // ----------------------------------------------------------------------------- |
137 // ----------------------------------------------------------------------------- |
138 str LDQuad::raw() |
138 str LDQuad::raw() |
139 { str val = fmt ("4 %1", color()); |
139 { str val = fmt ("4 %1", getColor()); |
140 |
140 |
141 for (int i = 0; i < 4; ++i) |
141 for (int i = 0; i < 4; ++i) |
142 val += fmt (" %1", getVertex (i)); |
142 val += fmt (" %1", getVertex (i)); |
143 |
143 |
144 return val; |
144 return val; |
145 } |
145 } |
146 |
146 |
147 // ============================================================================= |
147 // ============================================================================= |
148 // ----------------------------------------------------------------------------- |
148 // ----------------------------------------------------------------------------- |
149 str LDCndLine::raw() |
149 str LDCndLine::raw() |
150 { str val = fmt ("5 %1", color()); |
150 { str val = fmt ("5 %1", getColor()); |
151 |
151 |
152 // Add the coordinates |
152 // Add the coordinates |
153 for (int i = 0; i < 4; ++i) |
153 for (int i = 0; i < 4; ++i) |
154 val += fmt (" %1", getVertex (i)); |
154 val += fmt (" %1", getVertex (i)); |
155 |
155 |
163 } |
163 } |
164 |
164 |
165 // ============================================================================= |
165 // ============================================================================= |
166 // ----------------------------------------------------------------------------- |
166 // ----------------------------------------------------------------------------- |
167 str LDVertex::raw() |
167 str LDVertex::raw() |
168 { return fmt ("0 !LDFORGE VERTEX %1 %2", color(), pos); |
168 { return fmt ("0 !LDFORGE VERTEX %1 %2", getColor(), pos); |
169 } |
169 } |
170 |
170 |
171 // ============================================================================= |
171 // ============================================================================= |
172 // ----------------------------------------------------------------------------- |
172 // ----------------------------------------------------------------------------- |
173 str LDEmpty::raw() |
173 str LDEmpty::raw() |
204 // 1---2 1 1---2 |
204 // 1---2 1 1---2 |
205 LDTriangle* tri1 = new LDTriangle (getVertex (0), getVertex (1), getVertex (3)); |
205 LDTriangle* tri1 = new LDTriangle (getVertex (0), getVertex (1), getVertex (3)); |
206 LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3)); |
206 LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3)); |
207 |
207 |
208 // The triangles also inherit the quad's color |
208 // The triangles also inherit the quad's color |
209 tri1->setColor (color()); |
209 tri1->setColor (getColor()); |
210 tri2->setColor (color()); |
210 tri2->setColor (getColor()); |
211 |
211 |
212 QList<LDTriangle*> triangles; |
212 QList<LDTriangle*> triangles; |
213 triangles << tri1; |
213 triangles << tri1; |
214 triangles << tri2; |
214 triangles << tri2; |
215 return triangles; |
215 return triangles; |
220 void LDObject::replace (LDObject* other) |
220 void LDObject::replace (LDObject* other) |
221 { long idx = getIndex(); |
221 { long idx = getIndex(); |
222 assert (idx != -1); |
222 assert (idx != -1); |
223 |
223 |
224 // Replace the instance of the old object with the new object |
224 // Replace the instance of the old object with the new object |
225 file()->setObject (idx, other); |
225 getFile()->setObject (idx, other); |
226 |
226 |
227 // Remove the old object |
227 // Remove the old object |
228 delete this; |
228 delete this; |
229 } |
229 } |
230 |
230 |
231 // ============================================================================= |
231 // ============================================================================= |
232 // ----------------------------------------------------------------------------- |
232 // ----------------------------------------------------------------------------- |
233 void LDObject::swap (LDObject* other) |
233 void LDObject::swap (LDObject* other) |
234 { int i = 0; |
234 { int i = 0; |
235 |
235 |
236 for (LDObject* obj : file()->objects()) |
236 for (LDObject* obj : getFile()->getObjects()) |
237 { if (obj == this) |
237 { if (obj == this) |
238 file()->setObject (i, other); |
238 getFile()->setObject (i, other); |
239 elif (obj == other) |
239 elif (obj == other) |
240 file()->setObject (i, this); |
240 getFile()->setObject (i, this); |
241 |
241 |
242 ++i; |
242 ++i; |
243 } |
243 } |
244 |
244 |
245 file()->addToHistory (new SwapHistory (id(), other->id())); |
245 getFile()->addToHistory (new SwapHistory (getID(), other->getID())); |
246 } |
246 } |
247 |
247 |
248 // ============================================================================= |
248 // ============================================================================= |
249 // ----------------------------------------------------------------------------- |
249 // ----------------------------------------------------------------------------- |
250 LDLine::LDLine (vertex v1, vertex v2) |
250 LDLine::LDLine (vertex v1, vertex v2) |
263 |
263 |
264 // ============================================================================= |
264 // ============================================================================= |
265 // ----------------------------------------------------------------------------- |
265 // ----------------------------------------------------------------------------- |
266 LDObject::~LDObject() |
266 LDObject::~LDObject() |
267 { // If this object was selected, unselect it now |
267 { // If this object was selected, unselect it now |
268 if (selected()) |
268 if (isSelected()) |
269 unselect(); |
269 unselect(); |
270 |
270 |
271 // If this object was associated to a file, remove it off it now |
271 // If this object was associated to a file, remove it off it now |
272 if (file()) |
272 if (getFile()) |
273 file()->forgetObject (this); |
273 getFile()->forgetObject (this); |
274 |
274 |
275 // Delete the GL lists |
275 // Delete the GL lists |
276 GL::deleteLists (this); |
276 GL::deleteLists (this); |
277 |
277 |
278 // Remove this object from the list of LDObjects |
278 // Remove this object from the list of LDObjects |
296 |
296 |
297 break; |
297 break; |
298 |
298 |
299 case LDObject::Subfile: |
299 case LDObject::Subfile: |
300 { LDSubfile* ref = static_cast<LDSubfile*> (obj); |
300 { LDSubfile* ref = static_cast<LDSubfile*> (obj); |
301 matrix newMatrix = transform * ref->transform(); |
301 matrix newMatrix = transform * ref->getTransform(); |
302 vertex newpos = ref->position(); |
302 vertex newpos = ref->position(); |
303 |
303 |
304 newpos.transform (transform, pos); |
304 newpos.transform (transform, pos); |
305 ref->setPosition (newpos); |
305 ref->setPosition (newpos); |
306 ref->setTransform (newMatrix); |
306 ref->setTransform (newMatrix); |
309 |
309 |
310 default: |
310 default: |
311 break; |
311 break; |
312 } |
312 } |
313 |
313 |
314 if (obj->color() == maincolor) |
314 if (obj->getColor() == maincolor) |
315 obj->setColor (parentcolor); |
315 obj->setColor (parentcolor); |
316 } |
316 } |
317 |
317 |
318 // ============================================================================= |
318 // ============================================================================= |
319 // ----------------------------------------------------------------------------- |
319 // ----------------------------------------------------------------------------- |
320 QList<LDObject*> LDSubfile::inlineContents (InlineFlags flags) |
320 QList<LDObject*> LDSubfile::inlineContents (InlineFlags flags) |
321 { QList<LDObject*> objs = fileInfo()->inlineContents (flags); |
321 { QList<LDObject*> objs = getFileInfo()->inlineContents (flags); |
322 |
322 |
323 // Transform the objects |
323 // Transform the objects |
324 for (LDObject * obj : objs) |
324 for (LDObject * obj : objs) |
325 { // Set the parent now so we know what inlined this. |
325 { // Set the parent now so we know what inlined this. |
326 obj->setParent (this); |
326 obj->setParent (this); |
327 transformObject (obj, transform(), position(), color()); |
327 transformObject (obj, getTransform(), position(), getColor()); |
328 } |
328 } |
329 |
329 |
330 return objs; |
330 return objs; |
331 } |
331 } |
332 |
332 |
333 // ============================================================================= |
333 // ============================================================================= |
334 // ----------------------------------------------------------------------------- |
334 // ----------------------------------------------------------------------------- |
335 long LDObject::getIndex() const |
335 long LDObject::getIndex() const |
336 { |
336 { |
337 #ifndef RELEASE |
337 #ifndef RELEASE |
338 assert (file() != null); |
338 assert (getFile() != null); |
339 #endif |
339 #endif |
340 |
340 |
341 for (int i = 0; i < file()->getObjectCount(); ++i) |
341 for (int i = 0; i < getFile()->getObjectCount(); ++i) |
342 if (file()->getObject (i) == this) |
342 if (getFile()->getObject (i) == this) |
343 return i; |
343 return i; |
344 |
344 |
345 return -1; |
345 return -1; |
346 } |
346 } |
347 |
347 |
354 // If we move down, we need to iterate the array in reverse order. |
354 // If we move down, we need to iterate the array in reverse order. |
355 const long start = up ? 0 : (objs.size() - 1); |
355 const long start = up ? 0 : (objs.size() - 1); |
356 const long end = up ? objs.size() : -1; |
356 const long end = up ? objs.size() : -1; |
357 const long incr = up ? 1 : -1; |
357 const long incr = up ? 1 : -1; |
358 QList<LDObject*> objsToCompile; |
358 QList<LDObject*> objsToCompile; |
359 LDFile* file = objs[0]->file(); |
359 LDFile* file = objs[0]->getFile(); |
360 |
360 |
361 for (long i = start; i != end; i += incr) |
361 for (long i = start; i != end; i += incr) |
362 { LDObject* obj = objs[i]; |
362 { LDObject* obj = objs[i]; |
363 |
363 |
364 const long idx = obj->getIndex(), |
364 const long idx = obj->getIndex(), |
365 target = idx + (up ? -1 : 1); |
365 target = idx + (up ? -1 : 1); |
366 |
366 |
367 if ( (up && idx == 0) || (!up && idx == (long) (file->objects().size() - 1))) |
367 if ( (up && idx == 0) || (!up && idx == (long) (file->getObjects().size() - 1))) |
368 { // One of the objects hit the extrema. If this happens, this should be the first |
368 { // One of the objects hit the extrema. If this happens, this should be the first |
369 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
369 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
370 // abort the entire operation. |
370 // abort the entire operation. |
371 assert (i == start); |
371 assert (i == start); |
372 return; |
372 return; |
433 } |
433 } |
434 |
434 |
435 // ============================================================================= |
435 // ============================================================================= |
436 // ----------------------------------------------------------------------------- |
436 // ----------------------------------------------------------------------------- |
437 LDObject* LDObject::topLevelParent() |
437 LDObject* LDObject::topLevelParent() |
438 { if (!parent()) |
438 { if (!getParent()) |
439 return this; |
439 return this; |
440 |
440 |
441 LDObject* it = this; |
441 LDObject* it = this; |
442 |
442 |
443 while (it->parent()) |
443 while (it->getParent()) |
444 it = it->parent(); |
444 it = it->getParent(); |
445 |
445 |
446 return it; |
446 return it; |
447 } |
447 } |
448 |
448 |
449 // ============================================================================= |
449 // ============================================================================= |
450 // ----------------------------------------------------------------------------- |
450 // ----------------------------------------------------------------------------- |
451 LDObject* LDObject::next() const |
451 LDObject* LDObject::next() const |
452 { long idx = getIndex(); |
452 { long idx = getIndex(); |
453 assert (idx != -1); |
453 assert (idx != -1); |
454 |
454 |
455 if (idx == (long) file()->getObjectCount() - 1) |
455 if (idx == (long) getFile()->getObjectCount() - 1) |
456 return null; |
456 return null; |
457 |
457 |
458 return file()->getObject (idx + 1); |
458 return getFile()->getObject (idx + 1); |
459 } |
459 } |
460 |
460 |
461 // ============================================================================= |
461 // ============================================================================= |
462 // ----------------------------------------------------------------------------- |
462 // ----------------------------------------------------------------------------- |
463 LDObject* LDObject::prev() const |
463 LDObject* LDObject::prev() const |
595 if (idx > 0) |
595 if (idx > 0) |
596 { LDBFC* bfc = dynamic_cast<LDBFC*> (prev()); |
596 { LDBFC* bfc = dynamic_cast<LDBFC*> (prev()); |
597 |
597 |
598 if (bfc && bfc->type == LDBFC::InvertNext) |
598 if (bfc && bfc->type == LDBFC::InvertNext) |
599 { // This is prefixed with an invertnext, thus remove it. |
599 { // This is prefixed with an invertnext, thus remove it. |
600 file()->forgetObject (bfc); |
600 getFile()->forgetObject (bfc); |
601 delete bfc; |
601 delete bfc; |
602 return; |
602 return; |
603 } |
603 } |
604 } |
604 } |
605 |
605 |
606 // Not inverted, thus prefix it with a new invertnext. |
606 // Not inverted, thus prefix it with a new invertnext. |
607 LDBFC* bfc = new LDBFC (LDBFC::InvertNext); |
607 LDBFC* bfc = new LDBFC (LDBFC::InvertNext); |
608 file()->insertObj (idx, bfc); |
608 getFile()->insertObj (idx, bfc); |
609 } |
609 } |
610 |
610 |
611 // ============================================================================= |
611 // ============================================================================= |
612 // ----------------------------------------------------------------------------- |
612 // ----------------------------------------------------------------------------- |
613 static void invertLine (LDObject* line) |
613 static void invertLine (LDObject* line) |
634 { LDLine* repl = new LDLine; |
634 { LDLine* repl = new LDLine; |
635 |
635 |
636 for (int i = 0; i < repl->vertices(); ++i) |
636 for (int i = 0; i < repl->vertices(); ++i) |
637 repl->setVertex (i, getVertex (i)); |
637 repl->setVertex (i, getVertex (i)); |
638 |
638 |
639 repl->setColor (color()); |
639 repl->setColor (getColor()); |
640 |
640 |
641 replace (repl); |
641 replace (repl); |
642 return repl; |
642 return repl; |
643 } |
643 } |
644 |
644 |
645 // ============================================================================= |
645 // ============================================================================= |
646 // ----------------------------------------------------------------------------- |
646 // ----------------------------------------------------------------------------- |
647 LDObject* LDObject::fromID (int id) |
647 LDObject* LDObject::fromID (int id) |
648 { for (LDObject * obj : g_LDObjects) |
648 { for (LDObject * obj : g_LDObjects) |
649 if (obj->id() == id) |
649 if (obj->getID() == id) |
650 return obj; |
650 return obj; |
651 |
651 |
652 return null; |
652 return null; |
653 } |
653 } |
654 |
654 |
655 // ============================================================================= |
655 // ============================================================================= |
656 // ----------------------------------------------------------------------------- |
656 // ----------------------------------------------------------------------------- |
657 str LDOverlay::raw() |
657 str LDOverlay::raw() |
658 { return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", |
658 { return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", |
659 filename(), camera(), x(), y(), width(), height()); |
659 getFileName(), getCamera(), getX(), getY(), getWidth(), getHeight()); |
660 } |
660 } |
661 |
661 |
662 void LDOverlay::move (vertex vect) |
662 void LDOverlay::move (vertex vect) |
663 { Q_UNUSED (vect) |
663 { Q_UNUSED (vect) |
664 } |
664 } |
667 |
667 |
668 // ============================================================================= |
668 // ============================================================================= |
669 // Hook the set accessors of certain properties to this changeProperty function. |
669 // Hook the set accessors of certain properties to this changeProperty function. |
670 // It takes care of history management so we can capture low-level changes, this |
670 // It takes care of history management so we can capture low-level changes, this |
671 // makes history stuff work out of the box. |
671 // makes history stuff work out of the box. |
|
672 // |
|
673 // TODO: use new PROPERTY-callbacks |
672 // ----------------------------------------------------------------------------- |
674 // ----------------------------------------------------------------------------- |
673 template<class T> static void changeProperty (LDObject* obj, T* ptr, const T& val) |
675 template<class T> static void changeProperty (LDObject* obj, T* ptr, const T& val) |
674 { long idx; |
676 { long idx; |
675 |
677 |
676 if (*ptr == val) |
678 if (*ptr == val) |
677 return; |
679 return; |
678 |
680 |
679 if (obj->file() && (idx = obj->getIndex()) != -1) |
681 if (obj->getFile() && (idx = obj->getIndex()) != -1) |
680 { str before = obj->raw(); |
682 { str before = obj->raw(); |
681 *ptr = val; |
683 *ptr = val; |
682 str after = obj->raw(); |
684 str after = obj->raw(); |
683 |
685 |
684 obj->file()->addToHistory (new EditHistory (idx, before, after)); |
686 obj->getFile()->addToHistory (new EditHistory (idx, before, after)); |
685 } |
687 } |
686 else |
688 else |
687 *ptr = val; |
689 *ptr = val; |
688 } |
690 } |
689 |
691 |
690 // ============================================================================= |
692 // ============================================================================= |
691 // ----------------------------------------------------------------------------- |
693 // ----------------------------------------------------------------------------- |
692 READ_ACCESSOR (int, LDObject::color) |
694 const int& LDObject::getColor() const |
693 { return m_color; |
695 { return m_Color; |
694 } |
696 } |
695 |
697 |
696 SET_ACCESSOR (int, LDObject::setColor) |
698 void LDObject::setColor (int val) |
697 { changeProperty (this, &m_color, val); |
699 { changeProperty (this, &m_Color, val); |
698 } |
700 } |
699 |
701 |
700 // ============================================================================= |
702 // ============================================================================= |
701 // ----------------------------------------------------------------------------- |
703 // ----------------------------------------------------------------------------- |
702 const vertex& LDObject::getVertex (int i) const |
704 const vertex& LDObject::getVertex (int i) const |
708 } |
710 } |
709 |
711 |
710 // ============================================================================= |
712 // ============================================================================= |
711 // ----------------------------------------------------------------------------- |
713 // ----------------------------------------------------------------------------- |
712 void LDMatrixObject::setPosition (const vertex& a) |
714 void LDMatrixObject::setPosition (const vertex& a) |
713 { changeProperty (linkPointer(), &m_position, LDSharedVertex::getSharedVertex (a)); |
715 { changeProperty (getLinkPointer(), &m_position, LDSharedVertex::getSharedVertex (a)); |
714 } |
716 } |
715 |
717 |
716 // ============================================================================= |
718 // ============================================================================= |
717 // ----------------------------------------------------------------------------- |
719 // ----------------------------------------------------------------------------- |
718 READ_ACCESSOR (matrix, LDMatrixObject::transform) |
720 void LDMatrixObject::setTransform (const matrix& val) |
719 { return m_transform; |
721 { changeProperty (getLinkPointer(), &m_Transform, val); |
720 } |
|
721 |
|
722 SET_ACCESSOR (matrix, LDMatrixObject::setTransform) |
|
723 { changeProperty (linkPointer(), &m_transform, val); |
|
724 } |
722 } |
725 |
723 |
726 // ============================================================================= |
724 // ============================================================================= |
727 // ----------------------------------------------------------------------------- |
725 // ----------------------------------------------------------------------------- |
728 static QMap<vertex, LDSharedVertex*> g_sharedVerts; |
726 static QMap<vertex, LDSharedVertex*> g_sharedVerts; |
757 } |
755 } |
758 |
756 |
759 // ============================================================================= |
757 // ============================================================================= |
760 // ----------------------------------------------------------------------------- |
758 // ----------------------------------------------------------------------------- |
761 void LDObject::select() |
759 void LDObject::select() |
762 { if (!file()) |
760 { if (!getFile()) |
763 { log ("Warning: Object #%1 cannot be selected as it is not assigned a file!\n", id()); |
761 { log ("Warning: Object #%1 cannot be selected as it is not assigned a file!\n", getID()); |
764 return; |
762 return; |
765 } |
763 } |
766 |
764 |
767 file()->addToSelection (this); |
765 getFile()->addToSelection (this); |
768 } |
766 } |
769 |
767 |
770 void LDObject::unselect() |
768 void LDObject::unselect() |
771 { if (!file()) |
769 { if (!getFile()) |
772 { log ("Warning: Object #%1 cannot be unselected as it is not assigned a file!\n", id()); |
770 { log ("Warning: Object #%1 cannot be unselected as it is not assigned a file!\n", getID()); |
773 return; |
771 return; |
774 } |
772 } |
775 |
773 |
776 file()->removeFromSelection (this); |
774 getFile()->removeFromSelection (this); |
777 } |
775 } |