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

Last change on this file since 372 was 372, checked in by sz, 9 years ago

Renamed some classes and functions to make their purpose more obvious:

All MessageHandlers? must now be given the explicit "Enable" argument if you want them to automatically become active. This makes side effects clearly visible.

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