source: cpp/frams/model/geometry/modelgeometryinfo.cpp @ 234

Last change on this file since 234 was 234, checked in by sz, 11 years ago

Trivial changes to avoid compilation warnings about missing return values (might be incorrect)

  • Property svn:eol-style set to native
File size: 5.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 "modelgeometryinfo.h"
6#include <frams/model/geometry/geometryutils.h>
7#include <frams/model/geometry/meshbuilder.h>
8
9void ModelGeometryInfo::findSizesAndAxesOfModel(const Model &model, const double density,
10        Pt3D &sizes, Orient &axes)
11{
12        SListTempl<Pt3D> points;
13        MeshBuilder::ModelApices apices(density);
14        apices.initialize(&model);
15        apices.addAllPointsToList(points);
16        GeometryUtils::findSizesAndAxesOfPointsGroup(points, sizes, axes);
17}
18
19bool ModelGeometryInfo::boundingBox(const Model &model, Pt3D &lowerBoundary, Pt3D &upperBoundary)
20{
21        if (model.getPartCount() == 0)
22        {
23                return false;
24        }
25       
26        boundingBox(model.getPart(0), lowerBoundary, upperBoundary);
27       
28        for (int i = 1; i < model.getPartCount(); i++)
29        {
30                Pt3D partLowerBoundary, partUpperBoundary;
31                boundingBox(model.getPart(i), partLowerBoundary, partUpperBoundary);
32               
33                lowerBoundary.getMin(partLowerBoundary);
34                upperBoundary.getMax(partUpperBoundary);
35        }
36       
37        return true;
38}
39
40void ModelGeometryInfo::boundingBox(const Part *part, Pt3D &lowerBoundary, Pt3D &upperBoundary)
41{
42        lowerBoundary.x = upperBoundary.x = part->p.x;
43        lowerBoundary.y = upperBoundary.y = part->p.y;
44        lowerBoundary.z = upperBoundary.z = part->p.z;
45       
46        for (Octants::Octant o = Octants::FIRST; o < Octants::NUMBER; o = Octants::Octant(o+1))
47        {
48                Pt3D vertex = part->scale;
49                vertex.x *= Octants::isPositiveX(o) ? +1 : -1;
50                vertex.y *= Octants::isPositiveY(o) ? +1 : -1;
51                vertex.z *= Octants::isPositiveZ(o) ? +1 : -1;
52               
53                vertex = part->o.transform(vertex) + part->p;
54               
55                lowerBoundary.getMin(vertex);
56                upperBoundary.getMax(vertex);
57        }
58}
59
60double ModelGeometryInfo::volume(const Model &model, const double density)
61{
62        Pt3D lowerBoundary, upperBoundary;
63        boundingBox(model, lowerBoundary, upperBoundary);
64       
65        MeshBuilder::BoundingBoxVolume iterator(density);
66        iterator.initialize(lowerBoundary, upperBoundary);
67       
68        Pt3D point;
69        int allPoints = 0, pointsInsideModel = 0;
70       
71        while (iterator.tryGetNext(point))
72        {
73                allPoints += 1;
74                pointsInsideModel += GeometryUtils::isPointInsideModel(point, model) ? 1 : 0;
75        }
76       
77        double boundingBoxVolume
78                = (upperBoundary.x - lowerBoundary.x)
79                * (upperBoundary.y - lowerBoundary.y)
80                * (upperBoundary.z - lowerBoundary.z);
81       
82        return boundingBoxVolume * (double)pointsInsideModel / (double)allPoints;
83}
84
85double ModelGeometryInfo::area(const Model &model, const double density)
86{
87        double area = 0.0;
88       
89        for (int partIndex = 0; partIndex < model.getPartCount(); partIndex+=1)
90        {
91                area += externalAreaOfPart(model, partIndex, density);
92        }
93       
94        return area;
95}
96
97double ModelGeometryInfo::externalAreaOfPart(const Model &model, const int partIndex, const double density)
98{
99        switch (model.getPart(partIndex)->shape)
100        {
101                case Part::SHAPE_ELLIPSOID:
102                        return externalAreaOfEllipsoid(model, partIndex, density);
103                       
104                case Part::SHAPE_CUBOID:
105                        return externalAreaOfCuboid(model, partIndex, density);
106                       
107                case Part::SHAPE_CYLINDER:
108                        return externalAreaOfCylinder(model, partIndex, density);
109        }
110        return 0;
111}
112
113double externalAreaOfSurface(const Model &model, const int partIndex, MeshBuilder::Iterator &surface, const double area)
114{
115        Pt3D point;
116        int all = 0, sur = 0;
117       
118        while (surface.tryGetNext(point))
119        {
120                all += 1;
121                sur += GeometryUtils::isPointInsideModelExcludingPart(point, &model, partIndex) ? 0 : 1;
122        }
123       
124        return sur * area / all;
125}
126
127double ModelGeometryInfo::externalAreaOfEllipsoid(const Model &model, const int partIndex, const double density)
128{
129        Part *part = model.getPart(partIndex);
130       
131        MeshBuilder::EllipsoidSurface ellipsoid(density);
132        ellipsoid.initialize(part);
133       
134        double area = GeometryUtils::ellipsoidArea(part->scale);
135       
136        return externalAreaOfSurface(model, partIndex, ellipsoid, area);
137}
138
139double ModelGeometryInfo::externalAreaOfCuboid(const Model &model, const int partIndex, const double density)
140{
141        Part *part = model.getPart(partIndex);
142       
143        double externalArea = 0.0;
144       
145        MeshBuilder::RectangleSurface rectangle(density);
146       
147        for (CuboidFaces::Face f = CuboidFaces::FIRST; f < CuboidFaces::NUMBER; f = CuboidFaces::Face(f+1))
148        {
149                rectangle.initialize(part, f);
150               
151                double area = 4.0;
152                area *= !CuboidFaces::isX(f) ? part->scale.x : 1.0;
153                area *= !CuboidFaces::isY(f) ? part->scale.y : 1.0;
154                area *= !CuboidFaces::isZ(f) ? part->scale.z : 1.0;
155               
156                externalArea += externalAreaOfSurface(model, partIndex, rectangle, area);
157        }
158       
159        return externalArea;
160}
161
162double ModelGeometryInfo::externalAreaOfCylinder(const Model &model, const int partIndex, const double density)
163{
164        Part *part = model.getPart(partIndex);
165       
166        double externalArea = 0.0;
167       
168        MeshBuilder::EllipseSurface ellipse(density);
169       
170        double area = M_PI * part->scale.y * part->scale.z;
171       
172        for (CylinderBases::Base b = CylinderBases::FIRST; b < CylinderBases::NUMBER; b = CylinderBases::Base(b+1))
173        {
174                ellipse.initialize(part, b);
175               
176                externalArea += externalAreaOfSurface(model, partIndex, ellipse, area);
177        }
178       
179        MeshBuilder::CylinderWallSurface cylinderWall(density);
180        cylinderWall.initialize(part);
181       
182        area = 2.0*part->scale.x * GeometryUtils::ellipsePerimeter(part->scale.y, part->scale.z);
183       
184        externalArea += externalAreaOfSurface(model, partIndex, cylinderWall, area);
185       
186        return externalArea;
187}
Note: See TracBrowser for help on using the repository browser.