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

Last change on this file since 875 was 541, checked in by oriona, 8 years ago

Division by 0.0 for a single ellipsoid fixed [closes #42]. Sampling the same point twice fixed.

  • Property svn:eol-style set to native
File size: 19.3 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
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                if (edge.y > limit.y)
601                {
602                        initializePhase(Phase(phase+1));
603                }
604
605                else
606                {
607                        edge.z = scale.z * sqrt(1.0 - (edge.y * edge.y) / (scale.y * scale.y));
608                        limit.z = edge.z * edge.z / sqrt(edge.x * edge.x + edge.z * edge.z);
609                        area = Pt3D(edge.x, edge.y, 0.0);
610                }
611        }
612}
613
614
615
616MeshBuilder::PartSurface::PartSurface(const double _density):
617        Iterator(_density), cuboid(_density), cylinder(_density), ellipsoid(_density), iterator(NULL)
618{}
619
620void MeshBuilder::PartSurface::initialize(const Part *part)
621{
622        switch (part->shape)
623        {
624                case Part::SHAPE_ELLIPSOID:
625                        ellipsoid.setDensity(density);
626                        ellipsoid.initialize(part);
627                        iterator = &ellipsoid;
628                        break;
629                       
630                case Part::SHAPE_CUBOID:
631                        cuboid.setDensity(density);
632                        cuboid.initialize(part);
633                        iterator = &cuboid;
634                        break;
635                       
636                case Part::SHAPE_CYLINDER:
637                        cylinder.setDensity(density);
638                        cylinder.initialize(part);
639                        iterator = &cylinder;
640                        break;
641
642                default:
643                        logPrintf("MeshBuilder::PartSurface", "initialize", LOG_WARN, "Part shape=%d not supported, skipping...", part->shape);
644        }
645}
646
647bool MeshBuilder::PartSurface::tryGetNext(Pt3D &point)
648{
649        if (iterator == NULL)
650        {
651                return false;
652        }
653
654        return iterator->tryGetNext(point);
655}
656
657
658
659MeshBuilder::ModelSurface::ModelSurface(const double _density):
660        Iterator(_density), surface(_density), model(NULL), index(0)
661{}
662
663void MeshBuilder::ModelSurface::initialize(const Model *model)
664{
665        this->model = model;
666        surface.setDensity(density);
667       
668        index = 0;
669        if (model->getPartCount() > index)
670        {
671                surface.initialize(model->getPart(index));
672        }
673}
674
675bool MeshBuilder::ModelSurface::tryGetNext(Pt3D &point)
676{
677        if (model == NULL)
678        {
679                return false;
680        }
681       
682        do
683        {
684                while (!surface.tryGetNext(point))
685                {
686                        index += 1;
687                        if (model->getPartCount() > index)
688                        {
689                                surface.initialize(model->getPart(index));
690                        }
691                        else
692                        {
693                                return false;
694                        }
695                }
696        } while (GeometryUtils::isPointInsideModelExcludingPart(point, model, index));
697       
698        return true;
699}
700
701
702
703MeshBuilder::PartApices::PartApices(const double _density):
704        Iterator(_density), cuboid(), cylinder(_density), ellipsoid(_density), iterator(NULL)
705{}
706
707void MeshBuilder::PartApices::initialize(const Part *part)
708{
709        switch (part->shape)
710        {
711                case Part::SHAPE_ELLIPSOID:
712                        ellipsoid.setDensity(density);
713                        ellipsoid.initialize(part);
714                        iterator = &ellipsoid;
715                        break;
716                       
717                case Part::SHAPE_CUBOID:
718                        cuboid.initialize(part);
719                        iterator = &cuboid;
720                        break;
721                       
722                case Part::SHAPE_CYLINDER:
723                        cylinder.setDensity(density);
724                        cylinder.initialize(part);
725                        iterator = &cylinder;
726                        break;
727
728                default:
729                        logPrintf("MeshBuilder::PartApices", "initialize", LOG_WARN, "Part shape=%d not supported, skipping...", part->shape);
730        }
731}
732
733bool MeshBuilder::PartApices::tryGetNext(Pt3D &point)
734{
735        if (iterator == NULL)
736        {
737                return false;
738        }
739
740        return iterator->tryGetNext(point);
741}
742
743
744
745MeshBuilder::ModelApices::ModelApices(const double _density):
746        Iterator(_density), surface(_density), model(NULL), index(0)
747{}
748
749void MeshBuilder::ModelApices::initialize(const Model *model)
750{
751        this->model = model;
752        surface.setDensity(density);
753       
754        index = 0;
755        if (model->getPartCount() > index)
756        {
757                surface.initialize(model->getPart(index));
758        }
759}
760
761bool MeshBuilder::ModelApices::tryGetNext(Pt3D &point)
762{
763        if (model == NULL)
764        {
765                return false;
766        }
767       
768        do
769        {
770                while (!surface.tryGetNext(point))
771                {
772                        index += 1;
773                        if (model->getPartCount() > index)
774                        {
775                                surface.initialize(model->getPart(index));
776                        }
777                        else
778                        {
779                                return false;
780                        }
781                }
782        } while (GeometryUtils::isPointInsideModelExcludingPart(point, model, index));
783       
784        return true;
785}
786
787
788
789MeshBuilder::BoundingBoxVolume::BoundingBoxVolume(const double _density):
790        Iterator(_density), edge(_density), area(_density), volume(_density), length(0.0), width(0.0), height(0.0)
791{}
792
793void MeshBuilder::BoundingBoxVolume::initialize(const Model &model)
794{
795        Pt3D lowerBoundary, upperBoundary;
796        ModelGeometryInfo::boundingBox(model, lowerBoundary, upperBoundary);
797        initialize(lowerBoundary, upperBoundary);
798}
799
800void MeshBuilder::BoundingBoxVolume::initialize(const Pt3D &lowerBoundary, const Pt3D &upperBoundary)
801{
802        length = Pt3D(upperBoundary.x - lowerBoundary.x, 0.0, 0.0);
803        width = Pt3D(0.0, upperBoundary.y - lowerBoundary.y, 0.0);
804        height = Pt3D(0.0, 0.0, upperBoundary.z - lowerBoundary.z);
805
806        edge.setDensity(density);
807        edge.initialize(lowerBoundary, lowerBoundary + length);
808       
809        Pt3D dummy_point;
810        edge.tryGetNext(dummy_point); //increment iterator to start from the second point
811
812        area.setDensity(density);
813        area.initialize(lowerBoundary, lowerBoundary + width);
814       
815        volume = Segment(density);
816}
817
818bool MeshBuilder::BoundingBoxVolume::tryGetNext(Pt3D &point)
819{
820        while (!volume.tryGetNext(point))
821        {
822                while (!area.tryGetNext(point))
823                {
824                        if (edge.tryGetNext(point))
825                        {
826                                area.initialize(point, point + width);
827                        }
828                        else
829                        {
830                                return false;
831                        }
832                }
833               
834                volume.initialize(point, point + height);
835        }
836       
837        return true;
838}
Note: See TracBrowser for help on using the repository browser.