1 #include "LDModelParser.h"
2 #include "LDrawModelViewer.h"
3 #include "LDObiInfo.h"
4
5 #include <string.h>
6
7 #include <LDLoader/LDLMainModel.h>
8 #include <LDLoader/LDLShapeLine.h>
9 #include <LDLoader/LDLModelLine.h>
10 #include <LDLoader/LDLCommentLine.h>
11 #include <LDLoader/LDLConditionalLineLine.h>
12 #include <LDLoader/LDLPalette.h>
13 #include <TRE/TREMainModel.h>
14 #include <TRE/TRESubModel.h>
15 #include <TCFoundation/mystring.h>
16 #include <TCFoundation/TCMacros.h>
17 #include <TCFoundation/TCVector.h>
18 #include <TCFoundation/TCProgressAlert.h>
19 #include <TCFoundation/TCLocalStrings.h>
20 #include <ctype.h>
21
22 #ifdef WIN32
23 #if defined(_MSC_VER) && _MSC_VER >= 1400 && defined(_DEBUG)
24 #define new DEBUG_CLIENTBLOCK
25 #endif // _DEBUG
26 #endif // WIN32
27
28 static const int LO_NUM_SEGMENTS = 8;
29
30
LDModelParser(LDrawModelViewer * modelViewer)31 LDModelParser::LDModelParser(LDrawModelViewer *modelViewer)
32 :m_modelViewer(modelViewer),
33 m_topLDLModel(NULL),
34 m_mainTREModel(NULL),
35 m_seamWidth(0.0f),
36 m_obiInfo(NULL),
37 m_obiUniqueId(0),
38 m_abort(false)
39 {
40 TCByte defaultR, defaultG, defaultB;
41 bool defaultTrans;
42 int defaultColorNumber;
43
44 // Initialize all flags to false.
45 memset(&m_flags, 0, sizeof(m_flags));
46 m_flags.flattenParts = true; // Supporting false here could take a lot
47 // of work.
48 m_flags.seams = false;
49 m_flags.defaultColorSet = false;
50 m_flags.defaultColorNumberSet = false;
51 setCurveQuality(m_modelViewer->getCurveQuality());
52 setNoLightGeomFlag(m_modelViewer->getNoLightGeom());
53 setPrimitiveSubstitutionFlag(
54 m_modelViewer->getAllowPrimitiveSubstitution());
55 setSeamWidth(m_modelViewer->getSeamWidth());
56 m_modelViewer->getDefaultRGB(defaultR, defaultG, defaultB, defaultTrans);
57 setDefaultRGB(defaultR, defaultG, defaultB, defaultTrans);
58 defaultColorNumber = m_modelViewer->getDefaultColorNumber();
59 if (defaultColorNumber == -1)
60 {
61 TCByte r, g, b;
62 bool transparent;
63
64 modelViewer->getDefaultRGB(r, g, b, transparent);
65 LDLModel *mainModel = modelViewer->getMainModel();
66
67 if (mainModel)
68 {
69 LDLPalette *palette = mainModel->getMainModel()->getPalette();
70
71 setDefaultColorNumber(palette->getColorNumberForRGB(r, g, b,
72 transparent));
73 }
74 }
75 else
76 {
77 setDefaultColorNumber(defaultColorNumber);
78 }
79 m_flags.boundingBoxesOnly = m_modelViewer->getBoundingBoxesOnly();
80 m_flags.obi = m_modelViewer->getObi();
81 m_flags.newTexmap = false;
82 m_flags.texmapNext = false;
83 m_flags.texmapStarted = false;
84 }
85
~LDModelParser(void)86 LDModelParser::~LDModelParser(void)
87 {
88 }
89
dealloc(void)90 void LDModelParser::dealloc(void)
91 {
92 TCObject::release(m_topLDLModel);
93 TCObject::release(m_mainTREModel);
94 LDLPrimitiveCheck::dealloc();
95 }
96
shouldLoadConditionalLines(void)97 bool LDModelParser::shouldLoadConditionalLines(void)
98 {
99 return (getEdgeLinesFlag() && getConditionalLinesFlag()) ||
100 getSmoothCurvesFlag();
101 }
102
shouldLoadEdgeLines(void)103 bool LDModelParser::shouldLoadEdgeLines(void)
104 {
105 return getEdgeLinesFlag() || getSmoothCurvesFlag();
106 }
107
108
109 //void LDModelParser::finishPart(TREModel *treModel, TRESubModel *subModel)
110 //{
111 // if (getFlattenPartsFlag())
112 // {
113 // treModel->flatten();
114 // }
115 // if (getSmoothCurvesFlag())
116 // {
117 // treModel->smooth();
118 // }
119 // if (subModel)
120 // {
121 // if (getSeamsFlag() && !treModel->getNoShrinkFlag())
122 // {
123 // subModel->shrink(m_seamWidth);
124 // }
125 // }
126 //}
127
setDefaultRGB(TCByte r,TCByte g,TCByte b,bool transparent)128 void LDModelParser::setDefaultRGB(TCByte r, TCByte g, TCByte b,
129 bool transparent)
130 {
131 m_defaultR = r;
132 m_defaultG = g;
133 m_defaultB = b;
134 m_flags.defaultTrans = transparent;
135 setDefaultColorSetFlag(true);
136 }
137
setDefaultColorNumber(int colorNumber)138 void LDModelParser::setDefaultColorNumber(int colorNumber)
139 {
140 m_defaultColorNumber = colorNumber;
141 setDefaultColorNumberSetFlag(true);
142 }
143
getDefaultColorNumber(void)144 int LDModelParser::getDefaultColorNumber(void)
145 {
146 LDLPalette *palette = m_topLDLModel->getMainModel()->getPalette();
147 if (getDefaultColorNumberSetFlag())
148 {
149 return m_defaultColorNumber;
150 }
151 else if (getDefaultColorSetFlag())
152 {
153 return palette->getColorNumberForRGB(m_defaultR, m_defaultG,
154 m_defaultB, m_flags.defaultTrans);
155 }
156 return 7;
157 }
158
parseMainModel(LDLModel * mainLDLModel)159 bool LDModelParser::parseMainModel(LDLModel *mainLDLModel)
160 {
161 int colorNumber = 7;
162 int edgeColorNumber;
163
164 m_topLDLModel = (LDLModel *)mainLDLModel->retain();
165 m_mainTREModel = new TREMainModel;
166 if (m_alertSender != NULL)
167 {
168 m_mainTREModel->setAlertSender(m_alertSender);
169 }
170 else
171 {
172 m_mainTREModel->setSendProgressFlag(false);
173 }
174 m_mainTREModel->setMultiThreadedFlag(getMultiThreadedFlag());
175 m_mainTREModel->setUseStripsFlag(getUseStripsFlag());
176 m_mainTREModel->setPartFlag(mainLDLModel->isPart());
177 m_mainTREModel->setEdgeLinesFlag(getEdgeLinesFlag());
178 m_mainTREModel->setEdgesOnlyFlag(getEdgesOnlyFlag());
179 m_mainTREModel->setLightingFlag(getLightingFlag());
180 m_mainTREModel->setTwoSidedLightingFlag(getTwoSidedLightingFlag());
181 m_mainTREModel->setBFCFlag(getBFCFlag());
182 m_mainTREModel->setRedBackFacesFlag(getRedBackFacesFlag());
183 m_mainTREModel->setGreenFrontFacesFlag(getGreenFrontFacesFlag());
184 m_mainTREModel->setBlueNeutralFacesFlag(getBlueNeutralFacesFlag());
185 m_mainTREModel->setGl2psFlag(m_modelViewer->getGl2ps());
186 switch (m_modelViewer->getMemoryUsage())
187 {
188 case 0:
189 m_mainTREModel->setCompilePartsFlag(false);
190 m_mainTREModel->setCompileAllFlag(false);
191 m_mainTREModel->setFlattenConditionalsFlag(false);
192 break;
193 case 1:
194 m_mainTREModel->setCompilePartsFlag(true);
195 m_mainTREModel->setCompileAllFlag(false);
196 m_mainTREModel->setFlattenConditionalsFlag(false);
197 break;
198 case 2:
199 m_mainTREModel->setCompilePartsFlag(true);
200 m_mainTREModel->setCompileAllFlag(true);
201 m_mainTREModel->setFlattenConditionalsFlag(true);
202 break;
203 }
204 m_mainTREModel->setPolygonOffsetFlag(getPolygonOffsetFlag());
205 m_mainTREModel->setEdgeLineWidth(
206 m_modelViewer->getScaledHighlightLineWidth());
207 m_mainTREModel->setStudAnisoLevel(m_modelViewer->getAnisoLevel());
208 m_mainTREModel->setAALinesFlag(getAALinesFlag());
209 m_mainTREModel->setSortTransparentFlag(getSortTransparentFlag());
210 m_mainTREModel->setStippleFlag(getStippleFlag());
211 m_mainTREModel->setWireframeFlag(getWireframeFlag());
212 m_mainTREModel->setConditionalLinesFlag(getConditionalLinesFlag());
213 m_mainTREModel->setSmoothCurvesFlag(getSmoothCurvesFlag());
214 m_mainTREModel->setShowAllConditionalFlag(getShowAllConditionalFlag());
215 m_mainTREModel->setConditionalControlPointsFlag(
216 getConditionalControlPointsFlag());
217 m_mainTREModel->setStudLogoFlag(getStudLogoFlag());
218 m_mainTREModel->setStudTextureFilter(m_modelViewer->getTextureFilterType());
219 m_mainTREModel->setFlattenPartsFlag(getFlattenPartsFlag());
220 m_mainTREModel->setSeamWidth(getSeamWidth());
221 colorNumber = getDefaultColorNumber();
222 edgeColorNumber = mainLDLModel->getEdgeColorNumber(colorNumber);
223 m_mainTREModel->setColor(mainLDLModel->getPackedRGBA(colorNumber),
224 mainLDLModel->getPackedRGBA(edgeColorNumber));
225 m_obiTokens.clear();
226 if (parseModel(m_topLDLModel, m_mainTREModel, getBFCFlag(),
227 m_defaultColorNumber, false))
228 {
229 if (m_mainTREModel->isPart() || getFileIsPartFlag())
230 {
231 m_mainTREModel->setPartFlag(true);
232 //finishPart(m_mainTREModel);
233 }
234 m_mainTREModel->finish();
235 if (m_topLDLModel->getName())
236 {
237 m_mainTREModel->setName(m_topLDLModel->getName());
238 }
239 else
240 {
241 char *name = filenameFromPath(m_topLDLModel->getFilename());
242
243 m_mainTREModel->setName(name);
244 delete[] name;
245 }
246 if (m_alertSender != NULL)
247 {
248 TCProgressAlert::send("LDModelParser",
249 TCLocalStrings::get(_UC("ParsingStatus")), 1.0f, &m_abort,
250 this);
251 }
252 if (m_abort)
253 {
254 return false;
255 }
256 else
257 {
258 return m_mainTREModel->postProcess();
259 }
260 }
261 else
262 {
263 return false;
264 }
265 }
266
getFileIsPartFlag(void) const267 bool LDModelParser::getFileIsPartFlag(void) const
268 {
269 return m_modelViewer->getFileIsPart();
270 }
271
getEdgeLinesFlag(void) const272 bool LDModelParser::getEdgeLinesFlag(void) const
273 {
274 return m_modelViewer->getShowsHighlightLines();
275 }
276
getEdgesOnlyFlag(void) const277 bool LDModelParser::getEdgesOnlyFlag(void) const
278 {
279 return m_modelViewer->getEdgesOnly();
280 }
281
getLightingFlag(void) const282 bool LDModelParser::getLightingFlag(void) const
283 {
284 return m_modelViewer->getUseLighting();
285 }
286
getTwoSidedLightingFlag(void) const287 bool LDModelParser::getTwoSidedLightingFlag(void) const
288 {
289 return m_modelViewer->forceOneLight();
290 }
291
getBFCFlag(void) const292 bool LDModelParser::getBFCFlag(void) const
293 {
294 return m_modelViewer->getBfc();
295 }
296
getAALinesFlag(void) const297 bool LDModelParser::getAALinesFlag(void) const
298 {
299 return m_modelViewer->getLineSmoothing();
300 }
301
getSortTransparentFlag(void) const302 bool LDModelParser::getSortTransparentFlag(void) const
303 {
304 return m_modelViewer->getSortTransparent();
305 }
306
getStippleFlag(void) const307 bool LDModelParser::getStippleFlag(void) const
308 {
309 return m_modelViewer->getUseStipple();
310 }
311
getWireframeFlag(void) const312 bool LDModelParser::getWireframeFlag(void) const
313 {
314 return m_modelViewer->getDrawWireframe();
315 }
316
getConditionalLinesFlag(void) const317 bool LDModelParser::getConditionalLinesFlag(void) const
318 {
319 return m_modelViewer->getDrawConditionalHighlights();
320 }
321
getSmoothCurvesFlag(void) const322 bool LDModelParser::getSmoothCurvesFlag(void) const
323 {
324 return m_modelViewer->getPerformSmoothing();
325 }
326
getShowAllConditionalFlag(void) const327 bool LDModelParser::getShowAllConditionalFlag(void) const
328 {
329 return m_modelViewer->getShowAllConditionalLines();
330 }
331
getConditionalControlPointsFlag(void) const332 bool LDModelParser::getConditionalControlPointsFlag(void) const
333 {
334 return m_modelViewer->getShowConditionalControlPoints();
335 }
336
getPolygonOffsetFlag(void) const337 bool LDModelParser::getPolygonOffsetFlag(void) const
338 {
339 return m_modelViewer->getUsePolygonOffset();
340 }
341
getStudLogoFlag(void) const342 bool LDModelParser::getStudLogoFlag(void) const
343 {
344 return m_modelViewer->getTextureStuds();
345 }
346
getRedBackFacesFlag(void) const347 bool LDModelParser::getRedBackFacesFlag(void) const
348 {
349 return m_modelViewer->getRedBackFaces();
350 }
351
getGreenFrontFacesFlag(void) const352 bool LDModelParser::getGreenFrontFacesFlag(void) const
353 {
354 return m_modelViewer->getGreenFrontFaces();
355 }
356
getBlueNeutralFacesFlag(void) const357 bool LDModelParser::getBlueNeutralFacesFlag(void) const
358 {
359 return m_modelViewer->getBlueNeutralFaces();
360 }
361
getMultiThreadedFlag(void) const362 bool LDModelParser::getMultiThreadedFlag(void) const
363 {
364 return m_modelViewer->getMultiThreaded();
365 }
366
getUseStripsFlag(void) const367 bool LDModelParser::getUseStripsFlag(void) const
368 {
369 return m_modelViewer->getUseStrips();
370 }
371
addSubModel(LDLModelLine * modelLine,TREModel * treParentModel,TREModel * treModel,bool invert,int activeColorNumber)372 bool LDModelParser::addSubModel(
373 LDLModelLine *modelLine,
374 TREModel *treParentModel,
375 TREModel *treModel,
376 bool invert,
377 int activeColorNumber)
378 {
379 int colorNumber = actualColorNumber(modelLine, activeColorNumber);
380 TRESubModel *treSubModel = NULL;
381
382 if (colorNumber == 16 || colorNumber == 24)
383 {
384 treSubModel = treParentModel->addSubModel(modelLine->getMatrix(),
385 treModel, invert);
386 }
387 else
388 {
389 LDLModel *parentModel = modelLine->getParentModel();
390 TCULong edgeColorNumber = parentModel->getEdgeColorNumber(colorNumber);
391
392 treSubModel = treParentModel->addSubModel(
393 parentModel->getPackedRGBA(colorNumber),
394 parentModel->getPackedRGBA(edgeColorNumber),
395 modelLine->getMatrix(), treModel, invert);
396 treSubModel->setNonUniformFlag(modelLine->getNonUniformFlag());
397 if (parentModel->hasSpecular(colorNumber))
398 {
399 GLfloat specular[4];
400
401 parentModel->getSpecular(colorNumber, specular);
402 treSubModel->setSpecular(specular);
403 }
404 if (parentModel->hasShininess(colorNumber))
405 {
406 GLfloat shininess;
407
408 parentModel->getShininess(colorNumber, shininess);
409 treSubModel->setShininess(shininess);
410 }
411 }
412 if (treModel->isPart() && !treParentModel->isPart())
413 {
414 //finishPart(treModel, treSubModel);
415 if (strcasecmp(treModel->getName(), "light.dat") == 0)
416 {
417 treSubModel->setLightFlag(true);
418 }
419 }
420 if (TCVector::determinant(treSubModel->getMatrix()) < 0.0f)
421 {
422 // Generate an inverted version of the child model, because this
423 // reference to it involves a mirror.
424 treModel->getUnMirroredModel();
425 }
426 return true;
427 }
428
addBoundingQuad(TREModel * model,const TCVector * minMax,int face)429 void LDModelParser::addBoundingQuad(
430 TREModel *model,
431 const TCVector *minMax,
432 int face)
433 {
434 TCVector quad[4];
435 int faceIndices[][4][3] =
436 {
437 {
438 { 0, 0, 0 },
439 { 0, 1, 0 },
440 { 1, 1, 0 },
441 { 1, 0, 0 }
442 },
443 {
444 { 1, 1, 1 },
445 { 0, 1, 1 },
446 { 0, 0, 1 },
447 { 1, 0, 1 }
448 },
449 {
450 { 0, 0, 0 },
451 { 0, 0, 1 },
452 { 0, 1, 1 },
453 { 0, 1, 0 }
454 },
455 {
456 { 1, 1, 1 },
457 { 1, 0, 1 },
458 { 1, 0, 0 },
459 { 1, 1, 0 }
460 },
461 {
462 { 0, 0, 0 },
463 { 1, 0, 0 },
464 { 1, 0, 1 },
465 { 0, 0, 1 }
466 },
467 {
468 { 1, 1, 1 },
469 { 1, 1, 0 },
470 { 0, 1, 0 },
471 { 0, 1, 1 }
472 },
473 };
474 for (int q = 0; q < 4; q++)
475 {
476 for (int i = 0; i < 3; i++)
477 {
478 quad[q][i] = minMax[faceIndices[face][q][i]][i];
479 }
480 }
481 if (getBFCFlag())
482 {
483 model->addBFCQuad(quad);
484 }
485 else
486 {
487 model->addQuad(quad);
488 }
489 }
490
getActiveColorNumber(LDLModelLine * modelLine,int activeColorNumber)491 int LDModelParser::getActiveColorNumber(
492 LDLModelLine *modelLine,
493 int activeColorNumber)
494 {
495 if (modelLine)
496 {
497 int modelLineColorNumber = modelLine->getColorNumber();
498
499 if (modelLineColorNumber != 16)
500 {
501 if (modelLineColorNumber == 24)
502 {
503 LDLModel *ldlModel = modelLine->getModel();
504
505 if (ldlModel)
506 {
507 return ldlModel->getEdgeColorNumber(activeColorNumber);
508 }
509 }
510 else
511 {
512 return modelLineColorNumber;
513 }
514 }
515 }
516 return activeColorNumber;
517 }
518
modelNameKey(LDLModel * model,int activeColorNumber)519 std::string LDModelParser::modelNameKey(LDLModel *model, int activeColorNumber)
520 {
521 const char *name = model->getName();
522
523 if (model->colorNumberIsTransparent(activeColorNumber))
524 {
525 std::string nameKey;
526
527 m_obiInfo->end();
528 nameKey = "Trans:";
529 nameKey += name;
530 return nameKey;
531 }
532 else if (m_obiTokens.size() > 0 ||
533 (m_obiInfo != NULL && m_obiInfo->isActive()))
534 {
535 std::string nameKey;
536 char num[32];
537
538 sprintf(num, "%X:", m_obiUniqueId++);
539 nameKey = num;
540 nameKey += name;
541 return nameKey;
542 }
543 else
544 {
545 return name;
546 }
547 }
548
parseModel(LDLModelLine * modelLine,TREModel * treModel,bool bfc,int activeColorNumber,bool parentIsPart)549 bool LDModelParser::parseModel(
550 LDLModelLine *modelLine,
551 TREModel *treModel,
552 bool bfc,
553 int activeColorNumber,
554 bool parentIsPart)
555 {
556 LDLModel *ldlModel = modelLine->getModel();
557 bool invert = modelLine->getBFCInvert();
558
559 if (bfc)
560 {
561 bfc = modelLine->getBFCOn();
562 }
563 activeColorNumber = getActiveColorNumber(modelLine, activeColorNumber);
564 if (ldlModel->colorNumberIsTransparent(activeColorNumber))
565 {
566 bfc = false;
567 }
568 if (ldlModel)
569 {
570 TREModel *model = NULL;
571 std::string nameKey = modelNameKey(ldlModel, activeColorNumber);
572
573 model = m_mainTREModel->modelNamed(nameKey.c_str(), bfc);
574 if (model)
575 {
576 return addSubModel(modelLine, treModel, model, bfc && invert,
577 activeColorNumber);
578 }
579 else
580 {
581 model = new TREModel;
582 model->setMainModel(treModel->getMainModel());
583 model->setName(nameKey.c_str());
584 model->setPartFlag(ldlModel->isPart());
585 model->setNoShrinkFlag(ldlModel->getNoShrinkFlag());
586 if (m_flags.boundingBoxesOnly && ldlModel->isPart())
587 {
588 TCVector minMax[2];
589
590 m_mainTREModel->registerModel(model, bfc);
591 model->release();
592 ldlModel->getBoundingBox(minMax[0], minMax[1]);
593 for (int i = 0; i < 6; i++)
594 {
595 addBoundingQuad(model, minMax, i);
596 }
597 return addSubModel(modelLine, treModel, model, bfc && invert,
598 activeColorNumber);
599 }
600 else if (parseModel(ldlModel, model, bfc, activeColorNumber,
601 parentIsPart))
602 {
603 m_mainTREModel->registerModel(model, bfc);
604 model->release();
605 return addSubModel(modelLine, treModel, model, bfc && invert,
606 activeColorNumber);
607 }
608 else
609 {
610 model->release();
611 return false;
612 }
613 }
614 }
615 else
616 {
617 return false;
618 }
619 }
620
substituteStud(int numSegments)621 bool LDModelParser::substituteStud(int numSegments)
622 {
623 TCULong edgeColor = 0;
624
625 if (m_flags.obi &&
626 !m_topLDLModel->colorNumberIsTransparent(m_currentColorNumber) &&
627 m_obiTokens.find("obi_stud_cancel") == m_obiTokens.end())
628 {
629 LDLPalette *palette = m_topLDLModel->getMainModel()->getPalette();
630 int colorNumber = 0;
631
632 if (palette)
633 {
634 colorNumber = palette->getColorNumberForName("OBI_BLACK");
635 }
636 edgeColor = m_topLDLModel->getPackedRGBA(colorNumber);
637 }
638 m_currentTREModel->addCylinder(TCVector(0.0f, -4.0f, 0.0f), 6.0f, 4.0f,
639 numSegments, numSegments, getBFCFlag(), edgeColor, edgeColor);
640 m_currentTREModel->addStudDisc(TCVector(0.0f, -4.0f, 0.0f), 6.0f,
641 numSegments, numSegments, getBFCFlag());
642 if (shouldLoadEdgeLines())
643 {
644 if (getIsHighlightModel())
645 {
646 edgeColor = m_topLDLModel->getPackedRGBA(getDefaultColorNumber());
647 }
648 m_currentTREModel->addCircularEdge(TCVector(0.0f, -4.0f, 0.0f), 6.0f,
649 numSegments, -1, edgeColor);
650 m_currentTREModel->addCircularEdge(TCVector(0.0f, 0.0f, 0.0f), 6.0f,
651 numSegments, -1, edgeColor);
652 }
653 return true;
654 }
655
substituteStud(void)656 bool LDModelParser::substituteStud(void)
657 {
658 return substituteStud(getNumCircleSegments());
659 }
660
substituteStu2(void)661 bool LDModelParser::substituteStu2(void)
662 {
663 return substituteStud(LO_NUM_SEGMENTS);
664 }
665
substituteStu22(bool isA,bool bfc)666 bool LDModelParser::substituteStu22(bool isA, bool bfc)
667 {
668 int numSegments = LO_NUM_SEGMENTS;
669
670 m_currentTREModel->addCylinder(TCVector(0.0f, 0.0f, 0.0f), 4.0f, -4.0f, numSegments,
671 numSegments, bfc);
672 m_currentTREModel->addCylinder(TCVector(0.0f, -4.0f, 0.0f), 6.0f, 4.0f, numSegments,
673 numSegments, bfc);
674 m_currentTREModel->addOpenCone(TCVector(0.0f, -4.0f, 0.0f), 4.0f, 6.0f, 0.0f,
675 numSegments, numSegments, bfc);
676 if (shouldLoadEdgeLines())
677 {
678 TCULong edgeColor = 0;
679 if (getIsHighlightModel())
680 {
681 edgeColor = m_topLDLModel->getPackedRGBA(getDefaultColorNumber());
682 }
683 m_currentTREModel->addCircularEdge(TCVector(0.0f, -4.0f, 0.0f), 4.0f,
684 numSegments, -1, edgeColor);
685 m_currentTREModel->addCircularEdge(TCVector(0.0f, -4.0f, 0.0f), 6.0f,
686 numSegments, -1, edgeColor);
687 if (!isA)
688 {
689 m_currentTREModel->addCircularEdge(TCVector(0.0f, 0.0f, 0.0f), 4.0f,
690 numSegments, -1, edgeColor);
691 m_currentTREModel->addCircularEdge(TCVector(0.0f, 0.0f, 0.0f), 6.0f,
692 numSegments, -1, edgeColor);
693 }
694 }
695 return true;
696 }
697
substituteStu23(bool isA,bool bfc)698 bool LDModelParser::substituteStu23(bool isA, bool bfc)
699 {
700 int numSegments = LO_NUM_SEGMENTS;
701
702 m_currentTREModel->addCylinder(TCVector(0.0f, -4.0f, 0.0f), 4.0f, 4.0f, numSegments,
703 numSegments, bfc);
704 m_currentTREModel->addDisc(TCVector(0.0f, -4.0f, 0.0f), 4.0f, numSegments,
705 numSegments, bfc);
706 if (shouldLoadEdgeLines())
707 {
708 TCULong edgeColor = 0;
709 if (getIsHighlightModel())
710 {
711 edgeColor = m_topLDLModel->getPackedRGBA(getDefaultColorNumber());
712 }
713 m_currentTREModel->addCircularEdge(TCVector(0.0f, -4.0f, 0.0f), 4.0f,
714 numSegments, -1, edgeColor);
715 if (!isA)
716 {
717 m_currentTREModel->addCircularEdge(TCVector(0.0f, 0.0f, 0.0f), 4.0f,
718 numSegments, -1, edgeColor);
719 }
720 }
721 return true;
722 }
723
substituteStu24(bool isA,bool bfc)724 bool LDModelParser::substituteStu24(bool isA, bool bfc)
725 {
726 int numSegments = LO_NUM_SEGMENTS;
727
728 m_currentTREModel->addCylinder(TCVector(0.0f, 0.0f, 0.0f), 6.0f, -4.0f, numSegments,
729 numSegments, bfc);
730 m_currentTREModel->addCylinder(TCVector(0.0f, -4.0f, 0.0f), 8.0f, 4.0f, numSegments,
731 numSegments, bfc);
732 m_currentTREModel->addOpenCone(TCVector(0.0f, -4.0f, 0.0f), 6.0f, 8.0f, 0.0f,
733 numSegments, numSegments, bfc);
734 if (shouldLoadEdgeLines())
735 {
736 TCULong edgeColor = 0;
737 if (getIsHighlightModel())
738 {
739 edgeColor = m_topLDLModel->getPackedRGBA(getDefaultColorNumber());
740 }
741 m_currentTREModel->addCircularEdge(TCVector(0.0f, -4.0f, 0.0f), 6.0f,
742 numSegments, -1, edgeColor);
743 m_currentTREModel->addCircularEdge(TCVector(0.0f, -4.0f, 0.0f), 8.0f,
744 numSegments, -1, edgeColor);
745 if (!isA)
746 {
747 m_currentTREModel->addCircularEdge(TCVector(0.0f, 0.0f, 0.0f), 6.0f,
748 numSegments, -1, edgeColor);
749 m_currentTREModel->addCircularEdge(TCVector(0.0f, 0.0f, 0.0f), 8.0f,
750 numSegments, -1, edgeColor);
751 }
752 }
753 return true;
754 }
755
substituteTorusQ(TCFloat fraction,int size,bool bfc,bool isMixed,bool is48)756 bool LDModelParser::substituteTorusQ(TCFloat fraction, int size, bool bfc,
757 bool isMixed, bool is48)
758 {
759 int numSegments;
760 int numMinorSegments;
761
762 numSegments = getNumCircleSegments(fraction, is48);
763 numMinorSegments = getNumCircleSegments(0.0, is48 && !isMixed);
764 m_currentTREModel->addTorusIO(true, TCVector(0.0f, 0.0f, 0.0f), 1.0f,
765 getTorusFraction(size), numSegments,
766 getUsedCircleSegments(numSegments, fraction), numMinorSegments, bfc);
767 m_currentTREModel->addTorusIO(false, TCVector(0.0f, 0.0f, 0.0f), 1.0f,
768 getTorusFraction(size), numSegments,
769 getUsedCircleSegments(numSegments, fraction), numMinorSegments, bfc);
770 m_currentTREModel->addTorusIO(true, TCVector(0.0f, 0.0f, 0.0f), 1.0f,
771 -getTorusFraction(size), numSegments,
772 getUsedCircleSegments(numSegments, fraction), numMinorSegments, bfc);
773 m_currentTREModel->addTorusIO(false, TCVector(0.0f, 0.0f, 0.0f), 1.0f,
774 -getTorusFraction(size), numSegments,
775 getUsedCircleSegments(numSegments, fraction), numMinorSegments, bfc);
776 return true;
777 }
778
substituteTorusIO(bool inner,TCFloat fraction,int size,bool bfc,bool isMixed,bool is48)779 bool LDModelParser::substituteTorusIO(bool inner, TCFloat fraction, int size,
780 bool bfc, bool isMixed, bool is48)
781 {
782 int numSegments;
783 int numMinorSegments;
784 //int size;
785 //const char *modelName = m_currentTREModel->getName();
786 //TCFloat fraction;
787 //int offset = 0;
788
789 //if (is48)
790 //{
791 // offset = 3;
792 //}
793 //sscanf(modelName + 1 + offset, "%d", &numSegments);
794 //sscanf(modelName + 4 + offset, "%d", &size);
795 //fraction = (TCFloat)numSegments / 16.0f;
796 numSegments = getNumCircleSegments(fraction, is48);
797 numMinorSegments = getNumCircleSegments(0.0, is48 && !isMixed);
798 m_currentTREModel->addTorusIO(inner, TCVector(0.0f, 0.0f, 0.0f), 1.0f,
799 getTorusFraction(size), numSegments,
800 getUsedCircleSegments(numSegments, fraction), numMinorSegments, bfc);
801 return true;
802 }
803
substituteEighthSphere(bool bfc,bool is48)804 bool LDModelParser::substituteEighthSphere(bool bfc,
805 bool is48)
806 {
807 int numSegments = getNumCircleSegments(1.0, is48);
808
809 m_currentTREModel->addEighthSphere(TCVector(0.0f, 0.0f, 0.0f), 1.0f, numSegments,
810 bfc);
811 return true;
812 }
813
substituteCylinder(TCFloat fraction,bool bfc,bool is48)814 bool LDModelParser::substituteCylinder(TCFloat fraction,
815 bool bfc, bool is48)
816 {
817 int numSegments = getNumCircleSegments(fraction, is48);
818
819 m_currentTREModel->addCylinder(TCVector(0.0f, 0.0f, 0.0f), 1.0f, 1.0f, numSegments,
820 getUsedCircleSegments(numSegments, fraction), bfc);
821 return true;
822 }
823
substituteSlopedCylinder(TCFloat fraction,bool bfc,bool is48)824 bool LDModelParser::substituteSlopedCylinder(TCFloat fraction,
825 bool bfc, bool is48)
826 {
827 int numSegments = getNumCircleSegments(fraction, is48);
828
829 m_currentTREModel->addSlopedCylinder(TCVector(0.0f, 0.0f, 0.0f), 1.0f, 1.0f,
830 numSegments, getUsedCircleSegments(numSegments, fraction), bfc);
831 return true;
832 }
833
substituteSlopedCylinder2(TCFloat fraction,bool bfc,bool is48)834 bool LDModelParser::substituteSlopedCylinder2(TCFloat fraction, bool bfc,
835 bool is48)
836 {
837 int numSegments = getNumCircleSegments(fraction, is48);
838
839 m_currentTREModel->addSlopedCylinder2(TCVector(0.0f, 0.0f, 0.0f), 1.0f, 1.0f,
840 numSegments, getUsedCircleSegments(numSegments, fraction), bfc);
841 return true;
842 }
843
substituteChrd(TCFloat fraction,bool bfc,bool is48)844 bool LDModelParser::substituteChrd(TCFloat fraction, bool bfc,
845 bool is48)
846 {
847 int numSegments = getNumCircleSegments(fraction, is48);
848
849 m_currentTREModel->addChrd(TCVector(0.0f, 0.0f, 0.0f), 1.0f, numSegments,
850 getUsedCircleSegments(numSegments, fraction), bfc);
851 return true;
852 }
853
substituteDisc(TCFloat fraction,bool bfc,bool is48)854 bool LDModelParser::substituteDisc(TCFloat fraction, bool bfc,
855 bool is48)
856 {
857 int numSegments = getNumCircleSegments(fraction, is48);
858
859 m_currentTREModel->addDisc(TCVector(0.0f, 0.0f, 0.0f), 1.0f, numSegments,
860 getUsedCircleSegments(numSegments, fraction), bfc);
861 return true;
862 }
863
substituteNotDisc(TCFloat fraction,bool bfc,bool is48)864 bool LDModelParser::substituteNotDisc(TCFloat fraction,
865 bool bfc, bool is48)
866 {
867 int numSegments = getNumCircleSegments(fraction, is48);
868
869 m_currentTREModel->addNotDisc(TCVector(0.0f, 0.0f, 0.0f), 1.0f, numSegments,
870 getUsedCircleSegments(numSegments, fraction), bfc);
871 return true;
872 }
873
substituteTangent(TCFloat fraction,bool bfc,bool is48)874 bool LDModelParser::substituteTangent(TCFloat fraction,
875 bool bfc, bool is48)
876 {
877 int numSegments = getNumCircleSegments(fraction, is48);
878
879 while (numSegments % 16 != 0)
880 {
881 numSegments += LO_NUM_SEGMENTS;
882 }
883 m_currentTREModel->addTangent(TCVector(0.0f, 0.0f, 0.0f), 1.0f, numSegments,
884 getUsedCircleSegments(numSegments, fraction), bfc);
885 return true;
886 }
887
substituteCircularEdge(TCFloat fraction,bool is48)888 bool LDModelParser::substituteCircularEdge(TCFloat fraction,
889 bool is48)
890 {
891 if (shouldLoadEdgeLines())
892 {
893 TCULong edgeColor = 0;
894 if (getIsHighlightModel())
895 {
896 edgeColor = m_topLDLModel->getPackedRGBA(getDefaultColorNumber());
897 }
898 int numSegments = getNumCircleSegments(fraction, is48);
899
900 m_currentTREModel->addCircularEdge(TCVector(0.0f, 0.0f, 0.0f), 1.0f, numSegments,
901 getUsedCircleSegments(numSegments, fraction), edgeColor);
902 }
903 return true;
904 }
905
substituteCone(TCFloat fraction,int size,bool bfc,bool is48)906 bool LDModelParser::substituteCone(TCFloat fraction, int size,
907 bool bfc, bool is48)
908 {
909 int numSegments = getNumCircleSegments(fraction, is48);
910
911 m_currentTREModel->addOpenCone(TCVector(0.0f, 0.0f, 0.0f), (TCFloat)size + 1.0f,
912 (TCFloat)size, 1.0f, numSegments,
913 getUsedCircleSegments(numSegments, fraction), bfc);
914 return true;
915 }
916
substituteRing(TCFloat fraction,int size,bool bfc,bool is48,bool)917 bool LDModelParser::substituteRing(TCFloat fraction, int size,
918 bool bfc, bool is48, bool /*isOld*/)
919 {
920 int numSegments = getNumCircleSegments(fraction, is48);
921
922 m_currentTREModel->addRing(TCVector(0.0f, 0.0f, 0.0f), (TCFloat)size,
923 (TCFloat)size + 1.0f, numSegments,
924 getUsedCircleSegments(numSegments, fraction), bfc);
925 return true;
926 }
927
performPrimitiveSubstitution2(LDLModel * ldlModel,TREModel * treModel,int activeColorNumber,bool bfc)928 bool LDModelParser::performPrimitiveSubstitution2(
929 LDLModel *ldlModel,
930 TREModel *treModel,
931 int activeColorNumber,
932 bool bfc)
933 {
934 m_currentTREModel = treModel;
935 m_currentColorNumber = activeColorNumber;
936 return LDLPrimitiveCheck::performPrimitiveSubstitution(ldlModel, bfc);
937 }
938
actionLineIsActive(LDLActionLine * actionLine)939 bool LDModelParser::actionLineIsActive(LDLActionLine *actionLine)
940 {
941 if (getTexmapsFlag())
942 {
943 // If texmaps are enabled, we need to skip the fallback geometry.
944 return !actionLine->isTexmapFallback();
945 }
946 else
947 {
948 // If texmaps are disabled, we need to skip the texmap geometry.
949 return actionLine->getTexmapFilename().size() == 0;
950 }
951 }
952
parseModel(LDLModel * ldlModel,TREModel * treModel,bool bfc,int activeColorNumber,bool parentIsPart)953 bool LDModelParser::parseModel(
954 LDLModel *ldlModel,
955 TREModel *treModel,
956 bool bfc,
957 int activeColorNumber,
958 bool parentIsPart)
959 {
960 BFCState newState = ldlModel->getBFCState();
961 LDObiInfo obiInfo;
962 LDObiInfo *origObiInfo = m_obiInfo;
963
964 if (m_obiInfo != NULL && m_obiInfo->isActive() &&
965 !ldlModel->colorNumberIsTransparent(activeColorNumber))
966 {
967 obiInfo.start(m_obiInfo->getColor(), m_obiInfo->getEdgeColor(), true);
968 }
969 m_obiInfo = &obiInfo;
970 if (newState == BFCForcedOnState && parentIsPart)
971 {
972 newState = BFCOnState;
973 }
974 bfc = ((bfc && (newState == BFCOnState)) || newState == BFCForcedOnState)
975 && getBFCFlag() && !ldlModel->colorNumberIsTransparent(activeColorNumber);
976 if (ldlModel && !performPrimitiveSubstitution2(ldlModel, treModel,
977 activeColorNumber, bfc))
978 {
979 LDLFileLineArray *fileLines = ldlModel->getFileLines();
980
981 if (fileLines)
982 {
983 int i;
984 int count = ldlModel->getActiveLineCount();
985 StringSet obiOrigTokens = m_obiTokens;
986
987 for (i = 0; i < count && !m_abort; i++)
988 {
989 LDLFileLine *fileLine = (*fileLines)[i];
990
991 if (fileLine->isValid())
992 {
993 if (fileLine->isActionLine() &&
994 actionLineIsActive((LDLActionLine *)fileLine))
995 {
996 if (m_flags.newTexmap)
997 {
998 treModel->startTexture(fileLine->getTexmapType(),
999 fileLine->getTexmapFilename(),
1000 fileLine->getTexmapImage(),
1001 fileLine->getTexmapPoints(),
1002 fileLine->getTexmapExtra());
1003 m_flags.newTexmap = false;
1004 m_flags.texmapStarted = true;
1005 }
1006 //if (m_flags.obi)
1007 //{
1008 // ((LDLActionLine *)fileLine)->setObiOverrideActive(
1009 // !ldlModel->colorNumberIsTransparent(
1010 // activeColorNumber));
1011 //}
1012 switch (fileLine->getLineType())
1013 {
1014 case LDLLineTypeModel:
1015 parseModel((LDLModelLine *)fileLine, treModel, bfc,
1016 activeColorNumber, ldlModel->isPart());
1017 break;
1018 case LDLLineTypeLine:
1019 parseLine((LDLShapeLine *)fileLine, treModel,
1020 activeColorNumber);
1021 break;
1022 case LDLLineTypeTriangle:
1023 parseTriangle((LDLShapeLine *)fileLine, treModel,
1024 bfc, false, activeColorNumber);
1025 break;
1026 case LDLLineTypeQuad:
1027 parseQuad((LDLShapeLine *)fileLine, treModel, bfc,
1028 false, activeColorNumber);
1029 break;
1030 case LDLLineTypeConditionalLine:
1031 parseConditionalLine(
1032 (LDLConditionalLineLine *)fileLine, treModel,
1033 activeColorNumber);
1034 break;
1035 default:
1036 break;
1037 }
1038 m_obiInfo->actionHappened();
1039 if (m_flags.texmapNext)
1040 {
1041 treModel->endTexture();
1042 }
1043 }
1044 else if (fileLine->getLineType() == LDLLineTypeComment)
1045 {
1046 parseCommentLine((LDLCommentLine *)fileLine, treModel);
1047 }
1048 }
1049 if (ldlModel == m_topLDLModel && m_alertSender != NULL)
1050 {
1051 TCProgressAlert::send("LDLModelParser",
1052 TCLocalStrings::get(_UC("ParsingStatus")),
1053 (float)(i + 1) / (float)(count + 1), &m_abort, this);
1054 }
1055 }
1056 m_obiTokens = obiOrigTokens;
1057 }
1058 }
1059 m_obiInfo = origObiInfo;
1060 return !m_abort;
1061 }
1062
1063 // Note: static method
unsetToken(StringSet & tokens,const char * token)1064 bool LDModelParser::unsetToken(StringSet &tokens, const char *token)
1065 {
1066 StringSet::iterator it = tokens.find(token);
1067
1068 if (it != tokens.end())
1069 {
1070 tokens.erase(it);
1071 return true;
1072 }
1073 return false;
1074 }
1075
parseCommentLine(LDLCommentLine * commentLine,TREModel * treModel)1076 void LDModelParser::parseCommentLine(
1077 LDLCommentLine *commentLine,
1078 TREModel *treModel)
1079 {
1080 if (commentLine->isStepMeta())
1081 {
1082 treModel->nextStep();
1083 }
1084 else if (commentLine->isOBIMeta())
1085 {
1086 if (m_flags.obi)
1087 {
1088 // 0 !OBI SET <token>
1089 // 0 !OBI UNSET <token>
1090 // 0 !OBI NEXT <color> [IFSET <token>|IFNSET <token>]
1091 // 0 !OBI START <color> [IFSET <token>|IFNSET <token>]
1092 // 0 !OBI END
1093 switch (commentLine->getOBICommand())
1094 {
1095 case LDLCommentLine::OBICSet:
1096 if (commentLine->hasOBIToken())
1097 {
1098 std::string token = commentLine->getOBIToken();
1099
1100 convertStringToLower(&token[0]);
1101 m_obiTokens.insert(token);
1102 }
1103 break;
1104 case LDLCommentLine::OBICUnset:
1105 if (commentLine->hasOBIToken())
1106 {
1107 std::string token = commentLine->getOBIToken();
1108
1109 convertStringToLower(&token[0]);
1110 unsetToken(m_obiTokens, token.c_str());
1111 }
1112 break;
1113 case LDLCommentLine::OBICNext:
1114 case LDLCommentLine::OBICStart:
1115 m_obiInfo->start(commentLine, m_obiTokens);
1116 break;
1117 case LDLCommentLine::OBICEnd:
1118 m_obiInfo->end();
1119 break;
1120 default:
1121 // Gets rid of warning.
1122 break;
1123 }
1124 }
1125 }
1126 else if (commentLine->isTexmapMeta() && getTexmapsFlag() &&
1127 commentLine->isValid())
1128 {
1129 bool isStart = commentLine->containsTexmapCommand("START");
1130 bool isNext = commentLine->containsTexmapCommand("NEXT");
1131
1132 if (isStart || isNext)
1133 {
1134 // Note: the data has already been copied out of this command and
1135 // into the associated action lines. We just want to know that we
1136 // got here so we can activate the new texmap.
1137 m_flags.newTexmap = true;
1138 m_flags.texmapNext = isNext;
1139 }
1140 else if (commentLine->containsTexmapCommand("END"))
1141 {
1142 if (m_flags.texmapStarted)
1143 {
1144 treModel->endTexture();
1145 m_flags.texmapStarted = false;
1146 }
1147 else
1148 {
1149 // If the texmap didn't contain any geometry we need to clear
1150 // the newTexmap flag. Ideally we should also warn, but that's
1151 // not critical.
1152 m_flags.newTexmap = false;
1153 }
1154 }
1155 }
1156 }
1157
parseLine(LDLShapeLine * shapeLine,TREModel * treModel,int activeColorNumber)1158 void LDModelParser::parseLine(
1159 LDLShapeLine *shapeLine,
1160 TREModel *treModel,
1161 int activeColorNumber)
1162 {
1163 int colorNumber = actualColorNumber(shapeLine, activeColorNumber);
1164 //TCULong colorNumber = shapeLine->getColorNumber();
1165
1166 if (colorNumber == 16)
1167 {
1168 if (!getEdgesOnlyFlag())
1169 {
1170 treModel->addLine(shapeLine->getPoints());
1171 }
1172 }
1173 else if (colorNumber == 24)
1174 {
1175 if (shouldLoadEdgeLines())
1176 {
1177 TCULong edgeColor = 0;
1178 if (getIsHighlightModel())
1179 {
1180 edgeColor = m_topLDLModel->getPackedRGBA(getDefaultColorNumber());
1181 }
1182 treModel->addEdgeLine(shapeLine->getPoints(), edgeColor);
1183 }
1184 }
1185 else if (!getEdgesOnlyFlag())
1186 {
1187 treModel->addLine(shapeLine->getParentModel()->
1188 getPackedRGBA(colorNumber), shapeLine->getPoints());
1189 }
1190 }
1191
parseConditionalLine(LDLConditionalLineLine * conditionalLine,TREModel * treModel,int activeColorNumber)1192 void LDModelParser::parseConditionalLine(
1193 LDLConditionalLineLine
1194 *conditionalLine,
1195 TREModel *treModel,
1196 int activeColorNumber)
1197 {
1198 if (shouldLoadConditionalLines())
1199 {
1200 int colorNumber = actualColorNumber(conditionalLine, activeColorNumber);
1201 TCULong color = 0;
1202
1203 if (colorNumber != 24)
1204 {
1205 color = conditionalLine->getParentModel()->getPackedRGBA(
1206 colorNumber);
1207 }
1208 treModel->addConditionalLine(conditionalLine->getPoints(),
1209 conditionalLine->getControlPoints(), color);
1210 }
1211 }
1212
shouldFlipWinding(bool invert,bool windingCCW)1213 bool LDModelParser::shouldFlipWinding(bool invert, bool windingCCW)
1214 {
1215 return (invert && windingCCW) || (!invert && !windingCCW);
1216 }
1217
parseTriangle(LDLShapeLine * shapeLine,TREModel * treModel,bool bfc,bool invert,int activeColorNumber)1218 void LDModelParser::parseTriangle(
1219 LDLShapeLine *shapeLine,
1220 TREModel *treModel,
1221 bool bfc,
1222 bool invert,
1223 int activeColorNumber)
1224 {
1225 int colorNumber = actualColorNumber(shapeLine, activeColorNumber);
1226 //TCULong colorNumber = shapeLine->getColorNumber();
1227
1228 if (bfc)
1229 {
1230 bfc = shapeLine->getBFCOn();
1231 }
1232 if (colorNumber == 16)
1233 {
1234 if (bfc)
1235 {
1236 if (shouldFlipWinding(invert, shapeLine->getBFCWindingCCW()))
1237 {
1238 TCVector points[3];
1239
1240 points[0] = shapeLine->getPoints()[2];
1241 points[1] = shapeLine->getPoints()[1];
1242 points[2] = shapeLine->getPoints()[0];
1243 treModel->addBFCTriangle(points);
1244 }
1245 else
1246 {
1247 treModel->addBFCTriangle(shapeLine->getPoints());
1248 }
1249 }
1250 else
1251 {
1252 treModel->addTriangle(shapeLine->getPoints());
1253 }
1254 }
1255 else
1256 {
1257 if (bfc)
1258 {
1259 if (shouldFlipWinding(invert, shapeLine->getBFCWindingCCW()))
1260 {
1261 TCVector points[3];
1262
1263 points[0] = shapeLine->getPoints()[2];
1264 points[1] = shapeLine->getPoints()[1];
1265 points[2] = shapeLine->getPoints()[0];
1266 treModel->addBFCTriangle(shapeLine->getParentModel()->
1267 getPackedRGBA(colorNumber), points);
1268 }
1269 else
1270 {
1271 treModel->addBFCTriangle(shapeLine->getParentModel()->
1272 getPackedRGBA(colorNumber), shapeLine->getPoints());
1273 }
1274 }
1275 else
1276 {
1277 treModel->addTriangle(shapeLine->getParentModel()->
1278 getPackedRGBA(colorNumber), shapeLine->getPoints());
1279 }
1280 }
1281 }
1282
actualColorNumber(LDLActionLine * actionLine,int activeColorNumber)1283 int LDModelParser::actualColorNumber(
1284 LDLActionLine *actionLine,
1285 int activeColorNumber)
1286 {
1287 int colorNumber = actionLine->getColorNumber();
1288 LDLModel *model = actionLine->getParentModel();
1289
1290 if (model && !model->colorNumberIsTransparent(activeColorNumber))
1291 {
1292 TCULong color;
1293
1294 switch (colorNumber)
1295 {
1296 case 16:
1297 color = m_obiInfo->getColor();
1298 break;
1299 case 24:
1300 color = m_obiInfo->getEdgeColor();
1301 break;
1302 default:
1303 color = 0;
1304 break;
1305 }
1306 if (color != 0)
1307 {
1308 return LDLPalette::colorNumberForPackedRGBA(color);
1309 }
1310 }
1311 return colorNumber;
1312 }
1313
parseQuad(LDLShapeLine * shapeLine,TREModel * treModel,bool bfc,bool invert,int activeColorNumber)1314 void LDModelParser::parseQuad(
1315 LDLShapeLine *shapeLine,
1316 TREModel *treModel,
1317 bool bfc,
1318 bool invert,
1319 int activeColorNumber)
1320 {
1321 int colorNumber = actualColorNumber(shapeLine, activeColorNumber);
1322
1323 if (bfc)
1324 {
1325 bfc = shapeLine->getBFCOn();
1326 }
1327 if (colorNumber == 16)
1328 {
1329 if (bfc)
1330 {
1331 if (shouldFlipWinding(invert, shapeLine->getBFCWindingCCW()))
1332 {
1333 TCVector points[4];
1334
1335 points[0] = shapeLine->getPoints()[3];
1336 points[1] = shapeLine->getPoints()[2];
1337 points[2] = shapeLine->getPoints()[1];
1338 points[3] = shapeLine->getPoints()[0];
1339 treModel->addBFCQuad(points);
1340 }
1341 else
1342 {
1343 treModel->addBFCQuad(shapeLine->getPoints());
1344 }
1345 }
1346 else
1347 {
1348 treModel->addQuad(shapeLine->getPoints());
1349 }
1350 }
1351 else
1352 {
1353 if (bfc)
1354 {
1355 if (shouldFlipWinding(invert, shapeLine->getBFCWindingCCW()))
1356 {
1357 TCVector points[4];
1358
1359 points[0] = shapeLine->getPoints()[3];
1360 points[1] = shapeLine->getPoints()[2];
1361 points[2] = shapeLine->getPoints()[1];
1362 points[3] = shapeLine->getPoints()[0];
1363 treModel->addBFCQuad(shapeLine->getParentModel()->
1364 getPackedRGBA(colorNumber), points);
1365 }
1366 else
1367 {
1368 treModel->addBFCQuad(shapeLine->getParentModel()->
1369 getPackedRGBA(colorNumber), shapeLine->getPoints());
1370 }
1371 }
1372 else
1373 {
1374 treModel->addQuad(shapeLine->getParentModel()->
1375 getPackedRGBA(colorNumber), shapeLine->getPoints());
1376 }
1377 }
1378 }
1379
setSeamWidth(TCFloat seamWidth)1380 void LDModelParser::setSeamWidth(TCFloat seamWidth)
1381 {
1382 m_seamWidth = seamWidth;
1383 if (m_seamWidth)
1384 {
1385 setSeamsFlag(true);
1386 }
1387 else
1388 {
1389 setSeamsFlag(false);
1390 }
1391 }
1392
getSeamWidth(void)1393 TCFloat LDModelParser::getSeamWidth(void)
1394 {
1395 if (getSeamsFlag())
1396 {
1397 return m_seamWidth;
1398 }
1399 else
1400 {
1401 return 0.0f;
1402 }
1403 }
1404
1405