- Timestamp:
- 03/16/21 23:59:15 (4 years ago)
- Location:
- cpp/frams/model/geometry
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/model/geometry/modelgeoclass.cpp
r999 r1111 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-20 16Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2021 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 11 11 static ParamEntry modelgeo_paramtab[] = 12 12 { 13 { "Creature: Geometry", 1, 5, "ModelGeometry",13 { "Creature: Geometry", 1, 6, "ModelGeometry", 14 14 "Approximately estimates sizes, volume, and area of a Model based on the geometry of its parts.\n" 15 15 "Example usage:\n" … … 22 22 { "volume", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "volume", "p f()", PROCEDURE(p_volume), }, 23 23 { "area", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "area", "p f()", PROCEDURE(p_area), }, 24 { "voxels", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "voxels", "p oVector()", PROCEDURE(p_voxels), }, 24 25 { "sizesAndAxes", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "sizesAndAxes", "p oVector()", PROCEDURE(p_sizesandaxes), "The returned vector contains XYZ (sizes) and Orient (axes) objects." }, 25 26 { 0, 0, 0, }, … … 33 34 34 35 ModelGeometry::ModelGeometry(ModelObj *mo) 35 :par(modelgeo_paramtab, this)36 :par(modelgeo_paramtab, this) 36 37 { 37 38 cached_for_density = -1; //invalid value, will be updated on first request … … 56 57 cached_area = -1; 57 58 cached_sizes.x = -1; 59 cached_voxels.setEmpty(); 58 60 } 59 61 … … 74 76 if (m != NULL) 75 77 { 76 77 78 if (m->getShapeType() == Model::SHAPETYPE_BALL_AND_STICK) 79 { 78 80 Model *converted = new Model; 79 81 converted->open(); 80 82 converted->buildUsingSolidShapeTypes(*m, Part::SHAPE_CYLINDER, 0.2); 81 83 converted->close(); 82 m =converted;83 84 m = converted; 85 } 84 86 ModelGeometry *mg = new ModelGeometry((ModelObj*)m); 85 87 mg->density = density; … … 106 108 } 107 109 110 void ModelGeometry::p_voxels(ExtValue *args, ExtValue *ret) 111 { 112 onDensityChanged(); 113 if (cached_voxels.isEmpty()) //calculate if invalid 114 cached_voxels = ModelGeometryInfo::getVoxels(*model, density); 115 ret->setObject(cached_voxels); 116 } 117 108 118 void ModelGeometry::p_sizesandaxes(ExtValue *args, ExtValue *ret) 109 119 { -
cpp/frams/model/geometry/modelgeoclass.h
r286 r1111 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-20 15Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2021 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 18 18 double cached_volume, cached_area; 19 19 Pt3D cached_sizes; Orient cached_axes; 20 ExtObject cached_voxels; 20 21 21 22 Param par; … … 31 32 PARAMPROCDEF(p_volume); 32 33 PARAMPROCDEF(p_area); 34 PARAMPROCDEF(p_voxels); 33 35 PARAMPROCDEF(p_sizesandaxes); 34 36 #undef STATRICKCLASS -
cpp/frams/model/geometry/modelgeometryinfo.cpp
r660 r1111 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-20 15Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2021 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 6 6 #include <frams/model/geometry/geometryutils.h> 7 7 #include <frams/model/geometry/meshbuilder.h> 8 #include <frams/vm/classes/collectionobj.h> 9 #include <frams/vm/classes/3dobject.h> 8 10 9 11 void ModelGeometryInfo::findSizesAndAxes(Model &input_model, const double density, … … 33 35 return; 34 36 } 35 37 36 38 boundingBox(model.getPart(0), lowerBoundary, upperBoundary); 37 39 38 40 for (int i = 1; i < model.getPartCount(); i++) 39 41 { 40 42 Pt3D partLowerBoundary, partUpperBoundary; 41 43 boundingBox(model.getPart(i), partLowerBoundary, partUpperBoundary); 42 44 43 45 lowerBoundary.getMin(partLowerBoundary); 44 46 upperBoundary.getMax(partUpperBoundary); … … 51 53 lowerBoundary.y = upperBoundary.y = part->p.y; 52 54 lowerBoundary.z = upperBoundary.z = part->p.z; 53 54 for (Octants::Octant o = Octants::FIRST; o < Octants::NUMBER; o = Octants::Octant(o +1))55 56 for (Octants::Octant o = Octants::FIRST; o < Octants::NUMBER; o = Octants::Octant(o + 1)) 55 57 { 56 58 Pt3D vertex = part->scale; … … 58 60 vertex.y *= Octants::isPositiveY(o) ? +1 : -1; 59 61 vertex.z *= Octants::isPositiveZ(o) ? +1 : -1; 60 62 61 63 vertex = part->o.transform(vertex) + part->p; 62 64 63 65 lowerBoundary.getMin(vertex); 64 66 upperBoundary.getMax(vertex); … … 71 73 Pt3D lowerBoundary, upperBoundary; 72 74 boundingBox(model, lowerBoundary, upperBoundary); 73 75 74 76 MeshBuilder::BoundingBoxVolume iterator(density); 75 77 iterator.initialize(lowerBoundary, upperBoundary); 76 78 77 79 Pt3D point; 78 80 int allPoints = 0, pointsInsideModel = 0; 79 81 80 82 while (iterator.tryGetNext(point)) 81 83 { … … 83 85 pointsInsideModel += GeometryUtils::isPointInsideModel(point, model) ? 1 : 0; 84 86 } 85 87 86 88 double boundingBoxVolume 87 89 = (upperBoundary.x - lowerBoundary.x) 88 90 * (upperBoundary.y - lowerBoundary.y) 89 91 * (upperBoundary.z - lowerBoundary.z); 90 92 91 93 return boundingBoxVolume * (double)pointsInsideModel / (double)allPoints; 92 94 } 93 95 96 ExtObject ModelGeometryInfo::getVoxels(Model& input_model, const double density) 97 { 98 SolidsShapeTypeModel model(input_model); 99 Pt3D lowerBoundary, upperBoundary; 100 boundingBox(model, lowerBoundary, upperBoundary); 101 102 MeshBuilder::BoundingBoxVolume iterator(density); 103 iterator.initialize(lowerBoundary, upperBoundary); 104 105 Pt3D point; 106 VectorObject *voxels = new VectorObject; 107 108 while (iterator.tryGetNext(point)) 109 { 110 if (GeometryUtils::isPointInsideModel(point, model)) 111 { 112 voxels->data += new ExtValue(Pt3D_Ext::makeDynamicObject(point)); 113 } 114 } 115 116 return voxels->makeObject(); 117 } 118 94 119 double ModelGeometryInfo::area(Model &input_model, const double density) 95 120 { 96 121 SolidsShapeTypeModel model(input_model); 97 122 double area = 0.0; 98 99 for (int partIndex = 0; partIndex < model.getModel().getPartCount(); partIndex +=1)123 124 for (int partIndex = 0; partIndex < model.getModel().getPartCount(); partIndex += 1) 100 125 { 101 126 area += externalAreaOfPart(model, partIndex, density); 102 127 } 103 128 104 129 return area; 105 130 } … … 110 135 switch (part->shape) 111 136 { 112 113 114 115 116 117 118 119 137 case Part::SHAPE_ELLIPSOID: 138 return externalAreaOfEllipsoid(model, partIndex, density); 139 140 case Part::SHAPE_CUBOID: 141 return externalAreaOfCuboid(model, partIndex, density); 142 143 case Part::SHAPE_CYLINDER: 144 return externalAreaOfCylinder(model, partIndex, density); 120 145 } 121 146 logPrintf("ModelGeometryInfo", "externalAreaOfPart", LOG_ERROR, "Part shape=%d not supported", part->shape); … … 127 152 Pt3D point; 128 153 int all = 0, sur = 0; 129 154 130 155 while (surface.tryGetNext(point)) 131 156 { … … 133 158 sur += GeometryUtils::isPointInsideModelExcludingPart(point, &model, partIndex) ? 0 : 1; 134 159 } 135 160 136 161 return sur * area / all; 137 162 } … … 140 165 { 141 166 Part *part = model.getPart(partIndex); 142 167 143 168 MeshBuilder::EllipsoidSurface ellipsoid(density); 144 169 ellipsoid.initialize(part); 145 170 146 171 double area = GeometryUtils::ellipsoidArea(part->scale); 147 172 148 173 return externalAreaOfSurface(model, partIndex, ellipsoid, area); 149 174 } … … 152 177 { 153 178 Part *part = model.getPart(partIndex); 154 179 155 180 double externalArea = 0.0; 156 181 157 182 MeshBuilder::RectangleSurface rectangle(density); 158 159 for (CuboidFaces::Face f = CuboidFaces::FIRST; f < CuboidFaces::NUMBER; f = CuboidFaces::Face(f +1))183 184 for (CuboidFaces::Face f = CuboidFaces::FIRST; f < CuboidFaces::NUMBER; f = CuboidFaces::Face(f + 1)) 160 185 { 161 186 rectangle.initialize(part, f); 162 187 163 188 double area = 4.0; 164 189 area *= !CuboidFaces::isX(f) ? part->scale.x : 1.0; 165 190 area *= !CuboidFaces::isY(f) ? part->scale.y : 1.0; 166 191 area *= !CuboidFaces::isZ(f) ? part->scale.z : 1.0; 167 192 168 193 externalArea += externalAreaOfSurface(model, partIndex, rectangle, area); 169 194 } 170 195 171 196 return externalArea; 172 197 } … … 175 200 { 176 201 Part *part = model.getPart(partIndex); 177 202 178 203 double externalArea = 0.0; 179 204 180 205 MeshBuilder::EllipseSurface ellipse(density); 181 206 182 207 double area = M_PI * part->scale.y * part->scale.z; 183 184 for (CylinderBases::Base b = CylinderBases::FIRST; b < CylinderBases::NUMBER; b = CylinderBases::Base(b +1))208 209 for (CylinderBases::Base b = CylinderBases::FIRST; b < CylinderBases::NUMBER; b = CylinderBases::Base(b + 1)) 185 210 { 186 211 ellipse.initialize(part, b); 187 212 188 213 externalArea += externalAreaOfSurface(model, partIndex, ellipse, area); 189 214 } 190 215 191 216 MeshBuilder::CylinderWallSurface cylinderWall(density); 192 217 cylinderWall.initialize(part); 193 194 area = 2.0 *part->scale.x * GeometryUtils::ellipsePerimeter(part->scale.y, part->scale.z);195 218 219 area = 2.0 * part->scale.x * GeometryUtils::ellipsePerimeter(part->scale.y, part->scale.z); 220 196 221 externalArea += externalAreaOfSurface(model, partIndex, cylinderWall, area); 197 222 198 223 return externalArea; 199 224 } -
cpp/frams/model/geometry/modelgeometryinfo.h
r660 r1111 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-20 15Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2021 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 27 27 double volume(Model &model, const double density); 28 28 void findSizesAndAxes(Model &model, const double density, Pt3D &sizes, Orient &axes); 29 ExtObject getVoxels(Model &model, const double density); 29 30 30 31 void boundingBox(const Model &model, Pt3D &lowerBoundary, Pt3D &upperBoundary);
Note: See TracChangeset
for help on using the changeset viewer.