Index: /cpp/frams/model/modelobj.cpp
===================================================================
--- /cpp/frams/model/modelobj.cpp	(revision 722)
+++ /cpp/frams/model/modelobj.cpp	(revision 722)
@@ -0,0 +1,132 @@
+#include "modelobj.h"
+#include <frams/vm/classes/genoobj.h>
+#include <frams/util/extvalue.h>
+#include <frams/vm/classes/3dobject.h>
+
+#define FIELDSTRUCT ModelObj
+ParamEntry modelobj_paramtab[] =
+{
+	{ "Model", 1, 16, "Model", },
+	{ "se", 0, PARAM_NOSTATIC, "startenergy", "f", FIELD(startenergy), },
+	{ "Vstyle", 0, PARAM_NOSTATIC, "vis_style", "s", FIELD(vis_style), },
+
+	{ "geno", 0, PARAM_NOSTATIC | PARAM_READONLY, "geno", "o Geno", GETONLY(geno), },
+	{ "newFromString", 0, 0, "create new object", "p oModel(s genotype)", PROCEDURE(p_newfromstring), },
+	{ "newFromGeno", 0, 0, "create new object", "p oModel(oGeno)", PROCEDURE(p_newfromgeno), },
+
+	{ "numparts", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "number of parts", "d", GETONLY(numparts), },
+	{ "numjoints", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "number of joints", "d", GETONLY(numjoints), },
+	{ "numneurons", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "number of neurons", "d", GETONLY(numneurons), },
+	{ "numconnections", 0, PARAM_DONTSAVE | PARAM_NOSTATIC | PARAM_READONLY, "number of neuron connections", "d", GETONLY(numconnections), },
+
+	{ "getPart", 0, PARAM_USERHIDDEN | PARAM_NOSTATIC, "getPart (static model information)", "p oPart(d index)", PROCEDURE(p_getpart), },
+	{ "getJoint", 0, PARAM_USERHIDDEN | PARAM_NOSTATIC, "getJoint (static model information)", "p oJoint(d index)", PROCEDURE(p_getjoint), },
+	{ "getNeuroDef", 0, PARAM_USERHIDDEN | PARAM_NOSTATIC, "getNeuroDef", "p oNeuroDef(d index)", PROCEDURE(p_getneuro), },
+
+	{ "size_x", 0, PARAM_READONLY | PARAM_NOSTATIC | PARAM_DEPRECATED, "bounding box x size", "f", FIELD(size.x), "(size_x,size_y,size_z) are dimensions of the axis-aligned bounding box of the creature, including imaginary Part sizes (Part.s, usually 1.0). A creature consisting of a single default part has the size of (2.0,2.0,2.0) - twice the Part.s value (like a sphere diameter is twice its radius).\nSee also: Creature.moveAbs" },
+	{ "size_y", 0, PARAM_READONLY | PARAM_NOSTATIC | PARAM_DEPRECATED, "bounding box y size", "f", FIELD(size.y), "See Model.size_x" },
+	{ "size_z", 0, PARAM_READONLY | PARAM_NOSTATIC | PARAM_DEPRECATED, "bounding box z size", "f", FIELD(size.z), "See Model.size_x" },
+	{ "bboxSize", 0, PARAM_READONLY | PARAM_NOSTATIC, "Bounding box size", "oXYZ", GETONLY(bboxsize) },
+
+	{ 0, 0, 0, },
+};
+#undef FIELDSTRUCT
+
+void ModelObj::get_geno(ExtValue *ret)
+{
+	Geno *g;
+	if ((!geno.isValid()) && isValid())
+		g = new Geno(getF0Geno());
+	else
+		g = new Geno(geno);
+	ret->setObject(GenoObj::makeDynamicObjectAndDecRef(g));
+}
+
+void ModelObj::p_newfromstring(ExtValue *args, ExtValue *ret)
+{
+	*ret = makeDynamicObject(new Model(Geno(args[0].getString())));
+}
+
+void ModelObj::p_newfromgeno(ExtValue *args, ExtValue *ret)
+{
+	Geno *g = GenoObj::fromObject(args[0].getObject());
+	if (g)
+		*ret = makeDynamicObject(new Model(*g));
+	else
+		ret->setEmpty();
+}
+
+Param& ModelObj::getStaticParam()
+{
+#ifdef __CODEGUARD__
+	static ModelObj static_modelobj;
+	static Param static_modelparam(modelobj_paramtab,&static_modelobj);
+#else
+	static Param static_modelparam(modelobj_paramtab);
+#endif
+	return static_modelparam;
+}
+
+Param& ModelObj::getDynamicParam()
+{
+	static Param dynamic_modelparam(modelobj_paramtab);
+	return dynamic_modelparam;
+}
+
+ParamInterface* ModelObj::getInterface()
+{
+	return &getStaticParam();
+}
+
+ExtObject ModelObj::makeStaticObject(Model* m)
+{
+	return ExtObject(&getStaticParam(), (void*)m);
+}
+
+ExtObject ModelObj::makeDynamicObject(Model* m)
+{
+	return ExtObject(&getDynamicParam(), (DestrBase*)m);
+}
+
+Model* ModelObj::fromObject(const ExtValue& v, bool warn)
+{
+	return (Model*)v.getObjectTarget(getStaticParam().getName(), warn);
+}
+
+void ModelObj::p_getpart(PARAMPROCARGS)
+{
+	int i = args->getInt();
+	if ((i < 0) || (i >= getPartCount()))
+	{
+		ret->setEmpty();
+		return;
+	}
+	ret->setObject(ExtObject(&Part::getStaticParam(), getPart(i)));
+}
+
+void ModelObj::p_getjoint(PARAMPROCARGS)
+{
+	int i = args->getInt();
+	if ((i < 0) || (i >= getJointCount()))
+	{
+		ret->setEmpty();
+		return;
+	}
+	ret->setObject(ExtObject(&Joint::getStaticParam(), getJoint(i)));
+}
+
+void ModelObj::p_getneuro(PARAMPROCARGS)
+{
+	int i = args->getInt();
+	if ((i < 0) || (i >= getNeuroCount()))
+	{
+		ret->setEmpty();
+		return;
+	}
+	ret->setObject(ExtObject(&Neuro::getStaticParam(), getNeuro(i)));
+}
+
+void ModelObj::get_bboxsize(ExtValue *ret)
+{
+	*ret = Pt3D_Ext::makeDynamicObject(new Pt3D_Ext(size));
+}
Index: /cpp/frams/model/modelobj.h
===================================================================
--- /cpp/frams/model/modelobj.h	(revision 722)
+++ /cpp/frams/model/modelobj.h	(revision 722)
@@ -0,0 +1,39 @@
+#ifndef _MODELOBJ_H_
+#define _MODELOBJ_H_
+
+#include "model.h"
+
+extern ParamEntry modelobj_paramtab[];
+
+class ModelObj : public Model
+{
+public:
+#define STATRICKCLASS ModelObj
+
+	PARAMGETDEF(geno);
+	PARAMPROCDEF(p_newfromstring);
+	PARAMPROCDEF(p_newfromgeno);
+
+#define GETDELEGATE(name,type,value) PARAMGETDEF(name) {arg1->set ## type (value);}
+	GETDELEGATE(numparts, Int, getPartCount())
+	GETDELEGATE(numjoints, Int, getJointCount())
+	GETDELEGATE(numneurons, Int, getNeuroCount())
+	GETDELEGATE(numconnections, Int, getConnectionCount())
+#undef GETDELEGATE
+
+	PARAMPROCDEF(p_getpart);
+	PARAMPROCDEF(p_getjoint);
+	PARAMPROCDEF(p_getneuro);
+	PARAMGETDEF(bboxsize);
+
+#undef STATRICKCLASS
+
+	static ExtObject makeStaticObject(Model* g);
+	static ExtObject makeDynamicObject(Model* g);
+	static Model* fromObject(const ExtValue& v, bool warn = true);
+	static ParamInterface* getInterface();
+	static Param& getStaticParam();
+	static Param& getDynamicParam();
+};
+
+#endif
