29 |
29 |
30 // ============================================================================= |
30 // ============================================================================= |
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
32 // ============================================================================= |
32 // ============================================================================= |
33 // LDObject constructors |
33 // LDObject constructors |
34 LDObject::LDObject () { |
34 LDObject::LDObject() |
|
35 { |
35 qObjListEntry = null; |
36 qObjListEntry = null; |
36 setParent (null); |
37 setParent( null ); |
37 m_hidden = false; |
38 m_hidden = false; |
38 m_selected = false; |
39 m_selected = false; |
39 m_glinit = false; |
40 m_glinit = false; |
40 |
41 |
41 // Determine ID |
42 // Determine ID |
42 int id = 1; // 0 is invalid |
43 int id = 1; // 0 is invalid |
43 for( LDObject* obj : g_LDObjects ) |
44 |
|
45 for( LDObject * obj : g_LDObjects ) |
44 if( obj->id() >= id ) |
46 if( obj->id() >= id ) |
45 id = obj->id() + 1; |
47 id = obj->id() + 1; |
46 |
48 |
47 setID( id ); |
49 setID( id ); |
48 |
50 |
49 g_LDObjects << this; |
51 g_LDObjects << this; |
50 } |
52 } |
51 |
53 |
52 LDGibberish::LDGibberish () {} |
54 LDGibberish::LDGibberish() {} |
53 LDGibberish::LDGibberish (str contents, str reason) : contents (contents), reason (reason) {} |
55 LDGibberish::LDGibberish( str contents, str reason ) : contents( contents ), reason( reason ) {} |
54 |
56 |
55 // ============================================================================= |
57 // ============================================================================= |
56 str LDComment::raw () { |
58 str LDComment::raw() |
57 return fmt ("0 %1", text); |
59 { |
58 } |
60 return fmt( "0 %1", text ); |
59 |
61 } |
60 str LDSubfile::raw () { |
62 |
61 str val = fmt ("1 %1 %2 ", color (), position ()); |
63 str LDSubfile::raw() |
62 val += transform ().stringRep (); |
64 { |
|
65 str val = fmt( "1 %1 %2 ", color(), position() ); |
|
66 val += transform().stringRep(); |
63 val += ' '; |
67 val += ' '; |
64 val += fileInfo ()->name (); |
68 val += fileInfo()->name(); |
65 return val; |
69 return val; |
66 } |
70 } |
67 |
71 |
68 str LDLine::raw () { |
72 str LDLine::raw() |
69 str val = fmt ("2 %1", color ()); |
73 { |
70 |
74 str val = fmt( "2 %1", color() ); |
71 for (ushort i = 0; i < 2; ++i) |
75 |
72 val += fmt (" %1", getVertex (i)); |
76 for( ushort i = 0; i < 2; ++i ) |
|
77 val += fmt( " %1", getVertex( i ) ); |
73 |
78 |
74 return val; |
79 return val; |
75 } |
80 } |
76 |
81 |
77 str LDTriangle::raw () { |
82 str LDTriangle::raw() |
78 str val = fmt ("3 %1", color ()); |
83 { |
79 |
84 str val = fmt( "3 %1", color() ); |
80 for (ushort i = 0; i < 3; ++i) |
85 |
81 val += fmt (" %1", getVertex (i)); |
86 for( ushort i = 0; i < 3; ++i ) |
|
87 val += fmt( " %1", getVertex( i ) ); |
82 |
88 |
83 return val; |
89 return val; |
84 } |
90 } |
85 |
91 |
86 str LDQuad::raw () { |
92 str LDQuad::raw() |
87 str val = fmt ("4 %1", color ()); |
93 { |
88 |
94 str val = fmt( "4 %1", color() ); |
89 for (ushort i = 0; i < 4; ++i) |
95 |
90 val += fmt (" %1", getVertex (i)); |
96 for( ushort i = 0; i < 4; ++i ) |
|
97 val += fmt( " %1", getVertex( i ) ); |
91 |
98 |
92 return val; |
99 return val; |
93 } |
100 } |
94 |
101 |
95 str LDCondLine::raw () { |
102 str LDCondLine::raw() |
96 str val = fmt ("5 %1", color ()); |
103 { |
|
104 str val = fmt( "5 %1", color() ); |
97 |
105 |
98 // Add the coordinates |
106 // Add the coordinates |
99 for (ushort i = 0; i < 4; ++i) |
107 for( ushort i = 0; i < 4; ++i ) |
100 val += fmt (" %1", getVertex (i)); |
108 val += fmt( " %1", getVertex( i ) ); |
101 |
109 |
102 return val; |
110 return val; |
103 } |
111 } |
104 |
112 |
105 str LDGibberish::raw () { |
113 str LDGibberish::raw() |
|
114 { |
106 return contents; |
115 return contents; |
107 } |
116 } |
108 |
117 |
109 str LDVertex::raw () { |
118 str LDVertex::raw() |
110 return fmt ("0 !LDFORGE VERTEX %1 %2", color (), pos); |
119 { |
111 } |
120 return fmt( "0 !LDFORGE VERTEX %1 %2", color(), pos ); |
112 |
121 } |
113 str LDEmpty::raw () { |
122 |
114 return str (); |
123 str LDEmpty::raw() |
115 } |
124 { |
116 |
125 return ""; |
117 // ============================================================================= |
126 } |
118 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
127 |
119 // ============================================================================= |
128 // ============================================================================= |
120 const char* LDBFC::statements[] = { |
129 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
130 // ============================================================================= |
|
131 const char* LDBFC::statements[] = |
|
132 { |
121 "CERTIFY CCW", |
133 "CERTIFY CCW", |
122 "CCW", |
134 "CCW", |
123 "CERTIFY CW", |
135 "CERTIFY CW", |
124 "CW", |
136 "CW", |
125 "NOCERTIFY", |
137 "NOCERTIFY", |
126 "INVERTNEXT", |
138 "INVERTNEXT", |
127 }; |
139 }; |
128 |
140 |
129 str LDBFC::raw () { |
141 str LDBFC::raw() |
130 return fmt ("0 BFC %1", LDBFC::statements[type]); |
142 { |
131 } |
143 return fmt( "0 BFC %1", LDBFC::statements[type] ); |
132 |
144 } |
133 // ============================================================================= |
145 |
134 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
146 // ============================================================================= |
135 // ============================================================================= |
147 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
136 vector<LDTriangle*> LDQuad::splitToTriangles () { |
148 // ============================================================================= |
|
149 vector<LDTriangle*> LDQuad::splitToTriangles() |
|
150 { |
137 // Create the two triangles based on this quadrilateral: |
151 // Create the two triangles based on this quadrilateral: |
138 // 0---3 0---3 3 |
152 // 0---3 0---3 3 |
139 // | | | / /| |
153 // | | | / /| |
140 // | | = | / / | |
154 // | | = | / / | |
141 // | | |/ / | |
155 // | | |/ / | |
142 // 1---2 1 1---2 |
156 // 1---2 1 1---2 |
143 LDTriangle* tri1 = new LDTriangle (getVertex (0), getVertex (1), getVertex (3)); |
157 LDTriangle* tri1 = new LDTriangle( getVertex( 0 ), getVertex( 1 ), getVertex( 3 ) ); |
144 LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3)); |
158 LDTriangle* tri2 = new LDTriangle( getVertex( 1 ), getVertex( 2 ), getVertex( 3 ) ); |
145 |
159 |
146 // The triangles also inherit the quad's color |
160 // The triangles also inherit the quad's color |
147 tri1->setColor (color ()); |
161 tri1->setColor( color() ); |
148 tri2->setColor (color ()); |
162 tri2->setColor( color() ); |
149 |
163 |
150 vector<LDTriangle*> triangles; |
164 vector<LDTriangle*> triangles; |
151 triangles << tri1; |
165 triangles << tri1; |
152 triangles << tri2; |
166 triangles << tri2; |
153 return triangles; |
167 return triangles; |
154 } |
168 } |
155 |
169 |
156 // ============================================================================= |
170 // ============================================================================= |
157 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
171 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
158 // ============================================================================= |
172 // ============================================================================= |
159 void LDObject::replace (LDObject* replacement) { |
173 void LDObject::replace( LDObject* replacement ) |
160 long idx = getIndex (g_curfile); |
174 { |
161 assert (idx != -1); |
175 long idx = getIndex( g_curfile ); |
|
176 assert( idx != -1 ); |
162 |
177 |
163 // Replace the instance of the old object with the new object |
178 // Replace the instance of the old object with the new object |
164 g_curfile->setObject (idx, replacement); |
179 g_curfile->setObject( idx, replacement ); |
165 |
180 |
166 // Remove the old object |
181 // Remove the old object |
167 delete this; |
182 delete this; |
168 } |
183 } |
169 |
184 |
170 // ============================================================================= |
185 // ============================================================================= |
171 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
186 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
172 // ============================================================================= |
187 // ============================================================================= |
173 void LDObject::swap (LDObject* other) { |
188 void LDObject::swap( LDObject* other ) |
174 for (LDObject*& obj : *g_curfile) { |
189 { |
175 if (obj == this) |
190 for( LDObject*& obj : *g_curfile ) |
|
191 { |
|
192 if( obj == this ) |
176 obj = other; |
193 obj = other; |
177 elif (obj == other) |
194 elif( obj == other ) |
178 obj = this; |
195 obj = this; |
179 } |
196 } |
180 } |
197 } |
181 |
198 |
182 LDLine::LDLine (vertex v1, vertex v2) { |
199 LDLine::LDLine( vertex v1, vertex v2 ) |
183 setVertex (0, v1); |
200 { |
184 setVertex (1, v2); |
201 setVertex( 0, v1 ); |
185 } |
202 setVertex( 1, v2 ); |
186 |
203 } |
187 LDObject::~LDObject () { |
204 |
|
205 LDObject::~LDObject() |
|
206 { |
188 // Remove this object from the selection array if it is there. |
207 // Remove this object from the selection array if it is there. |
189 for (ulong i = 0; i < g_win->sel().size(); ++i) |
208 for( ulong i = 0; i < g_win->sel().size(); ++i ) |
190 if (g_win->sel ()[i] == this) |
209 if( g_win->sel()[i] == this ) |
191 g_win->sel ().erase (i); |
210 g_win->sel().erase( i ); |
192 |
211 |
193 // Delete the GL lists |
212 // Delete the GL lists |
194 GL::deleteLists( this ); |
213 GL::deleteLists( this ); |
195 |
214 |
196 // Remove this object from the list of LDObjects |
215 // Remove this object from the list of LDObjects |
197 ulong pos = g_LDObjects.find( this ); |
216 ulong pos = g_LDObjects.find( this ); |
198 if( pos < g_LDObjects.size()) |
217 |
|
218 if( pos < g_LDObjects.size() ) |
199 g_LDObjects.erase( pos ); |
219 g_LDObjects.erase( pos ); |
200 } |
220 } |
201 |
221 |
202 // ============================================================================= |
222 // ============================================================================= |
203 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
223 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
204 // ============================================================================= |
224 // ============================================================================= |
205 static void transformObject (LDObject* obj, matrix transform, vertex pos, short parentcolor) { |
225 static void transformObject( LDObject* obj, matrix transform, vertex pos, short parentcolor ) |
206 switch (obj->getType()) { |
226 { |
|
227 switch( obj->getType() ) |
|
228 { |
207 case LDObject::Line: |
229 case LDObject::Line: |
208 case LDObject::CondLine: |
230 case LDObject::CondLine: |
209 case LDObject::Triangle: |
231 case LDObject::Triangle: |
210 case LDObject::Quad: |
232 case LDObject::Quad: |
211 for (short i = 0; i < obj->vertices (); ++i) { |
233 for( short i = 0; i < obj->vertices(); ++i ) |
212 vertex v = obj->getVertex (i); |
234 { |
213 v.transform (transform, pos); |
235 vertex v = obj->getVertex( i ); |
214 obj->setVertex (i, v); |
236 v.transform( transform, pos ); |
|
237 obj->setVertex( i, v ); |
215 } |
238 } |
216 break; |
239 break; |
217 |
240 |
218 case LDObject::Subfile: |
241 case LDObject::Subfile: |
219 { |
242 { |
220 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
243 LDSubfile* ref = static_cast<LDSubfile*>( obj ); |
221 matrix newMatrix = transform * ref->transform (); |
244 matrix newMatrix = transform * ref->transform(); |
222 vertex newpos = ref->position (); |
245 vertex newpos = ref->position(); |
223 |
246 |
224 newpos.transform (transform, pos); |
247 newpos.transform( transform, pos ); |
225 ref->setPosition (newpos); |
248 ref->setPosition( newpos ); |
226 ref->setTransform (newMatrix); |
249 ref->setTransform( newMatrix ); |
227 } |
250 } |
228 break; |
251 break; |
229 |
252 |
230 default: |
253 default: |
231 break; |
254 break; |
232 } |
255 } |
233 |
256 |
234 if (obj->color () == maincolor) |
257 if( obj->color() == maincolor ) |
235 obj->setColor (parentcolor); |
258 obj->setColor( parentcolor ); |
236 } |
259 } |
237 |
260 |
238 // ============================================================================= |
261 // ============================================================================= |
239 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
262 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
240 // ============================================================================= |
263 // ============================================================================= |
241 vector<LDObject*> LDSubfile::inlineContents (bool deep, bool cache) { |
264 vector<LDObject*> LDSubfile::inlineContents( bool deep, bool cache ) |
|
265 { |
242 vector<LDObject*> objs, objcache; |
266 vector<LDObject*> objs, objcache; |
243 |
267 |
244 // If we have this cached, just clone that |
268 // If we have this cached, just clone that |
245 if (deep && fileInfo ()->cache ().size ()) { |
269 if( deep && fileInfo()->cache().size() ) |
246 for (LDObject* obj : fileInfo ()->cache ()) |
270 { |
247 objs << obj->clone (); |
271 for( LDObject * obj : fileInfo()->cache() ) |
248 } else { |
272 objs << obj->clone(); |
249 if (!deep) |
273 } |
|
274 else |
|
275 { |
|
276 if( !deep ) |
250 cache = false; |
277 cache = false; |
251 |
278 |
252 for (LDObject* obj : *fileInfo ()) { |
279 for( LDObject * obj : *fileInfo() ) |
253 // Skip those without schemantic meaning |
280 { |
254 switch (obj->getType ()) { |
281 // Skip those without scemantic meaning |
255 case LDObject::Comment: |
282 if( !obj->isScemantic() ) |
256 case LDObject::Empty: |
|
257 case LDObject::Gibberish: |
|
258 case LDObject::Unidentified: |
|
259 case LDObject::Vertex: |
|
260 continue; |
283 continue; |
261 |
|
262 case LDObject::BFC: |
|
263 // Filter non-INVERTNEXT statements |
|
264 if (static_cast<LDBFC*> (obj)->type != LDBFC::InvertNext) |
|
265 continue; |
|
266 break; |
|
267 |
|
268 default: |
|
269 break; |
|
270 } |
|
271 |
284 |
272 // Got another sub-file reference, inline it if we're deep-inlining. If not, |
285 // Got another sub-file reference, inline it if we're deep-inlining. If not, |
273 // just add it into the objects normally. Also, we only cache immediate |
286 // just add it into the objects normally. Also, we only cache immediate |
274 // subfiles and this is not one. Yay, recursion! |
287 // subfiles and this is not one. Yay, recursion! |
275 if (deep && obj->getType() == LDObject::Subfile) { |
288 if( deep && obj->getType() == LDObject::Subfile ) |
276 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
289 { |
|
290 LDSubfile* ref = static_cast<LDSubfile*>( obj ); |
277 |
291 |
278 vector<LDObject*> otherobjs = ref->inlineContents (true, false); |
292 vector<LDObject*> otherobjs = ref->inlineContents( true, false ); |
279 |
293 |
280 for (LDObject* otherobj : otherobjs) { |
294 for( LDObject * otherobj : otherobjs ) |
|
295 { |
281 // Cache this object, if desired |
296 // Cache this object, if desired |
282 if (cache) |
297 if( cache ) |
283 objcache << otherobj->clone (); |
298 objcache << otherobj->clone(); |
284 |
299 |
285 objs << otherobj; |
300 objs << otherobj; |
286 } |
301 } |
287 } else { |
302 } |
288 if (cache) |
303 else |
289 objcache << obj->clone (); |
304 { |
|
305 if( cache ) |
|
306 objcache << obj->clone(); |
290 |
307 |
291 objs << obj->clone (); |
308 objs << obj->clone(); |
292 } |
309 } |
293 } |
310 } |
294 |
311 |
295 if (cache) |
312 if( cache ) |
296 fileInfo ()->setCache (objcache); |
313 fileInfo()->setCache( objcache ); |
297 } |
314 } |
298 |
315 |
299 // Transform the objects |
316 // Transform the objects |
300 for (LDObject* obj : objs) { |
317 for( LDObject * obj : objs ) |
|
318 { |
301 // Set the parent now so we know what inlined this. |
319 // Set the parent now so we know what inlined this. |
302 obj->setParent (this); |
320 obj->setParent( this ); |
303 |
321 |
304 transformObject (obj, transform (), position (), color ()); |
322 transformObject( obj, transform(), position(), color() ); |
305 } |
323 } |
306 |
324 |
307 return objs; |
325 return objs; |
308 } |
326 } |
309 |
327 |
310 // ============================================================================= |
328 // ============================================================================= |
311 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
329 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
312 // ============================================================================= |
330 // ============================================================================= |
313 long LDObject::getIndex (LDOpenFile* file) const { |
331 long LDObject::getIndex( LDOpenFile* file ) const |
314 for (ulong i = 0; i < file->numObjs (); ++i) |
332 { |
315 if (file->obj (i) == this) |
333 for( ulong i = 0; i < file->numObjs(); ++i ) |
|
334 if( file->obj( i ) == this ) |
316 return i; |
335 return i; |
317 |
336 |
318 return -1; |
337 return -1; |
319 } |
338 } |
320 |
339 |
321 // ============================================================================= |
340 // ============================================================================= |
322 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
341 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
323 // ============================================================================= |
342 // ============================================================================= |
324 void LDObject::moveObjects (vector<LDObject*> objs, const bool bUp) { |
343 void LDObject::moveObjects( vector<LDObject*> objs, const bool up ) |
|
344 { |
325 // If we move down, we need to iterate the array in reverse order. |
345 // If we move down, we need to iterate the array in reverse order. |
326 const long start = bUp ? 0 : (objs.size() - 1); |
346 const long start = up ? 0 : ( objs.size() - 1 ); |
327 const long end = bUp ? objs.size() : -1; |
347 const long end = up ? objs.size() : -1; |
328 const long incr = bUp ? 1 : -1; |
348 const long incr = up ? 1 : -1; |
329 |
|
330 vector<LDObject*> objsToCompile; |
349 vector<LDObject*> objsToCompile; |
331 |
350 |
332 for (long i = start; i != end; i += incr) { |
351 for( long i = start; i != end; i += incr ) |
|
352 { |
333 LDObject* obj = objs[i]; |
353 LDObject* obj = objs[i]; |
334 |
354 |
335 const long idx = obj->getIndex (g_curfile), |
355 const long idx = obj->getIndex( g_curfile ), |
336 target = idx + (bUp ? -1 : 1); |
356 target = idx + ( up ? -1 : 1 ); |
337 |
357 |
338 if ((bUp == true and idx == 0) or |
358 if(( up && idx == 0 ) || ( !up && idx == (long) ( g_curfile->objs().size() - 1 )) ) |
339 (bUp == false and idx == (long)(g_curfile->objs ().size() - 1))) |
|
340 { |
359 { |
341 // One of the objects hit the extrema. If this happens, this should be the first |
360 // One of the objects hit the extrema. If this happens, this should be the first |
342 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
361 // object to be iterated on. Thus, nothing has changed yet and it's safe to just |
343 // abort the entire operation. |
362 // abort the entire operation. |
344 assert (i == start); |
363 assert( i == start ); |
345 return; |
364 return; |
346 } |
365 } |
347 |
366 |
348 objsToCompile << obj; |
367 objsToCompile << obj; |
349 objsToCompile << g_curfile->obj (target); |
368 objsToCompile << g_curfile->obj( target ); |
350 |
369 |
351 obj->swap (g_curfile->obj (target)); |
370 obj->swap( g_curfile->obj( target ) ); |
352 } |
371 } |
|
372 |
|
373 objsToCompile.makeUnique(); |
353 |
374 |
354 // The objects need to be recompiled, otherwise their pick lists are left with |
375 // The objects need to be recompiled, otherwise their pick lists are left with |
355 // the wrong index colors which messes up selection. |
376 // the wrong index colors which messes up selection. |
356 for (LDObject* obj : objsToCompile) |
377 for( LDObject * obj : objsToCompile ) |
357 g_win->R ()->compileObject (obj); |
378 g_win->R()->compileObject( obj ); |
358 } |
379 } |
359 |
380 |
360 str LDObject::typeName( LDObject::Type type ) |
381 str LDObject::typeName( LDObject::Type type ) |
361 { |
382 { |
362 LDObject* obj = LDObject::getDefault( type ); |
383 LDObject* obj = LDObject::getDefault( type ); |
366 } |
387 } |
367 |
388 |
368 // ============================================================================= |
389 // ============================================================================= |
369 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
390 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
370 // ============================================================================= |
391 // ============================================================================= |
371 str LDObject::objectListContents (const vector<LDObject*>& objs) { |
392 str LDObject::objectListContents( const vector<LDObject*>& objs ) |
|
393 { |
372 bool firstDetails = true; |
394 bool firstDetails = true; |
373 str text = ""; |
395 str text = ""; |
374 |
396 |
375 if (objs.size() == 0) |
397 if( objs.size() == 0 ) |
376 return "nothing"; // :) |
398 return "nothing"; // :) |
377 |
399 |
378 for (long i = 0; i < LDObject::NumTypes; ++i) { |
400 for( long i = 0; i < LDObject::NumTypes; ++i ) |
379 LDObject::Type objType = (LDObject::Type) i; |
401 { |
|
402 LDObject::Type objType = ( LDObject::Type ) i; |
380 ulong objCount = 0; |
403 ulong objCount = 0; |
381 |
404 |
382 for (LDObject* obj : objs) |
405 for( LDObject * obj : objs ) |
383 if (obj->getType() == objType) |
406 if( obj->getType() == objType ) |
384 objCount++; |
407 objCount++; |
385 |
408 |
386 if (objCount == 0) |
409 if( objCount == 0 ) |
387 continue; |
410 continue; |
388 |
411 |
389 if (!firstDetails) |
412 if( !firstDetails ) |
390 text += ", "; |
413 text += ", "; |
391 |
414 |
392 str noun = fmt ("%1%2", typeName( objType ), plural( objCount )); |
415 str noun = fmt( "%1%2", typeName( objType ), plural( objCount ) ); |
393 |
416 |
394 // Plural of "vertex" is "vertices". Stupid English. |
417 // Plural of "vertex" is "vertices". Stupid English. |
395 if (objType == LDObject::Vertex && objCount != 1) |
418 if( objType == LDObject::Vertex && objCount != 1 ) |
396 noun = "vertices"; |
419 noun = "vertices"; |
397 |
420 |
398 text += fmt ("%1 %2", objCount, noun); |
421 text += fmt( "%1 %2", objCount, noun ); |
399 firstDetails = false; |
422 firstDetails = false; |
400 } |
423 } |
401 |
424 |
402 return text; |
425 return text; |
403 } |
426 } |
404 |
427 |
405 // ============================================================================= |
428 // ============================================================================= |
406 LDObject* LDObject::topLevelParent () { |
429 LDObject* LDObject::topLevelParent() |
407 if (!parent ()) |
430 { |
|
431 if( !parent() ) |
408 return this; |
432 return this; |
409 |
433 |
410 LDObject* it = this; |
434 LDObject* it = this; |
411 |
435 |
412 while (it->parent ()) |
436 while( it->parent() ) |
413 it = it->parent (); |
437 it = it->parent(); |
414 |
438 |
415 return it; |
439 return it; |
416 } |
440 } |
417 |
441 |
418 // ============================================================================= |
442 // ============================================================================= |
419 LDObject* LDObject::next () const { |
443 LDObject* LDObject::next() const |
420 long idx = getIndex (g_curfile); |
444 { |
421 assert (idx != -1); |
445 long idx = getIndex( g_curfile ); |
422 |
446 assert( idx != -1 ); |
423 if (idx == (long) g_curfile->numObjs () - 1) |
447 |
|
448 if( idx == ( long ) g_curfile->numObjs() - 1 ) |
424 return null; |
449 return null; |
425 |
450 |
426 return g_curfile->obj (idx + 1); |
451 return g_curfile->obj( idx + 1 ); |
427 } |
452 } |
428 |
453 |
429 // ============================================================================= |
454 // ============================================================================= |
430 LDObject* LDObject::prev () const { |
455 LDObject* LDObject::prev() const |
431 long idx = getIndex (g_curfile); |
456 { |
432 assert (idx != -1); |
457 long idx = getIndex( g_curfile ); |
433 |
458 assert( idx != -1 ); |
434 if (idx == 0) |
459 |
|
460 if( idx == 0 ) |
435 return null; |
461 return null; |
436 |
462 |
437 return g_curfile->obj (idx - 1); |
463 return g_curfile->obj( idx - 1 ); |
438 } |
464 } |
439 |
465 |
440 // ============================================================================= |
466 // ============================================================================= |
441 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
467 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
442 // ============================================================================= |
468 // ============================================================================= |
443 void LDObject::move (vertex vect) { (void) vect; } |
469 void LDObject::move( vertex vect ) { (void) vect; } |
444 void LDEmpty::move (vertex vect) { (void) vect; } |
470 void LDEmpty::move( vertex vect ) { (void) vect; } |
445 void LDBFC::move (vertex vect) { (void) vect; } |
471 void LDBFC::move( vertex vect ) { (void) vect; } |
446 void LDComment::move (vertex vect) { (void) vect; } |
472 void LDComment::move( vertex vect ) { (void) vect; } |
447 void LDGibberish::move (vertex vect) { (void) vect; } |
473 void LDGibberish::move( vertex vect ) { (void) vect; } |
448 |
474 |
449 void LDVertex::move (vertex vect) { |
475 void LDVertex::move( vertex vect ) |
|
476 { |
450 pos += vect; |
477 pos += vect; |
451 } |
478 } |
452 |
479 |
453 void LDSubfile::move (vertex vect) { |
480 void LDSubfile::move( vertex vect ) |
454 setPosition (position () + vect); |
481 { |
455 } |
482 setPosition( position() + vect ); |
456 |
483 } |
457 void LDLine::move (vertex vect) { |
484 |
458 for (short i = 0; i < 2; ++i) |
485 void LDLine::move( vertex vect ) |
459 setVertex (i, getVertex (i) + vect); |
486 { |
460 } |
487 for( short i = 0; i < 2; ++i ) |
461 |
488 setVertex( i, getVertex( i ) + vect ); |
462 void LDTriangle::move (vertex vect) { |
489 } |
463 for (short i = 0; i < 3; ++i) |
490 |
464 setVertex (i, getVertex (i) + vect); |
491 void LDTriangle::move( vertex vect ) |
465 } |
492 { |
466 |
493 for( short i = 0; i < 3; ++i ) |
467 void LDQuad::move (vertex vect) { |
494 setVertex( i, getVertex( i ) + vect ); |
468 for (short i = 0; i < 4; ++i) |
495 } |
469 setVertex (i, getVertex (i) + vect); |
496 |
470 } |
497 void LDQuad::move( vertex vect ) |
471 |
498 { |
472 void LDCondLine::move (vertex vect) { |
499 for( short i = 0; i < 4; ++i ) |
473 for (short i = 0; i < 4; ++i) |
500 setVertex( i, getVertex( i ) + vect ); |
474 setVertex (i, getVertex (i) + vect); |
501 } |
|
502 |
|
503 void LDCondLine::move( vertex vect ) |
|
504 { |
|
505 for( short i = 0; i < 4; ++i ) |
|
506 setVertex( i, getVertex( i ) + vect ); |
475 } |
507 } |
476 |
508 |
477 // ============================================================================= |
509 // ============================================================================= |
478 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
510 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
479 // ============================================================================= |
511 // ============================================================================= |
480 #define CHECK_FOR_OBJ(N) \ |
512 #define CHECK_FOR_OBJ(N) \ |
481 if (type == LDObject::N) \ |
513 if( type == LDObject::N ) \ |
482 return new LD##N; |
514 return new LD##N; |
483 LDObject* LDObject::getDefault (const LDObject::Type type) { |
515 |
484 CHECK_FOR_OBJ (Comment) |
516 LDObject* LDObject::getDefault( const LDObject::Type type ) |
485 CHECK_FOR_OBJ (BFC) |
517 { |
486 CHECK_FOR_OBJ (Line) |
518 CHECK_FOR_OBJ( Comment ) |
487 CHECK_FOR_OBJ (CondLine) |
519 CHECK_FOR_OBJ( BFC ) |
488 CHECK_FOR_OBJ (Subfile) |
520 CHECK_FOR_OBJ( Line ) |
489 CHECK_FOR_OBJ (Triangle) |
521 CHECK_FOR_OBJ( CondLine ) |
490 CHECK_FOR_OBJ (Quad) |
522 CHECK_FOR_OBJ( Subfile ) |
491 CHECK_FOR_OBJ (Empty) |
523 CHECK_FOR_OBJ( Triangle ) |
492 CHECK_FOR_OBJ (BFC) |
524 CHECK_FOR_OBJ( Quad ) |
493 CHECK_FOR_OBJ (Gibberish) |
525 CHECK_FOR_OBJ( Empty ) |
494 CHECK_FOR_OBJ (Vertex) |
526 CHECK_FOR_OBJ( BFC ) |
495 CHECK_FOR_OBJ (Overlay) |
527 CHECK_FOR_OBJ( Gibberish ) |
|
528 CHECK_FOR_OBJ( Vertex ) |
|
529 CHECK_FOR_OBJ( Overlay ) |
496 return null; |
530 return null; |
497 } |
531 } |
498 |
532 |
499 // ============================================================================= |
533 // ============================================================================= |
500 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
534 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
501 // ============================================================================= |
535 // ============================================================================= |
502 void LDObject::invert () { } |
536 void LDObject::invert() {} |
503 void LDBFC::invert () { } |
537 void LDBFC::invert() {} |
504 void LDEmpty::invert () { } |
538 void LDEmpty::invert() {} |
505 void LDComment::invert () { } |
539 void LDComment::invert() {} |
506 void LDGibberish::invert () { } |
540 void LDGibberish::invert() {} |
507 |
541 |
508 void LDTriangle::invert () { |
542 void LDTriangle::invert() |
|
543 { |
509 // Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1. |
544 // Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1. |
510 // Thus, we swap 1 and 2. |
545 // Thus, we swap 1 and 2. |
511 vertex tmp = getVertex (1); |
546 vertex tmp = getVertex( 1 ); |
512 setVertex (1, getVertex (2)); |
547 setVertex( 1, getVertex( 2 ) ); |
513 setVertex (2, tmp); |
548 setVertex( 2, tmp ); |
514 |
549 |
515 return; |
550 return; |
516 } |
551 } |
517 |
552 |
518 void LDQuad::invert () { |
553 void LDQuad::invert() |
|
554 { |
519 // Quad: 0 -> 1 -> 2 -> 3 |
555 // Quad: 0 -> 1 -> 2 -> 3 |
520 // rev: 0 -> 3 -> 2 -> 1 |
556 // rev: 0 -> 3 -> 2 -> 1 |
521 // Thus, we swap 1 and 3. |
557 // Thus, we swap 1 and 3. |
522 vertex tmp = getVertex (1); |
558 vertex tmp = getVertex( 1 ); |
523 setVertex (1, getVertex (3)); |
559 setVertex( 1, getVertex( 3 ) ); |
524 setVertex (3, tmp); |
560 setVertex( 3, tmp ); |
525 } |
561 } |
526 |
562 |
527 void LDSubfile::invert () { |
563 void LDSubfile::invert() |
|
564 { |
528 // Subfiles are inverted when they're prefixed with |
565 // Subfiles are inverted when they're prefixed with |
529 // a BFC INVERTNEXT statement. Thus we need to toggle this status. |
566 // a BFC INVERTNEXT statement. Thus we need to toggle this status. |
530 // For flat primitives it's sufficient that the determinant is |
567 // For flat primitives it's sufficient that the determinant is |
531 // flipped but I don't have a method for checking flatness yet. |
568 // flipped but I don't have a method for checking flatness yet. |
532 // Food for thought... |
569 // Food for thought... |
533 |
570 |
534 ulong idx = getIndex( g_curfile ); |
571 ulong idx = getIndex( g_curfile ); |
535 |
572 |
536 if (idx > 0) { |
573 if( idx > 0 ) |
|
574 { |
537 LDBFC* bfc = dynamic_cast<LDBFC*>( prev() ); |
575 LDBFC* bfc = dynamic_cast<LDBFC*>( prev() ); |
538 |
576 |
539 if( bfc && bfc->type == LDBFC::InvertNext ) |
577 if( bfc && bfc->type == LDBFC::InvertNext ) |
540 { |
578 { |
541 // This is prefixed with an invertnext, thus remove it. |
579 // This is prefixed with an invertnext, thus remove it. |