[Bf-committers] First data extraction from armatures using python (patch)
Jordi Rovira i Bonet
bf-committers@blender.org
Tue, 29 Apr 2003 13:28:02 +0200
This is a multi-part message in MIME format.
--------------070201000005070004020906
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Hello,
Finally i've been able to generate a patch on what i've been doing
about armatures: The current supported python api includes the following
additions:
Blender.Armature.getRaw(string name) :
get the armature with the given name
Mesh.getVertexInfluences(int index):
returns a list of pairs (string bonename, float weight) with the
vertex influences received by the vertex indicated in the index.
Blender.Armature has two properties:
* name (string)
* bones (list of Bone)
Bone has many properties matching the ones in the C structure:
* head (vector 3d)
* tail (vector 3d)
* roll (float)
* loc (vector 3d)
* quat (quaternion)
* size (vector 3d)
* children (list of Bone)
* parent (Bone)
* valid (1 or 0 if wrapping a null bone)
This is a completely provisional API. And unstable. I'm posting it
here so i can receive flaming and some good notes on what should it be,
so i can change it. Python masters: what do you say? I've been focusing
mainly in QUERYING the information (despite some function can set some
values), because it seems that the main use of this will be exporting data.
As i don't have a full exporter yet, i don't know if i've made all
required data accessible. But it's a beginning.
One problem i have is that when getting the parent of a mesh, if its
an armature, the call to "getType()" returns "25" which is the constant
associated to the armatures, but doesn't return "Armature". And when
trying to getData() it doen't work. I have to get the armature by
getting the name, and then:
Blender.Object.Get(object.parent.name).getData()
I need to figure out how to export animations now (actions).
Attached to this file you can find a patch appliable to the CVS source
(at least on 29 April 12:51 C.E.T). The command is
patch -p0 < armature_api.pp
from the root of the blender source. There are also 3 files to add:
opy_armature* that should go into directory
/source/blender/bpython/intern
and Armature.py, that should go into
/intern/python/modules/Blender
to get a blender with the modifications i've been playing with.
I did'nt know if it was possible to generate a patch which added the
files automatically. Any hint?
(bandoler)
--------------070201000005070004020906
Content-Type: text/plain;
name="armature_api.pp"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="armature_api.pp"
Index: intern/python/py_main.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/intern/python/py_main.c,v
retrieving revision 1.3
diff -B -b -c -r1.3 py_main.c
*** intern/python/py_main.c 25 Nov 2002 09:53:06 -0000 1.3
--- intern/python/py_main.c 29 Apr 2003 10:22:56 -0000
***************
*** 2062,2067 ****
--- 2062,2071 ----
}
}
break;
+ case OB_ARMATURE:
+ object->data = PyString_FromString(((bArmature*) obj->data)->id.name+2);
+ object->type = PyString_FromString("Armature");
+ break;
case OB_CURVE:
printf("Curve\n");
break;
Index: intern/python/modules/Makefile.am
===================================================================
RCS file: /cvsroot/bf-blender/blender/intern/python/modules/Makefile.am,v
retrieving revision 1.4
diff -B -b -c -r1.4 Makefile.am
*** intern/python/modules/Makefile.am 12 Apr 2003 17:20:55 -0000 1.4
--- intern/python/modules/Makefile.am 29 Apr 2003 10:22:56 -0000
***************
*** 12,17 ****
--- 12,18 ----
Blender/Material.py \
Blender/Mesh.py \
Blender/NMesh.py \
+ Blender/Armature.py \
Blender/Object.py \
Blender/Scene.py \
Blender/Text.py \
Index: intern/python/modules/Blender/Object.py
===================================================================
RCS file: /cvsroot/bf-blender/blender/intern/python/modules/Blender/Object.py,v
retrieving revision 1.3
diff -B -b -c -r1.3 Object.py
*** intern/python/modules/Blender/Object.py 6 Feb 2003 03:30:22 -0000 1.3
--- intern/python/modules/Blender/Object.py 29 Apr 2003 10:22:56 -0000
***************
*** 276,293 ****
_getters = {}
! from Blender import Mesh, Camera, Lamp
t = _Object.Types
Types = {"Camera" : t.CAMERA,
"Empty" : t.EMPTY,
"Lamp" : t.LAMP,
"Mesh" : t.MESH,
}
# create lookup table for data wrappers
_dataWrappers = range(max(Types.values()) + 1)
_dataWrappers[t.MESH] = ("Mesh", Mesh.rawMesh)
_dataWrappers[t.CAMERA] = ("Camera", Camera.Camera)
_dataWrappers[t.LAMP] = ("Lamp", Lamp.Lamp)
_dataWrappers[t.EMPTY] = ("Empty", _Empty_nodata)
--- 276,295 ----
_getters = {}
! from Blender import Mesh, Camera, Lamp, Armature
t = _Object.Types
Types = {"Camera" : t.CAMERA,
"Empty" : t.EMPTY,
"Lamp" : t.LAMP,
"Mesh" : t.MESH,
+ "Armature" : t.ARMATURE,
}
# create lookup table for data wrappers
_dataWrappers = range(max(Types.values()) + 1)
_dataWrappers[t.MESH] = ("Mesh", Mesh.rawMesh)
+ _dataWrappers[t.ARMATURE] = ("Armature", Armature.Armature)
_dataWrappers[t.CAMERA] = ("Camera", Camera.Camera)
_dataWrappers[t.LAMP] = ("Lamp", Lamp.Lamp)
_dataWrappers[t.EMPTY] = ("Empty", _Empty_nodata)
Index: intern/python/modules/Blender/__init__.py
===================================================================
RCS file: /cvsroot/bf-blender/blender/intern/python/modules/Blender/__init__.py,v
retrieving revision 1.4
diff -B -b -c -r1.4 __init__.py
*** intern/python/modules/Blender/__init__.py 6 Feb 2003 03:30:22 -0000 1.4
--- intern/python/modules/Blender/__init__.py 29 Apr 2003 10:22:56 -0000
***************
*** 2,8 ****
# The Blender main module wrapper
# (c) 06/2001, NaN // strubi@blender.nl
! __all__ = ["Object", "Image", "NMesh", "Window", "Mesh", "sys",
"Lamp", "Scene", "Draw", "Camera", "Material", "Types", "Ipo",
"BGL"]
--- 2,8 ----
# The Blender main module wrapper
# (c) 06/2001, NaN // strubi@blender.nl
! __all__ = ["Object", "Image", "NMesh", "Armature", "Window", "Mesh", "sys",
"Lamp", "Scene", "Draw", "Camera", "Material", "Types", "Ipo",
"BGL"]
***************
*** 14,20 ****
bylink = _Blender.bylink
import Object, Image, Mesh, Window, sys, Lamp, Scene, Draw, Camera
! import Material, NMesh, BGL, Types, Ipo, Text
deg = lambda x: 0.0174532925199 * x # conversion from degrees to radians
--- 14,20 ----
bylink = _Blender.bylink
import Object, Image, Mesh, Window, sys, Lamp, Scene, Draw, Camera
! import Material, NMesh, Armature, BGL, Types, Ipo, Text
deg = lambda x: 0.0174532925199 * x # conversion from degrees to radians
Index: source/blender/bpython/Makefile.am
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/bpython/Makefile.am,v
retrieving revision 1.8
diff -B -b -c -r1.8 Makefile.am
*** source/blender/bpython/Makefile.am 12 Apr 2003 17:21:00 -0000 1.8
--- source/blender/bpython/Makefile.am 29 Apr 2003 10:22:58 -0000
***************
*** 38,43 ****
--- 38,45 ----
intern/opy_matrix.c \
intern/opy_nmesh.c \
intern/opy_nmesh.h \
+ intern/opy_armature.c \
+ intern/opy_armature.h \
intern/opy_vector.c \
intern/opy_vector.h \
intern/opy_window.c
Index: source/blender/bpython/intern/BPY_main.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/bpython/intern/BPY_main.h,v
retrieving revision 1.5
diff -B -b -c -r1.5 BPY_main.h
*** source/blender/bpython/intern/BPY_main.h 27 Dec 2002 13:10:15 -0000 1.5
--- source/blender/bpython/intern/BPY_main.h 29 Apr 2003 10:22:58 -0000
***************
*** 51,56 ****
--- 51,57 ----
#include "BKE_text.h"
#include "BKE_displist.h"
#include "BKE_mesh.h"
+ #include "BKE_armature.h"
#include "BKE_material.h"
#include "BKE_object.h"
#include "BKE_screen.h"
Index: source/blender/bpython/intern/BPY_modules.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/bpython/intern/BPY_modules.h,v
retrieving revision 1.6
diff -B -b -c -r1.6 BPY_modules.h
*** source/blender/bpython/intern/BPY_modules.h 27 Dec 2002 13:10:15 -0000 1.6
--- source/blender/bpython/intern/BPY_modules.h 29 Apr 2003 10:22:58 -0000
***************
*** 33,38 ****
--- 33,39 ----
extern PyObject *init_blender(void);
extern PyObject *init_py_nmesh(void);
+ extern PyObject *init_py_armature(void);
extern PyObject *init_py_draw(void);
extern PyObject *init_py_bgl(void);
extern PyObject *initWindow(void);
Index: source/blender/bpython/intern/BPY_object.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/bpython/intern/BPY_object.c,v
retrieving revision 1.3
diff -B -b -c -r1.3 BPY_object.c
*** source/blender/bpython/intern/BPY_object.c 25 Nov 2002 12:01:57 -0000 1.3
--- source/blender/bpython/intern/BPY_object.c 29 Apr 2003 10:22:58 -0000
***************
*** 480,485 ****
--- 480,486 ----
PyDict_SetItemString(dict, "Types", d);
BPY_ADDCONST(d, EMPTY);
BPY_ADDCONST(d, MESH);
+ BPY_ADDCONST(d, ARMATURE);
BPY_ADDCONST(d, LAMP);
BPY_ADDCONST(d, CAMERA);
Index: source/blender/bpython/intern/b_interface.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/bpython/intern/b_interface.h,v
retrieving revision 1.5
diff -B -b -c -r1.5 b_interface.h
*** source/blender/bpython/intern/b_interface.h 27 Dec 2002 13:10:15 -0000 1.5
--- source/blender/bpython/intern/b_interface.h 29 Apr 2003 10:22:58 -0000
***************
*** 101,106 ****
--- 101,107 ----
#define getSceneList() _GETMAINLIST(scene)
#define getObjectList() _GETMAINLIST(object)
#define getMeshList() _GETMAINLIST(mesh)
+ #define getArmatureList() _GETMAINLIST(armature)
#define getMaterialList() _GETMAINLIST(mat)
#define getCameraList() _GETMAINLIST(camera)
#define getLampList() _GETMAINLIST(lamp)
Index: source/blender/bpython/intern/opy_blender.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/bpython/intern/opy_blender.c,v
retrieving revision 1.3
diff -B -b -c -r1.3 opy_blender.c
*** source/blender/bpython/intern/opy_blender.c 25 Nov 2002 12:01:57 -0000 1.3
--- source/blender/bpython/intern/opy_blender.c 29 Apr 2003 10:22:58 -0000
***************
*** 324,329 ****
--- 324,330 ----
PyDict_SetItemString(dict, "Image", INITMODULE(Image)());
PyDict_SetItemString(dict, "Window",INITMODULE(Window)());
PyDict_SetItemString(dict, "NMesh", init_py_nmesh());
+ PyDict_SetItemString(dict, "Armature", init_py_armature());
PyDict_SetItemString(dict, "Draw", init_py_draw());
PyDict_SetItemString(dict, "BGL", init_py_bgl());
#ifdef EXPERIMENTAL
Index: source/blender/bpython/intern/opy_datablock.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/bpython/intern/opy_datablock.c,v
retrieving revision 1.3
diff -B -b -c -r1.3 opy_datablock.c
*** source/blender/bpython/intern/opy_datablock.c 25 Nov 2002 12:01:57 -0000 1.3
--- source/blender/bpython/intern/opy_datablock.c 29 Apr 2003 10:22:58 -0000
***************
*** 88,93 ****
--- 88,94 ----
#include "opy_datablock.h"
#include "opy_nmesh.h"
+ #include "opy_armature.h"
#include "opy_vector.h" /* matrix datatypes */
***************
*** 1100,1105 ****
--- 1101,1115 ----
*/
// return newNCurveObject(data);
+
+ } else if (idn==ID_AR) {
+ return newArmature(data);
+ /* newb= PyObject_NEW(DataBlock, &DataBlock_Type);
+ newb->type= "Armature";
+ newb->type_list= getArmatureList();
+ newb->properties= Armature_Properties;
+ */
+
} else if (idn==ID_LA) {
newb= PyObject_NEW(DataBlock, &DataBlock_Type);
Index: source/blender/bpython/intern/opy_nmesh.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/bpython/intern/opy_nmesh.c,v
retrieving revision 1.4
diff -B -b -c -r1.4 opy_nmesh.c
*** source/blender/bpython/intern/opy_nmesh.c 20 Dec 2002 02:18:57 -0000 1.4
--- source/blender/bpython/intern/opy_nmesh.c 29 Apr 2003 10:22:58 -0000
***************
*** 38,43 ****
--- 38,45 ----
#include "BPY_tools.h"
#include "BPY_main.h"
+ #include "DNA_armature_types.h"
+
#include "opy_datablock.h"
#include "opy_nmesh.h"
***************
*** 746,751 ****
--- 748,808 ----
}
+
+ /** Python documentation string for the function getVertexInfluence. */
+ static char NMesh_getVertexInfluences_doc[] = "Return a list of the influences of bones in the vertex specified by index. The list contains pairs with the bone name and the weight.";
+
+ /** Implementation of the python method getVertexInfluence for an NMesh object.
+ * This method returns a list of pairs (string,float) with bone nemaes and influences that this vertex receives.
+ * @author Jordi Rovira i Bonet
+ */
+ static PyObject *NMesh_getVertexInfluences(PyObject *self, PyObject *args)
+ {
+ // Get a reference to the mesh object wrapped in here.
+ Mesh *me= ((NMesh*)self)->mesh;
+
+ // Parse the parameters: only on integer (vertex index)
+ int index;
+ BPY_TRY(PyArg_ParseTuple(args, "i", &index));
+
+ // Declare the list to return
+ PyObject* influence_list = NULL;
+
+ // Proceed only if we have vertex deformation information and index is valid
+ if (me->dvert)
+ if ((index>=0) && (index<me->totvert))
+ {
+ // Number of bones influencig the vertex
+ int totinfluences=me->dvert[index].totweight;
+
+ // Build the list only with weights and names of the influent bones
+ influence_list = PyList_New(totinfluences);
+
+ //Get the reference of the first wwight structure
+ MDeformWeight *sweight = me->dvert[index].dw;
+ int i;
+ for (i=0; i<totinfluences; i++) {
+
+ // Some check that should always be true
+ assert(sweight->data);
+
+ //Add the weight and the name of the bone, which is used to identify it
+ PyList_SetItem(influence_list, i, Py_BuildValue("[sf]", sweight->data->name, sweight->weight));
+
+ //Next weight
+ sweight++;
+ }
+ }
+ else influence_list = PyList_New(0);
+ else influence_list = PyList_New(0);
+
+ // Return the list. !QUESTION! Should i reincrement the number of references like i'm doing?
+ return BPY_incr_ret(influence_list);
+
+ }
+
+
+
static char NMesh_update_doc[] = "updates the Mesh";
static PyObject *NMesh_update(PyObject *self, PyObject *args)
{
***************
*** 841,846 ****
--- 898,904 ----
MethodDef(getActiveFace),
MethodDef(getSelectedFaces),
MethodDef(update),
+ MethodDef(getVertexInfluences),
#ifdef EXPERIMENTAL
MethodDef(asMesh),
#endif
--------------070201000005070004020906
Content-Type: text/x-csrc;
name="opy_armature.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="opy_armature.c"
/* python.c MIXED MODEL
*
* june 99
* $Id: opy_armature.c,v 1.4 2002/12/20 02:18:57 mein Exp $
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include "Python.h"
#include "BPY_macros.h"
#include "b_interface.h"
#include "BPY_tools.h"
#include "BPY_main.h"
#include "opy_datablock.h"
#include "opy_armature.h"
#include "MEM_guardedalloc.h"
#include "BKE_armature.h"
#include "BKE_mesh.h"
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_displist.h"
#include "BKE_screen.h"
#include "BKE_object.h"
#include "BPY_objtypes.h"
#include "BLI_blenlib.h"
#include "BIF_space.h"
#include "opy_vector.h"
#include "b_interface.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* PROTOS */
static int unlink_existingArmaturedata(bArmature *armature);
void initArmature(void);
PyObject *init_py_armature(void);
int BPY_check_sequence_consistency(PyObject *seq, PyTypeObject *against);
static wBone *wbone_from_data(Bone* rawbone);
/* TYPE OBJECTS */
PyTypeObject Armature_Type;
PyTypeObject Bone_Type;
/* DEFINES */
/* GLOBALS */
static PyObject *g_armaturemodule = NULL;
/*****************************/
/* Armature Bone Object */
/*****************************/
static void Bone_dealloc(PyObject *self) {
PyMem_DEL(self);
}
static wBone *newbone (Bone* rawbone, wBone* parent) {
// Create wrapper object
wBone *mc= (wBone *) PyObject_NEW(wBone, &Bone_Type);
// Set reference to real blender bone
mc->bone = rawbone;
// check that we are really wrapping a bone
if (rawbone)
{
// Set parent, or wrap null in no parent
if (parent) mc->parent = parent;
else mc->parent = newbone(NULL,NULL);
// Count child bones
int totbones = 0;
Bone* current = rawbone->childbase.first;
for (;current; current=current->next) totbones++;
// Build the list of children recursively
mc->children= PyList_New(totbones);
Bone *mbone = rawbone->childbase.first;
int i;
for (i=0; i<totbones; i++) {
assert(mbone);
PyList_SetItem(mc->children, i, (PyObject *) newbone(mbone,mc));
mbone = mbone->next;
}
}
else
{
// We are null, so parent doesn't matter. Set NULL too.
mc->parent = NULL;
}
return mc;
}
PyObject *Bone_repr(wBone *self)
{
static char s[256];
if (self->bone)
sprintf (s, "[Bone - name<%s>, head<%f, %f, %f>, tail<%f,%f,%f>, roll<%f>]", self->bone->name, self->bone->head[0], self->bone->head[1], self->bone->head[2], self->bone->tail[0], self->bone->tail[1], self->bone->tail[2]);
else sprintf(s,"[Bone - NULL]");
return Py_BuildValue("s", s);
}
static PyObject *Bone_getattr(PyObject *self, char *name) {
wBone *mc= (wBone *) self;
if (mc->bone)
{
if (strcmp(name, "roll")==0) return Py_BuildValue("f", mc->bone->roll);
else if (strcmp(name, "valid")==0) return Py_BuildValue("i", 1);
else if (strcmp(name, "name")==0) return Py_BuildValue("s", mc->bone->name);
else if (strcmp(name, "head")==0) return Py_BuildValue("[fff]", mc->bone->head[0],mc->bone->head[1],mc->bone->head[2]);
else if (strcmp(name, "tail")==0) return Py_BuildValue("[fff]", mc->bone->tail[0],mc->bone->tail[1],mc->bone->tail[2]);
else if (strcmp(name, "loc")==0) return Py_BuildValue("[fff]", mc->bone->loc[0], mc->bone->loc[1], mc->bone->loc[2]);
else if (strcmp(name, "size")==0) return Py_BuildValue("[fff]", mc->bone->size[0], mc->bone->size[1], mc->bone->size[2]);
else if (strcmp(name, "quat")==0) return Py_BuildValue("[ffff]", mc->bone->quat[0], mc->bone->quat[1], mc->bone->quat[2], mc->bone->quat[3]);
else if (strcmp(name, "parent")==0) return BPY_incr_ret(mc->parent);
else if (strcmp(name, "children")==0) return BPY_incr_ret(mc->children);
}
else if (strcmp(name, "valid")==0) return Py_BuildValue("i", 0);
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
}
PyTypeObject Bone_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Bone", /*tp_name*/
sizeof(wBone), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor) Bone_dealloc, /*tp_dealloc*/
(printfunc) 0, /*tp_print*/
(getattrfunc) Bone_getattr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc) Bone_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
};
/*****************************/
/* Armature Python Object */
/*****************************/
static void Armature_dealloc(PyObject *self) {
Armature *me= (Armature *) self;
Py_DECREF(me->name);
PyMem_DEL(self);
}
static char Armature_link_doc[] = "(object) - Links Armature data with Object 'object'";
PyObject * Armature_link(PyObject *self, PyObject *args)
{
return DataBlock_link(self, args);
}
#undef MethodDef
#define MethodDef(func) {#func, Armature_##func, METH_VARARGS, Armature_##func##_doc}
static struct PyMethodDef Armature_methods[] = {
{NULL, NULL}
};
static PyObject *Armature_getattr(PyObject *self, char *name)
{
Armature *me= (Armature *) self;
if (STREQ(name, "name"))
return BPY_incr_ret(me->name);
else if (STREQ(name, "bones"))
return BPY_incr_ret(me->bones);
else if (STREQ(name, "users")) {
if (me->armature)
{
return PyInt_FromLong(me->armature->id.us);
} else { // it's a free mesh:
return Py_BuildValue("i", 0);
}
}
return Py_FindMethod(Armature_methods, (PyObject*)self, name);
}
static int Armature_setattr(PyObject *self, char *name, PyObject *v) {
Armature *me= (Armature *) self;
if (STREQ2(name, "name", "bones")) {
if(PySequence_Check(v)) {
if(STREQ(name, "name")) {
Py_DECREF(me->name);
me->name= BPY_incr_ret(v);
} else if (STREQ(name, "bones")) {
Py_DECREF(me->bones);
me->bones= BPY_incr_ret(v);
}
} else {
PyErr_SetString(PyExc_AttributeError, "expected a sequence");
return -1;
}
} else {
PyErr_SetString(PyExc_AttributeError, name);
return -1;
}
return 0;
}
#undef BPY_ADDCONST
#define BPY_ADDCONST(dict, name) insertConst(dict, #name, PyInt_FromLong(TF_##name))
/* set constants for face drawing mode -- see drawmesh.c */
static void init_ArmatureConst(PyObject *d)
{
/* transparent modes
BPY_ADDCONST(d, SOLID);
BPY_ADDCONST(d, ADD);
BPY_ADDCONST(d, ALPHA);
BPY_ADDCONST(d, SUB);
*/
}
PyTypeObject Armature_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Armature", /*tp_name*/
sizeof(bArmature), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor) Armature_dealloc, /*tp_dealloc*/
(printfunc) 0, /*tp_print*/
(getattrfunc) Armature_getattr, /*tp_getattr*/
(setattrfunc) Armature_setattr, /*tp_setattr*/
};
PyObject *newArmature(bArmature *oldarmature)
{
Armature *me= PyObject_NEW(Armature, &Armature_Type);
if (!oldarmature) {
me->name= BPY_incr_ret(Py_None);
me->bones= PyList_New(0);
me->armature= 0;
} else {
int totbones = 0;
Bone* current = oldarmature->bonebase.first;
for (;current; current=current->next) totbones++;
Bone *mbone = oldarmature->bonebase.first;
me->name= PyString_FromString(oldarmature->id.name+2);
me->armature= oldarmature;
me->bones= PyList_New(totbones);
int i;
for (i=0; i<totbones; i++) {
assert(mbone);
// Create bone with null parent
PyList_SetItem(me->bones, i, (PyObject *) newbone(mbone,NULL));
mbone = mbone->next;
}
}
return (PyObject *) me;
}
static char Armaturemodule_New_doc[]=
"() - returns a new, empty Armature object\n";
static PyObject *Armaturemodule_New(PyObject *self, PyObject *args)
{
return newArmature(NULL);
}
static char Armaturemodule_GetRaw_doc[]=
"([name]) - Get a raw armature from Blender\n \
\n \
[name] Name of the armature to be returned\n \
\n \
If name is not specified a new empty armature is\n \
returned, otherwise Blender returns an existing\n \
armature.";
static PyObject *Armaturemodule_GetRaw(PyObject *self, PyObject *args)
{
char *name=NULL;
bArmature *oldarmature=NULL;
BPY_TRY(PyArg_ParseTuple(args, "|s", &name));
if(name) {
oldarmature = (bArmature *) getFromList(getArmatureList(), name);
if (!oldarmature) return BPY_incr_ret(Py_None);
}
return newArmature(oldarmature);
}
static int unlink_existingArmaturedata(bArmature *armature)
{
// not implemented?
// unlink_armature(armature);
return 1;
}
#undef MethodDef
#define MethodDef(func) {#func, Armaturemodule_##func, METH_VARARGS, Armaturemodule_##func##_doc}
static struct PyMethodDef Armaturemodule_methods[] = {
MethodDef(GetRaw),
MethodDef(New),
{NULL, NULL}
};
#undef BPY_ADDCONST
#define BPY_ADDCONST(dict, name) insertConst(dict, #name, PyInt_FromLong(TF_##name))
PyObject *init_py_armature(void)
{
PyObject *d;
PyObject *mod= Py_InitModule(SUBMODULE(Armature), Armaturemodule_methods);
PyObject *dict= PyModule_GetDict(mod);
Armature_Type.ob_type= &PyType_Type;
d = ConstObject_New();
PyDict_SetItemString(dict, "Const" , d);
init_ArmatureConst(d);
g_armaturemodule = mod;
return mod;
}
#ifdef SHAREDMODULE
void initArmature(void)
{
init_py_armature();
}
#endif
--------------070201000005070004020906
Content-Type: text/x-chdr;
name="opy_armature.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="opy_armature.h"
/**
* $Id: opy_nmesh.h,v 1.5 2002/12/27 13:10:16 mein Exp $
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
/* opy_armature.h */
#include "DNA_armature_types.h"
#define Armature_Check(v) ((v)->ob_type == &Armature_Type)
#define Bone_Check(v) ((v)->ob_type == &Bone_Type)
struct PyBlock;
typedef struct _Armature
{
PyObject_HEAD
bArmature *armature;
PyObject *name;
PyObject *bones;
char flags;
} Armature;
typedef struct _Bone {
PyObject_HEAD
Bone *bone;
PyObject *parent;
PyObject *children;
} wBone;
/* PROTOS */
PyObject *newArmature(bArmature *oldarmature);
--------------070201000005070004020906
Content-Type: text/plain;
name="Armature.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="Armature.py"
"""The Blender Armature module
This module provides access to the raw **Armature** data block.
This module is worse than experimental.
"""
import _Blender.Armature as _Armature
import shadow
class Armature:
"""The Armature object
This contains a copy of the armature object data.
Attributes
"""
def __init__(self, object):
if object:
self._object = object
else:
self._object = _Armature.GetRaw()
def __repr__(self):
return "[Armature \"%s\"]" % self.name
def __getattr__(self, name):
if name == 'bones':
return self._object.bones
elif name == 'name':
return self._object.name
else:
return getattr(self._object, name)
def New(name = None):
"""Creates a new Armature mesh object and returns it"""
pass
def GetRaw(name = None):
"""If 'name' specified, the Armature object with 'name' is returned, 'None'
if not existant. Otherwise, a new empty Armature is initialized and returned."""
pass
# override all these functions again, because we only used them for
# documentation
New = _Armature.New
GetRaw = _Armature.GetRaw
def Armature(data):
return data
# Bone wrapper class
class Bone:
"""Bone wrapper class
This class emulates a bone allowing to read its data
"""
def __init__(self, vlist):
self.name = "unnamed"
self.head = [0.0,0.0,0.0]
self.tail = [1.0,0.0,0.0]
self.roll = 0.0
# override:
#Bone = _Armature.Bone
--------------070201000005070004020906--