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

Last change on this file since 271 was 271, checked in by Maciej Komosinski, 10 years ago

Refreshed header comments

  • Property svn:eol-style set to native
File size: 3.9 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 1999-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
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        "Example usage:\n"
15        "Simulator.print(ModelGeometry.forModel(Model.newFromString(\"//0\\np:sh=1\\n\")).area());\n\n"
16        "ModelGeometry.geom_density refers to the global simulator parameter (also available in GUI).\n"
17        "To set geom_density for individual ModelGeometry objects:\n"
18        "var mg=ModelGeometry.forModel(GenePools[0][0].getModel()); mg.geom_density=2; GenePools[0][0].user1=mg.area();\n" },
19        { "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.
20        { "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." },
21        { "volume", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "volume", "p f()", PROCEDURE(p_volume), },
22        { "area", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "area", "p f()", PROCEDURE(p_area), },
23        { "sizesAndAxes", 0, PARAM_NOSTATIC | PARAM_USERHIDDEN, "sizesAndAxes", "p oVector()", PROCEDURE(p_sizesandaxes), "The returned vector contains XYZ (sizes) and Orient (axes) objects." },
24        { 0, 0, 0, },
25};
26#undef FIELDSTRUCT
27
28ExtObject ModelGeometry::makeDynamicObject(ModelGeometry* mg)
29{
30        return ExtObject(&mg->par, mg);
31}
32
33ModelGeometry::ModelGeometry(ModelObj *mo)
34:par(modelgeo_paramtab, this)
35{
36        cached_for_density = -1; //invalid value, will be updated on first request
37        invalidateAllCached();
38        model = mo;
39        if (model != NULL)
40                model->incref();
41}
42
43ModelGeometry::~ModelGeometry()
44{
45        if (model != NULL)
46                model->decref();
47}
48
49// Mark all 3 results as invalid.
50// Validity of these 3 values must be maintained independently,
51// as each of them is calculated by an individual call.
52void ModelGeometry::invalidateAllCached()
53{
54        cached_volume = -1;
55        cached_area = -1;
56        cached_sizes.x = -1;
57}
58
59// Invalidates cached results if a new density is requested
60// (called in all geometry calculation functions)
61void ModelGeometry::onDensityChanged()
62{
63        if (cached_for_density != density)
64        {
65                invalidateAllCached();
66                cached_for_density = density;
67        }
68}
69
70void ModelGeometry::p_formodel(ExtValue *args, ExtValue *ret)
71{
72        Model *m = ModelObj::fromObject(*args);
73        if (m != NULL)
74        {
75                ModelGeometry *mg = new ModelGeometry((ModelObj*)m);
76                mg->density = density;
77                ret->setObject(ModelGeometry::makeDynamicObject(mg));
78        }
79        else
80                ret->setEmpty();
81}
82
83void ModelGeometry::p_volume(ExtValue *args, ExtValue *ret)
84{
85        onDensityChanged();
86        if (cached_volume < 0) //calculate if invalid
87                cached_volume = ModelGeometryInfo::volume(*model, density);
88        ret->setDouble(cached_volume);
89}
90
91void ModelGeometry::p_area(ExtValue *args, ExtValue *ret)
92{
93        onDensityChanged();
94        if (cached_area < 0) //calculate if invalid
95                cached_area = ModelGeometryInfo::area(*model, density);
96        ret->setDouble(cached_area);
97}
98
99void ModelGeometry::p_sizesandaxes(ExtValue *args, ExtValue *ret)
100{
101        onDensityChanged();
102        if (cached_sizes.x < 0) //calculate if invalid
103                ModelGeometryInfo::findSizesAndAxesOfModel(*model, density, cached_sizes, cached_axes);
104
105        VectorObject* n = new VectorObject;
106        n->data += new ExtValue(Pt3D_Ext::makeDynamicObject(cached_sizes));
107        n->data += new ExtValue(Orient_Ext::makeDynamicObject(new Orient_Ext(cached_axes)));
108        ret->setObject(n->makeObject());
109}
Note: See TracBrowser for help on using the repository browser.