source: cpp/frams/model/geometry/meshbuilder.cpp @ 262

Last change on this file since 262 was 262, checked in by Maciej Komosinski, 10 years ago

Geometry evaluation no longer crashes for models that contain only unsupported cylinder shapes [refs #46]

  • Property svn:eol-style set to native
File size: 19.2 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 2002-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include "meshbuilder.h"
6
7#include <frams/model/geometry/modelgeometryinfo.h>
8#include <stdio.h>
9#include <math.h>
10
11MeshBuilder::Iterator::Iterator(const double _density):
12        density(_density)
13{}
14
15double MeshBuilder::Iterator::getDensity() const
16{
17        return density;
18}
19
20void MeshBuilder::Iterator::setDensity(const double _density)
21{
22        density = _density;
23}
24
25void MeshBuilder::Iterator::forEach(Callback &callback)
26{
27        Pt3D point;
28       
29        while (tryGetNext(point))
30        {
31                callback(point);
32        }
33}
34
35void MeshBuilder::Iterator::addAllPointsToList(SListTempl<Pt3D> &list)
36{
37        Pt3D point;
38       
39        while (tryGetNext(point))
40        {
41                list += point;
42        }
43}
44
45
46
47MeshBuilder::Segment::Segment(const double _density):
48        Iterator(_density), point1(0), point2(0), i(0), I(0), numberOfPoints(0)
49{}
50
51void MeshBuilder::Segment::initialize(const Pt3D &point1, const Pt3D &point2, const bool skipFirst, const bool skipLast, const bool forceOddNumberOfPoints)
52{
53        this->point1 = point1;
54        this->point2 = point2;
55        numberOfPoints = (int)ceil(density * point1.distanceTo(point2)) + 1;
56        numberOfPoints += forceOddNumberOfPoints && (numberOfPoints%2 == 0) ? 1 : 0;
57        i = skipFirst ? 1 : 0;
58        I = numberOfPoints - (skipLast ? 1 : 0);
59}
60
61bool MeshBuilder::Segment::tryGetNext(Pt3D &point)
62{
63        if (i >= I)
64        {
65                return false;
66        }
67       
68        double position = GeometryUtils::pointPosition(i, numberOfPoints);
69        point.x = GeometryUtils::combination(point1.x, point2.x, position);
70        point.y = GeometryUtils::combination(point1.y, point2.y, position);
71        point.z = GeometryUtils::combination(point1.z, point2.z, position);
72       
73        i += 1;
74        return true;
75}
76
77
78
79MeshBuilder::RectangleSurface::RectangleSurface(const double _density):
80        Iterator(_density), edge1(_density), edge2(_density), area(_density), skipVerticalEdges(false), forceOddNumberOfPoints(false)
81{}
82
83void MeshBuilder::RectangleSurface::initialize(const Part *part, const CuboidFaces::Face face, const bool skipVerticalEdges, const bool skipHorizontalEdges, const bool forceOddNumberOfPoints)
84{
85        Pt3D apex1, apex2, apex3, apex4;
86        GeometryUtils::getRectangleApicesFromCuboid(part, face, apex1, apex2, apex3, apex4);
87        initialize(apex1, apex2, apex3, apex4, skipVerticalEdges, skipHorizontalEdges, forceOddNumberOfPoints);
88}
89
90void MeshBuilder::RectangleSurface::initialize(const double width, const double height, const Pt3D &position, const Orient &orient, const bool skipVerticalEdges, const bool skipHorizontalEdges, const bool forceOddNumberOfPoints)
91{
92        Pt3D apex1, apex2, apex3, apex4;
93        GeometryUtils::getRectangleApices(width, height, position, orient, apex1, apex2, apex3, apex4);
94        initialize(apex1, apex2, apex3, apex4, skipVerticalEdges, skipHorizontalEdges, forceOddNumberOfPoints);
95}
96
97void MeshBuilder::RectangleSurface::initialize(const Pt3D &apex1, const Pt3D &apex2, const Pt3D &apex3, const Pt3D &apex4, const bool skipVerticalEdges, const bool skipHorizontalEdges, const bool forceOddNumberOfPoints)
98{
99        this->skipVerticalEdges = skipVerticalEdges;
100        this->forceOddNumberOfPoints = forceOddNumberOfPoints;
101       
102        edge1.setDensity(density);
103        edge1.initialize(apex1, apex2, skipHorizontalEdges, skipHorizontalEdges, forceOddNumberOfPoints);
104       
105        edge2.setDensity(density);
106        edge2.initialize(apex3, apex4, skipHorizontalEdges, skipHorizontalEdges, forceOddNumberOfPoints);
107       
108        area = Segment(density);
109}
110
111bool MeshBuilder::RectangleSurface::tryGetNext(Pt3D &point)
112{
113        while (!area.tryGetNext(point))
114        {
115                Pt3D point1, point2;
116                if (edge1.tryGetNext(point1) && edge2.tryGetNext(point2))
117                {
118                        area.initialize(point1, point2, skipVerticalEdges, skipVerticalEdges, forceOddNumberOfPoints);
119                }
120                else
121                {
122                        return false;
123                }
124        }
125       
126        return true;
127}
128
129
130
131MeshBuilder::CuboidApices::CuboidApices():
132        Iterator(0), scale(0), position(0), orient(Orient_1), octant(Octants::NUMBER)
133{}
134
135void MeshBuilder::CuboidApices::initialize(const Part *part)
136{
137        initialize(part->scale, part->p, part->o);
138}
139
140void MeshBuilder::CuboidApices::initialize(const Pt3D &scale, const Pt3D &position, const Orient &orient)
141{
142        this->scale = scale;
143        this->position = position;
144        this->orient = orient;
145        octant = Octants::FIRST;
146}
147
148bool MeshBuilder::CuboidApices::tryGetNext(Pt3D &point)
149{
150        if (octant == Octants::NUMBER)
151        {
152                return false;
153        }
154       
155        Pt3D temp(scale);
156       
157        temp.x *= Octants::isPositiveX(octant) ? 1 : -1;
158        temp.y *= Octants::isPositiveY(octant) ? 1 : -1;
159        temp.z *= Octants::isPositiveZ(octant) ? 1 : -1;
160       
161        orient.transform(point, temp);
162        point += position;
163       
164        octant = Octants::Octant(octant+1);
165       
166        return true;
167}
168
169
170
171MeshBuilder::CuboidSurface::CuboidSurface(const double _density):
172        Iterator(_density), apices(), rectangle(_density), iterator(NULL), part(NULL), face(CuboidFaces::NUMBER)
173{}
174
175void MeshBuilder::CuboidSurface::initialize(const Part *part)
176{
177        this->part = part;
178        face = CuboidFaces::FIRST;
179        apices.setDensity(density);
180        apices.initialize(part);
181        iterator = &apices;
182        rectangle.setDensity(density);
183}
184
185bool MeshBuilder::CuboidSurface::tryGetNext(Pt3D &point)
186{
187        if (iterator == NULL)
188        {
189                return false;
190        }
191       
192        while(!iterator->tryGetNext(point))
193        {
194                if (face < CuboidFaces::NUMBER)
195                {
196                        iterator = &rectangle;
197                        rectangle.initialize(part, face, true, false);
198                        face = CuboidFaces::Face(face+1);
199                }
200                else
201                {
202                        return false;
203                }
204        }
205       
206        return true;
207}
208
209
210
211MeshBuilder::EllipseSurface::EllipseSurface(const double _density):
212        Iterator(_density), rectangle(_density), position(0), orient(Orient_1), inversedSquaredWidth(0.0), inversedSquaredHeight(0.0)
213{}
214
215void MeshBuilder::EllipseSurface::initialize(const Part *part, const CylinderBases::Base base)
216{
217        double relativePositionX = part->scale.x;
218        relativePositionX *= CylinderBases::isPositive(base) ? +1 : -1;
219        Pt3D relativePosition;
220        part->o.transform(relativePosition, Pt3D(relativePositionX, 0.0, 0.0));
221        initialize(part->scale.y, part->scale.z, part->p + relativePosition, part->o);
222}
223
224void MeshBuilder::EllipseSurface::initialize(const double width, const double height, const Pt3D &position, const Orient &orient)
225{
226        this->position = position;
227        this->orient = orient;
228        rectangle.setDensity(density);
229        rectangle.initialize(width, height, Pt3D(0), Orient_1, false, false, true);
230        inversedSquaredWidth = 1.0 / pow(width, 2.0);
231        inversedSquaredHeight = 1.0 / pow(height, 2.0);
232}
233
234bool MeshBuilder::EllipseSurface::tryGetNext(Pt3D &point)
235{
236        Pt3D temp;
237       
238        while (rectangle.tryGetNext(temp))
239        {
240                double r
241                        = (pow(temp.y, 2.0) * inversedSquaredWidth)
242                        + (pow(temp.z, 2.0) * inversedSquaredHeight);
243                if (r <= 1.0)
244                {
245                        orient.transform(point, temp);
246                        point += position;
247                        return true;
248                }
249        }
250       
251        return false;
252}
253
254
255
256MeshBuilder::Ellipse::Ellipse(const double _density):
257        Iterator(_density), phase(Done), position(0), orient(Orient_1), width(0.0), height(0.0), d(0.0), p(0.0), q(0.0), P(0.0), Q(0.0), D(0.0), a(0.0), b(0.0), quadrant(QuadrantsYZ::FIRST)
258{}
259
260void MeshBuilder::Ellipse::initialize(const Part *part, const CylinderBases::Base base)
261{
262        double relativePositionX = part->scale.x;
263        relativePositionX *= CylinderBases::isPositive(base) ? +1 : -1;
264        Pt3D relativePosition;
265        part->o.transform(relativePosition, Pt3D(relativePositionX, 0.0, 0.0));
266        initialize(part->scale.y, part->scale.z, part->p + relativePosition, part->o);
267}
268
269void MeshBuilder::Ellipse::initialize(const double width, const double height, const Pt3D &position, const Orient &orient)
270{
271        this->width = width;
272        this->height = height;
273        this->position = position;
274        this->orient = orient;
275        calculateAndSetSegmentationDistance();
276        initializePhase(yToZ);
277        D = 0;
278}
279
280bool MeshBuilder::Ellipse::tryGetNext(Pt3D &point)
281{
282        if (phase == Done)
283        {
284                return false;
285        }
286       
287        setPoint(point);
288       
289        quadrant = QuadrantsYZ::QuadrantYZ(quadrant+1);
290       
291        if (quadrant == QuadrantsYZ::NUMBER)
292        {
293                quadrant = QuadrantsYZ::FIRST;
294                findNextPQAndPhase();
295        }
296       
297        return true;
298}
299
300void MeshBuilder::Ellipse::calculateAndSetSegmentationDistance()
301{
302        d = 1.0 / density;
303        int i = 0;
304       
305        Pt3D p1(0);
306        i += findLastPQOfPhase(yToZ, p1.z, p1.y);
307       
308        Pt3D p2(0);
309        i += findLastPQOfPhase(zToY, p2.y, p2.z);
310               
311        double ld = p1.distanceTo(p2);
312        double td = i * d + ld;
313        int n = (int)ceil(td * density);
314        d = td / n;
315}
316
317void MeshBuilder::Ellipse::initializePhase(Phase ph)
318{
319        phase = ph;
320       
321        if (phase != Done)
322        {
323                a = phase == yToZ ? height : width;
324                b = phase == yToZ ? width : height;
325               
326                p = 0.0;
327                q = b;
328                P = a*a / sqrt(a*a + b*b);
329                Q = b*b / sqrt(a*a + b*b);
330               
331                quadrant = QuadrantsYZ::POSITIVE_Y_NEGATIVE_Z;
332        }
333}
334
335void MeshBuilder::Ellipse::setPoint(Pt3D &point)
336{
337        double np = p * (QuadrantsYZ::isPositiveY(quadrant) ? +1 : -1);
338        double nq = q * (QuadrantsYZ::isPositiveZ(quadrant) ? +1 : -1);
339       
340        double y = phase == yToZ ? nq : np;
341        double z = phase == yToZ ? np : nq;
342       
343        Pt3D temp(0.0, y, z);
344        orient.transform(point, temp);
345        point += position;
346}
347
348void MeshBuilder::Ellipse::findNextPQAndPhase()
349{
350        double _p = p;
351        double _q = q;
352       
353        GeometryUtils::getNextEllipseSegmentationPoint(d, a, b, p, q);
354       
355        if (p > P)
356        {
357                D += sqrt(pow(P-_p, 2.0) + pow(Q-_q, 2.0));
358               
359                if ((phase == zToY) && (D > 1.5 * d))
360                {
361                        p = P;
362                        q = Q;
363                        D = 0;
364                }
365                else
366                {
367                        initializePhase(Phase(phase+1));
368                }
369        }
370}
371
372int MeshBuilder::Ellipse::findLastPQOfPhase(Phase ph, double &lp, double &lq)
373{
374        initializePhase(ph);
375        int i = 0;
376       
377        do
378        {
379                lp = p;
380                lq = q;
381               
382                GeometryUtils::getNextEllipseSegmentationPoint(d, a, b, p, q);
383               
384                i += p <= P ? 1 : 0;
385        } while (p <= P);
386       
387        return i;
388}
389
390MeshBuilder::CylinderEdges::CylinderEdges(const double _density):
391        Iterator(_density), ellipse(_density), edge(0.0), length(0.0), base(CylinderBases::NUMBER)
392{}
393
394void MeshBuilder::CylinderEdges::initialize(const Part *part)
395{
396        initialize(part->scale, part->p, part->o);
397}
398
399void MeshBuilder::CylinderEdges::initialize(const Pt3D &scale, const Pt3D &position, const Orient &orient)
400{
401        initialize(scale.x, scale.y, scale.z, position, orient);
402}
403
404void MeshBuilder::CylinderEdges::initialize(const double length, const double width, const double height, const Pt3D &position, const Orient &orient)
405{
406        ellipse.setDensity(density);
407        ellipse.initialize(width, height, position, orient);
408       
409        orient.transform(this->length, Pt3D(length, 0.0, 0.0));
410       
411        base = CylinderBases::NUMBER;
412}
413
414bool MeshBuilder::CylinderEdges::tryGetNext(Pt3D &point)
415{
416        if (base == CylinderBases::NUMBER)
417        {
418                if (!ellipse.tryGetNext(edge))
419                {
420                        return false;
421                }
422               
423                base = CylinderBases::FIRST;
424        }
425       
426        point.x = edge.x + length.x * (CylinderBases::isPositive(base) ? +1 : -1);
427        point.y = edge.y + length.y * (CylinderBases::isPositive(base) ? +1 : -1);
428        point.z = edge.z + length.z * (CylinderBases::isPositive(base) ? +1 : -1);
429       
430        base = CylinderBases::Base(base+1);
431       
432        return true;
433}
434
435
436
437MeshBuilder::CylinderWallSurface::CylinderWallSurface(const double _density):
438        Iterator(_density), edge(_density), length(0.0), area(_density)
439{}
440
441void MeshBuilder::CylinderWallSurface::initialize(const Part *part)
442{
443        initialize(part->scale, part->p, part->o);
444}
445
446void MeshBuilder::CylinderWallSurface::initialize(const Pt3D &scale, const Pt3D &position, const Orient &orient)
447{
448        initialize(scale.x, scale.y, scale.z, position, orient);
449}
450
451void MeshBuilder::CylinderWallSurface::initialize(const double length, const double width, const double height, const Pt3D &position, const Orient &orient)
452{
453        edge.setDensity(density);
454        edge.initialize(width, height, position, orient);
455       
456        orient.transform(this->length, Pt3D(length, 0.0, 0.0));
457       
458        area.setDensity(density);
459}
460
461bool MeshBuilder::CylinderWallSurface::tryGetNext(Pt3D &point)
462{
463        while (!area.tryGetNext(point))
464        {
465                if (edge.tryGetNext(point))
466                {
467                        area.initialize(point + length, point - length);
468                }
469                else
470                {
471                        return false;
472                }
473        }
474       
475        return true;
476}
477
478
479
480MeshBuilder::CylinderSurface::CylinderSurface(const double _density):
481        Iterator(_density), wall(_density), ellipse(_density), iterator(NULL), part(NULL), base(CylinderBases::NUMBER)
482{}
483
484void MeshBuilder::CylinderSurface::initialize(const Part *part)
485{
486        this->part = part;
487        base = CylinderBases::FIRST;
488        wall.setDensity(density);
489        wall.initialize(part);
490        iterator = &wall;
491        ellipse.setDensity(density);
492}
493
494bool MeshBuilder::CylinderSurface::tryGetNext(Pt3D &point)
495{
496        if (iterator == NULL)
497        {
498                return false;
499        }
500       
501        while(!iterator->tryGetNext(point))
502        {
503                if (base < CylinderBases::NUMBER)
504                {
505                        iterator = &ellipse;
506                        ellipse.initialize(part, base);
507                        base = CylinderBases::Base(base+1);
508                }
509                else
510                {
511                        return false;
512                }
513        }
514       
515        return true;
516}
517
518
519
520MeshBuilder::EllipsoidSurface::EllipsoidSurface(const double _density):
521        Iterator(_density), phase(Done), edge(0.0), area(0.0), scale(0.0), limit(0.0), d(0.0), part(NULL), octant(Octants::NUMBER)
522{}
523
524void MeshBuilder::EllipsoidSurface::initialize(const Part *part)
525{
526        this->part = part;
527        d = 1.0 / density;
528        initializePhase(X);
529}
530
531bool MeshBuilder::EllipsoidSurface::tryGetNext(Pt3D &point)
532{
533        if (phase == Done)
534        {
535                return false;
536        }
537       
538        setPoint(point);
539        proceedToNextOctant();
540       
541        if (octant == Octants::NUMBER)
542        {
543                octant = Octants::FIRST;
544                findNextAreaEdgeAndPhase();
545        }
546       
547        return true;
548}
549
550void MeshBuilder::EllipsoidSurface::initializePhase(Phase ph)
551{
552        phase = ph;
553       
554        if (phase != Done)
555        {
556                scale.x = phase == X ? part->scale.x : phase == Y ? part->scale.y : part->scale.z;
557                scale.y = phase == X ? part->scale.y : phase == Y ? part->scale.z : part->scale.x;
558                scale.z = phase == X ? part->scale.z : phase == Y ? part->scale.x : part->scale.y;
559               
560                edge = Pt3D(scale.x, 0.0, scale.z);
561                limit.y = scale.y*scale.y / sqrt(scale.x*scale.x + scale.y*scale.y);
562                limit.z = edge.z*edge.z / sqrt(edge.x*edge.x + edge.z*edge.z);
563                area = Pt3D(edge.x, edge.y, 0.0);
564               
565                octant = Octants::FIRST;
566        }
567}
568
569void MeshBuilder::EllipsoidSurface::setPoint(Pt3D &point)
570{
571        Pt3D temp1(area);
572        temp1.x *= Octants::isPositiveX(octant) ? +1 : -1;
573        temp1.y *= Octants::isPositiveY(octant) ? +1 : -1;
574        temp1.z *= Octants::isPositiveZ(octant) ? +1 : -1;
575       
576        Pt3D temp2;
577        temp2.x = phase == X ? temp1.x : phase == Y ? temp1.z : temp1.y;
578        temp2.y = phase == X ? temp1.y : phase == Y ? temp1.x : temp1.z;
579        temp2.z = phase == X ? temp1.z : phase == Y ? temp1.y : temp1.x;
580       
581        part->o.transform(point, temp2);
582        point += part->p;
583}
584
585void MeshBuilder::EllipsoidSurface::proceedToNextOctant()
586{
587        int step = 1;
588        step += (Octants::isNegativeZ(octant) && (area.z == 0.0)) ? 1 : 0;
589        step += (Octants::isNegativeY(octant) && (area.y == 0.0)) ? 2 : 0;
590        octant = Octants::Octant(octant + step);
591}
592
593void MeshBuilder::EllipsoidSurface::findNextAreaEdgeAndPhase()
594{
595        GeometryUtils::getNextEllipseSegmentationPoint(d, edge.z, edge.x, area.z, area.x);
596               
597        if ((area.z > limit.z) || (area.y > limit.y * sqrt(1.0 - (area.z*area.z) / (scale.z*scale.z))))
598        {
599                GeometryUtils::getNextEllipseSegmentationPoint(d, scale.y, scale.x, edge.y, edge.x);
600                edge.z = scale.z * sqrt(1.0 - (edge.y*edge.y) / (scale.y*scale.y));
601                limit.z = edge.z*edge.z / sqrt(edge.x*edge.x + edge.z*edge.z);
602                area = Pt3D(edge.x, edge.y, 0.0);
603               
604                if (edge.y > limit.y)
605                {
606                        initializePhase(Phase(phase+1));
607                }
608        }
609}
610
611
612
613MeshBuilder::PartSurface::PartSurface(const double _density):
614        Iterator(_density), cuboid(_density), cylinder(_density), ellipsoid(_density), iterator(NULL)
615{}
616
617void MeshBuilder::PartSurface::initialize(const Part *part)
618{
619        switch (part->shape)
620        {
621                case Part::SHAPE_ELLIPSOID:
622                        ellipsoid.setDensity(density);
623                        ellipsoid.initialize(part);
624                        iterator = &ellipsoid;
625                        break;
626                       
627                case Part::SHAPE_CUBOID:
628                        cuboid.setDensity(density);
629                        cuboid.initialize(part);
630                        iterator = &cuboid;
631                        break;
632                       
633                case Part::SHAPE_CYLINDER:
634                        cylinder.setDensity(density);
635                        cylinder.initialize(part);
636                        iterator = &cylinder;
637                        break;
638
639                default:
640                        FMprintf("MeshBuilder::PartSurface", "initialize", FMLV_WARN, "Part shape=%d not supported, skipping...", part->shape);
641        }
642}
643
644bool MeshBuilder::PartSurface::tryGetNext(Pt3D &point)
645{
646        if (iterator == NULL)
647        {
648                return false;
649        }
650
651        return iterator->tryGetNext(point);
652}
653
654
655
656MeshBuilder::ModelSurface::ModelSurface(const double _density):
657        Iterator(_density), surface(_density), model(NULL), index(0)
658{}
659
660void MeshBuilder::ModelSurface::initialize(const Model *model)
661{
662        this->model = model;
663        surface.setDensity(density);
664       
665        index = 0;
666        if (model->getPartCount() > index)
667        {
668                surface.initialize(model->getPart(index));
669        }
670}
671
672bool MeshBuilder::ModelSurface::tryGetNext(Pt3D &point)
673{
674        if (model == NULL)
675        {
676                return false;
677        }
678       
679        do
680        {
681                while (!surface.tryGetNext(point))
682                {
683                        index += 1;
684                        if (model->getPartCount() > index)
685                        {
686                                surface.initialize(model->getPart(index));
687                        }
688                        else
689                        {
690                                return false;
691                        }
692                }
693        } while (GeometryUtils::isPointInsideModelExcludingPart(point, model, index));
694       
695        return true;
696}
697
698
699
700MeshBuilder::PartApices::PartApices(const double _density):
701        Iterator(_density), cuboid(), cylinder(_density), ellipsoid(_density), iterator(NULL)
702{}
703
704void MeshBuilder::PartApices::initialize(const Part *part)
705{
706        switch (part->shape)
707        {
708                case Part::SHAPE_ELLIPSOID:
709                        ellipsoid.setDensity(density);
710                        ellipsoid.initialize(part);
711                        iterator = &ellipsoid;
712                        break;
713                       
714                case Part::SHAPE_CUBOID:
715                        cuboid.initialize(part);
716                        iterator = &cuboid;
717                        break;
718                       
719                case Part::SHAPE_CYLINDER:
720                        cylinder.setDensity(density);
721                        cylinder.initialize(part);
722                        iterator = &cylinder;
723                        break;
724
725                default:
726                        FMprintf("MeshBuilder::PartApices", "initialize", FMLV_WARN, "Part shape=%d not supported, skipping...", part->shape);
727        }
728}
729
730bool MeshBuilder::PartApices::tryGetNext(Pt3D &point)
731{
732        if (iterator == NULL)
733        {
734                return false;
735        }
736
737        return iterator->tryGetNext(point);
738}
739
740
741
742MeshBuilder::ModelApices::ModelApices(const double _density):
743        Iterator(_density), surface(_density), model(NULL), index(0)
744{}
745
746void MeshBuilder::ModelApices::initialize(const Model *model)
747{
748        this->model = model;
749        surface.setDensity(density);
750       
751        index = 0;
752        if (model->getPartCount() > index)
753        {
754                surface.initialize(model->getPart(index));
755        }
756}
757
758bool MeshBuilder::ModelApices::tryGetNext(Pt3D &point)
759{
760        if (model == NULL)
761        {
762                return false;
763        }
764       
765        do
766        {
767                while (!surface.tryGetNext(point))
768                {
769                        index += 1;
770                        if (model->getPartCount() > index)
771                        {
772                                surface.initialize(model->getPart(index));
773                        }
774                        else
775                        {
776                                return false;
777                        }
778                }
779        } while (GeometryUtils::isPointInsideModelExcludingPart(point, model, index));
780       
781        return true;
782}
783
784
785
786MeshBuilder::BoundingBoxVolume::BoundingBoxVolume(const double _density):
787        Iterator(_density), edge(_density), area(_density), volume(_density), length(0.0), width(0.0), height(0.0)
788{}
789
790void MeshBuilder::BoundingBoxVolume::initialize(const Model &model)
791{
792        Pt3D lowerBoundary, upperBoundary;
793        ModelGeometryInfo::boundingBox(model, lowerBoundary, upperBoundary);
794        initialize(lowerBoundary, upperBoundary);
795}
796
797void MeshBuilder::BoundingBoxVolume::initialize(const Pt3D &lowerBoundary, const Pt3D &upperBoundary)
798{
799        length = Pt3D(upperBoundary.x - lowerBoundary.x, 0.0, 0.0);
800        width = Pt3D(0.0, upperBoundary.y - lowerBoundary.y, 0.0);
801        height = Pt3D(0.0, 0.0, upperBoundary.z - lowerBoundary.z);
802
803        edge.setDensity(density);
804        edge.initialize(lowerBoundary, lowerBoundary + length);
805       
806        area.setDensity(density);
807        area.initialize(lowerBoundary, lowerBoundary + width);
808       
809        volume = Segment(density);
810}
811
812bool MeshBuilder::BoundingBoxVolume::tryGetNext(Pt3D &point)
813{
814        while (!volume.tryGetNext(point))
815        {
816                while (!area.tryGetNext(point))
817                {
818                        if (edge.tryGetNext(point))
819                        {
820                                area.initialize(point, point + width);
821                        }
822                        else
823                        {
824                                return false;
825                        }
826                }
827               
828                volume.initialize(point, point + height);
829        }
830       
831        return true;
832}
Note: See TracBrowser for help on using the repository browser.