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

Last change on this file since 239 was 239, checked in by rgolebiewski, 10 years ago

Changed type of value returned by some functions (two initializers and one setter) to void.

  • Property svn:eol-style set to native
File size: 18.9 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}
640
641bool MeshBuilder::PartSurface::tryGetNext(Pt3D &point)
642{
643        if (iterator == NULL)
644        {
645                return false;
646        }
647
648        return iterator->tryGetNext(point);
649}
650
651
652
653MeshBuilder::ModelSurface::ModelSurface(const double _density):
654        Iterator(_density), surface(_density), model(NULL), index(0)
655{}
656
657void MeshBuilder::ModelSurface::initialize(const Model *model)
658{
659        this->model = model;
660        surface.setDensity(density);
661       
662        index = 0;
663        if (model->getPartCount() > index)
664        {
665                surface.initialize(model->getPart(index));
666        }
667}
668
669bool MeshBuilder::ModelSurface::tryGetNext(Pt3D &point)
670{
671        if (model == NULL)
672        {
673                return false;
674        }
675       
676        do
677        {
678                while (!surface.tryGetNext(point))
679                {
680                        index += 1;
681                        if (model->getPartCount() > index)
682                        {
683                                surface.initialize(model->getPart(index));
684                        }
685                        else
686                        {
687                                return false;
688                        }
689                }
690        } while (GeometryUtils::isPointInsideModelExcludingPart(point, model, index));
691       
692        return true;
693}
694
695
696
697MeshBuilder::PartApices::PartApices(const double _density):
698        Iterator(_density), cuboid(), cylinder(_density), ellipsoid(_density), iterator(NULL)
699{}
700
701void MeshBuilder::PartApices::initialize(const Part *part)
702{
703        switch (part->shape)
704        {
705                case Part::SHAPE_ELLIPSOID:
706                        ellipsoid.setDensity(density);
707                        ellipsoid.initialize(part);
708                        iterator = &ellipsoid;
709                        break;
710                       
711                case Part::SHAPE_CUBOID:
712                        cuboid.initialize(part);
713                        iterator = &cuboid;
714                        break;
715                       
716                case Part::SHAPE_CYLINDER:
717                        cylinder.setDensity(density);
718                        cylinder.initialize(part);
719                        iterator = &cylinder;
720                        break;
721        }
722}
723
724bool MeshBuilder::PartApices::tryGetNext(Pt3D &point)
725{
726        if (iterator == NULL)
727        {
728                return false;
729        }
730
731        return iterator->tryGetNext(point);
732}
733
734
735
736MeshBuilder::ModelApices::ModelApices(const double _density):
737        Iterator(_density), surface(_density), model(NULL), index(0)
738{}
739
740void MeshBuilder::ModelApices::initialize(const Model *model)
741{
742        this->model = model;
743        surface.setDensity(density);
744       
745        index = 0;
746        if (model->getPartCount() > index)
747        {
748                surface.initialize(model->getPart(index));
749        }
750}
751
752bool MeshBuilder::ModelApices::tryGetNext(Pt3D &point)
753{
754        if (model == NULL)
755        {
756                return false;
757        }
758       
759        do
760        {
761                while (!surface.tryGetNext(point))
762                {
763                        index += 1;
764                        if (model->getPartCount() > index)
765                        {
766                                surface.initialize(model->getPart(index));
767                        }
768                        else
769                        {
770                                return false;
771                        }
772                }
773        } while (GeometryUtils::isPointInsideModelExcludingPart(point, model, index));
774       
775        return true;
776}
777
778
779
780MeshBuilder::BoundingBoxVolume::BoundingBoxVolume(const double _density):
781        Iterator(_density), edge(_density), area(_density), volume(_density), length(0.0), width(0.0), height(0.0)
782{}
783
784void MeshBuilder::BoundingBoxVolume::initialize(const Model &model)
785{
786        Pt3D lowerBoundary, upperBoundary;
787        ModelGeometryInfo::boundingBox(model, lowerBoundary, upperBoundary);
788        initialize(lowerBoundary, upperBoundary);
789}
790
791void MeshBuilder::BoundingBoxVolume::initialize(const Pt3D &lowerBoundary, const Pt3D &upperBoundary)
792{
793        length = Pt3D(upperBoundary.x - lowerBoundary.x, 0.0, 0.0);
794        width = Pt3D(0.0, upperBoundary.y - lowerBoundary.y, 0.0);
795        height = Pt3D(0.0, 0.0, upperBoundary.z - lowerBoundary.z);
796
797        edge.setDensity(density);
798        edge.initialize(lowerBoundary, lowerBoundary + length);
799       
800        area.setDensity(density);
801        area.initialize(lowerBoundary, lowerBoundary + width);
802       
803        volume = Segment(density);
804}
805
806bool MeshBuilder::BoundingBoxVolume::tryGetNext(Pt3D &point)
807{
808        while (!volume.tryGetNext(point))
809        {
810                while (!area.tryGetNext(point))
811                {
812                        if (edge.tryGetNext(point))
813                        {
814                                area.initialize(point, point + width);
815                        }
816                        else
817                        {
818                                return false;
819                        }
820                }
821               
822                volume.initialize(point, point + height);
823        }
824       
825        return true;
826}
Note: See TracBrowser for help on using the repository browser.