Ignore:
Timestamp:
03/16/21 23:59:15 (4 years ago)
Author:
Maciej Komosinski
Message:

Added a function to get voxels of sampled Model geometry from script

Location:
cpp/frams/model/geometry
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/model/geometry/modelgeoclass.cpp

    r999 r1111  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2016  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2021  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1111static ParamEntry modelgeo_paramtab[] =
    1212{
    13         { "Creature: Geometry", 1, 5, "ModelGeometry",
     13        { "Creature: Geometry", 1, 6, "ModelGeometry",
    1414        "Approximately estimates sizes, volume, and area of a Model based on the geometry of its parts.\n"
    1515        "Example usage:\n"
     
    2222        { "volume", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "volume", "p f()", PROCEDURE(p_volume), },
    2323        { "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), },
    2425        { "sizesAndAxes", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "sizesAndAxes", "p oVector()", PROCEDURE(p_sizesandaxes), "The returned vector contains XYZ (sizes) and Orient (axes) objects." },
    2526        { 0, 0, 0, },
     
    3334
    3435ModelGeometry::ModelGeometry(ModelObj *mo)
    35 :par(modelgeo_paramtab, this)
     36        :par(modelgeo_paramtab, this)
    3637{
    3738        cached_for_density = -1; //invalid value, will be updated on first request
     
    5657        cached_area = -1;
    5758        cached_sizes.x = -1;
     59        cached_voxels.setEmpty();
    5860}
    5961
     
    7476        if (m != NULL)
    7577        {
    76                 if (m->getShapeType() == Model::SHAPETYPE_BALL_AND_STICK)
    77                         {
     78                if (m->getShapeType() == Model::SHAPETYPE_BALL_AND_STICK)
     79                {
    7880                        Model *converted = new Model;
    7981                        converted->open();
    8082                        converted->buildUsingSolidShapeTypes(*m, Part::SHAPE_CYLINDER, 0.2);
    8183                        converted->close();
    82                         m=converted;
    83                         }
     84                        m = converted;
     85                }
    8486                ModelGeometry *mg = new ModelGeometry((ModelObj*)m);
    8587                mg->density = density;
     
    106108}
    107109
     110void 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
    108118void ModelGeometry::p_sizesandaxes(ExtValue *args, ExtValue *ret)
    109119{
  • cpp/frams/model/geometry/modelgeoclass.h

    r286 r1111  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2021  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1818        double cached_volume, cached_area;
    1919        Pt3D cached_sizes; Orient cached_axes;
     20        ExtObject cached_voxels;
    2021
    2122        Param par;
     
    3132        PARAMPROCDEF(p_volume);
    3233        PARAMPROCDEF(p_area);
     34        PARAMPROCDEF(p_voxels);
    3335        PARAMPROCDEF(p_sizesandaxes);
    3436#undef STATRICKCLASS
  • cpp/frams/model/geometry/modelgeometryinfo.cpp

    r660 r1111  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2021  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    66#include <frams/model/geometry/geometryutils.h>
    77#include <frams/model/geometry/meshbuilder.h>
     8#include <frams/vm/classes/collectionobj.h>
     9#include <frams/vm/classes/3dobject.h>
    810
    911void ModelGeometryInfo::findSizesAndAxes(Model &input_model, const double density,
     
    3335                return;
    3436        }
    35        
     37
    3638        boundingBox(model.getPart(0), lowerBoundary, upperBoundary);
    37        
     39
    3840        for (int i = 1; i < model.getPartCount(); i++)
    3941        {
    4042                Pt3D partLowerBoundary, partUpperBoundary;
    4143                boundingBox(model.getPart(i), partLowerBoundary, partUpperBoundary);
    42                
     44
    4345                lowerBoundary.getMin(partLowerBoundary);
    4446                upperBoundary.getMax(partUpperBoundary);
     
    5153        lowerBoundary.y = upperBoundary.y = part->p.y;
    5254        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))
    5557        {
    5658                Pt3D vertex = part->scale;
     
    5860                vertex.y *= Octants::isPositiveY(o) ? +1 : -1;
    5961                vertex.z *= Octants::isPositiveZ(o) ? +1 : -1;
    60                
     62
    6163                vertex = part->o.transform(vertex) + part->p;
    62                
     64
    6365                lowerBoundary.getMin(vertex);
    6466                upperBoundary.getMax(vertex);
     
    7173        Pt3D lowerBoundary, upperBoundary;
    7274        boundingBox(model, lowerBoundary, upperBoundary);
    73        
     75
    7476        MeshBuilder::BoundingBoxVolume iterator(density);
    7577        iterator.initialize(lowerBoundary, upperBoundary);
    76        
     78
    7779        Pt3D point;
    7880        int allPoints = 0, pointsInsideModel = 0;
    79        
     81
    8082        while (iterator.tryGetNext(point))
    8183        {
     
    8385                pointsInsideModel += GeometryUtils::isPointInsideModel(point, model) ? 1 : 0;
    8486        }
    85        
     87
    8688        double boundingBoxVolume
    8789                = (upperBoundary.x - lowerBoundary.x)
    8890                * (upperBoundary.y - lowerBoundary.y)
    8991                * (upperBoundary.z - lowerBoundary.z);
    90        
     92
    9193        return boundingBoxVolume * (double)pointsInsideModel / (double)allPoints;
    9294}
    9395
     96ExtObject 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
    94119double ModelGeometryInfo::area(Model &input_model, const double density)
    95120{
    96121        SolidsShapeTypeModel model(input_model);
    97122        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)
    100125        {
    101126                area += externalAreaOfPart(model, partIndex, density);
    102127        }
    103        
     128
    104129        return area;
    105130}
     
    110135        switch (part->shape)
    111136        {
    112                 case Part::SHAPE_ELLIPSOID:
    113                         return externalAreaOfEllipsoid(model, partIndex, density);
    114                        
    115                 case Part::SHAPE_CUBOID:
    116                         return externalAreaOfCuboid(model, partIndex, density);
    117                        
    118                 case Part::SHAPE_CYLINDER:
    119                         return externalAreaOfCylinder(model, partIndex, density);
     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);
    120145        }
    121146        logPrintf("ModelGeometryInfo", "externalAreaOfPart", LOG_ERROR, "Part shape=%d not supported", part->shape);
     
    127152        Pt3D point;
    128153        int all = 0, sur = 0;
    129        
     154
    130155        while (surface.tryGetNext(point))
    131156        {
     
    133158                sur += GeometryUtils::isPointInsideModelExcludingPart(point, &model, partIndex) ? 0 : 1;
    134159        }
    135        
     160
    136161        return sur * area / all;
    137162}
     
    140165{
    141166        Part *part = model.getPart(partIndex);
    142        
     167
    143168        MeshBuilder::EllipsoidSurface ellipsoid(density);
    144169        ellipsoid.initialize(part);
    145        
     170
    146171        double area = GeometryUtils::ellipsoidArea(part->scale);
    147        
     172
    148173        return externalAreaOfSurface(model, partIndex, ellipsoid, area);
    149174}
     
    152177{
    153178        Part *part = model.getPart(partIndex);
    154        
     179
    155180        double externalArea = 0.0;
    156        
     181
    157182        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))
    160185        {
    161186                rectangle.initialize(part, f);
    162                
     187
    163188                double area = 4.0;
    164189                area *= !CuboidFaces::isX(f) ? part->scale.x : 1.0;
    165190                area *= !CuboidFaces::isY(f) ? part->scale.y : 1.0;
    166191                area *= !CuboidFaces::isZ(f) ? part->scale.z : 1.0;
    167                
     192
    168193                externalArea += externalAreaOfSurface(model, partIndex, rectangle, area);
    169194        }
    170        
     195
    171196        return externalArea;
    172197}
     
    175200{
    176201        Part *part = model.getPart(partIndex);
    177        
     202
    178203        double externalArea = 0.0;
    179        
     204
    180205        MeshBuilder::EllipseSurface ellipse(density);
    181        
     206
    182207        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))
    185210        {
    186211                ellipse.initialize(part, b);
    187                
     212
    188213                externalArea += externalAreaOfSurface(model, partIndex, ellipse, area);
    189214        }
    190        
     215
    191216        MeshBuilder::CylinderWallSurface cylinderWall(density);
    192217        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
    196221        externalArea += externalAreaOfSurface(model, partIndex, cylinderWall, area);
    197        
     222
    198223        return externalArea;
    199224}
  • cpp/frams/model/geometry/modelgeometryinfo.h

    r660 r1111  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2021  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    2727        double volume(Model &model, const double density);
    2828        void findSizesAndAxes(Model &model, const double density, Pt3D &sizes, Orient &axes);
     29        ExtObject getVoxels(Model &model, const double density);
    2930
    3031        void boundingBox(const Model &model, Pt3D &lowerBoundary, Pt3D &upperBoundary);
Note: See TracChangeset for help on using the changeset viewer.