source: cpp/frams/model/geometry/modelgeoclass.cpp @ 659

Last change on this file since 659 was 658, checked in by Maciej Komosinski, 8 years ago
  • One function name made shorter
  • Fixed some typos
  • Predictable behavior for empty (zero-Part) Models (that should never happen)
  • Property svn:eol-style set to native
File size: 4.0 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2016  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "modelgeoclass.h"
6#include "modelgeometryinfo.h"
7#include <frams/vm/classes/collectionobj.h>
8#include <frams/vm/classes/3dobject.h>
9
10#define FIELDSTRUCT ModelGeometry
11static ParamEntry modelgeo_paramtab[] =
12{
13        { "Creature: Geometry", 1, 5, "ModelGeometry",
14        "Approximately estimates sizes, volume, and area of a Model based on the geometry of its parts.\n"
15        "Example usage:\n"
16        "Simulator.print(ModelGeometry.forModel(Model.newFromString(\"//0\\np:sh=1\\n\")).area());\n\n"
17        "ModelGeometry.geom_density refers to the global simulator parameter (also available in GUI).\n"
18        "To set geom_density for individual ModelGeometry objects:\n"
19        "var mg=ModelGeometry.forModel(GenePools[0][0].getModel()); mg.geom_density=2; GenePools[0][0].data->area=mg.area();\n" },
20        { "geom_density", 0, 0, "Density", "f 0.01 100.0 1.0", FIELD(density), "Affects the geometry calculation precision" }, //note: we used 'geom_density' instead of 'density' to make the name more unique - because sim_params merges all configuration fields in a single namespace.
21        { "forModel", 0, PARAM_USERHIDDEN, "", "p oModelGeometry(oModel)", PROCEDURE(p_formodel), "The returned ModelGeometry object can be used to calculate geometric properties (volume, area, sizes) of the associated model. The density is copied from the current global ModelGeometry.geom_density on object creation." },
22        { "volume", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "volume", "p f()", PROCEDURE(p_volume), },
23        { "area", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "area", "p f()", PROCEDURE(p_area), },
24        { "sizesAndAxes", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "sizesAndAxes", "p oVector()", PROCEDURE(p_sizesandaxes), "The returned vector contains XYZ (sizes) and Orient (axes) objects." },
25        { 0, 0, 0, },
26};
27#undef FIELDSTRUCT
28
29ExtObject ModelGeometry::makeDynamicObject(ModelGeometry* mg)
30{
31        return ExtObject(&mg->par, mg);
32}
33
34ModelGeometry::ModelGeometry(ModelObj *mo)
35:par(modelgeo_paramtab, this)
36{
37        cached_for_density = -1; //invalid value, will be updated on first request
38        invalidateAllCached();
39        model = mo;
40        if (model != NULL)
41                model->incref();
42}
43
44ModelGeometry::~ModelGeometry()
45{
46        if (model != NULL)
47                model->decref();
48}
49
50// Mark all 3 results as invalid.
51// Validity of these 3 values must be maintained independently,
52// as each of them is calculated by an individual call.
53void ModelGeometry::invalidateAllCached()
54{
55        cached_volume = -1;
56        cached_area = -1;
57        cached_sizes.x = -1;
58}
59
60// Invalidates cached results if a new density is requested
61// (called in all geometry calculation functions)
62void ModelGeometry::onDensityChanged()
63{
64        if (cached_for_density != density)
65        {
66                invalidateAllCached();
67                cached_for_density = density;
68        }
69}
70
71void ModelGeometry::p_formodel(ExtValue *args, ExtValue *ret)
72{
73        Model *m = ModelObj::fromObject(*args);
74        if (m != NULL)
75        {
76                ModelGeometry *mg = new ModelGeometry((ModelObj*)m);
77                mg->density = density;
78                ret->setObject(ModelGeometry::makeDynamicObject(mg));
79        }
80        else
81                ret->setEmpty();
82}
83
84void ModelGeometry::p_volume(ExtValue *args, ExtValue *ret)
85{
86        onDensityChanged();
87        if (cached_volume < 0) //calculate if invalid
88                cached_volume = ModelGeometryInfo::volume(*model, density);
89        ret->setDouble(cached_volume);
90}
91
92void ModelGeometry::p_area(ExtValue *args, ExtValue *ret)
93{
94        onDensityChanged();
95        if (cached_area < 0) //calculate if invalid
96                cached_area = ModelGeometryInfo::area(*model, density);
97        ret->setDouble(cached_area);
98}
99
100void ModelGeometry::p_sizesandaxes(ExtValue *args, ExtValue *ret)
101{
102        onDensityChanged();
103        if (cached_sizes.x < 0) //calculate if invalid
104                ModelGeometryInfo::findSizesAndAxes(*model, density, cached_sizes, cached_axes);
105
106        VectorObject* n = new VectorObject;
107        n->data += new ExtValue(Pt3D_Ext::makeDynamicObject(cached_sizes));
108        n->data += new ExtValue(Orient_Ext::makeDynamicObject(new Orient_Ext(cached_axes)));
109        ret->setObject(n->makeObject());
110}
Note: See TracBrowser for help on using the repository browser.