-NLA module added
-ability to set poses for the armatures - allows for keyframing armatures -adds support for actions/actionchannels -additional checking for addBone and clear parenting -moved getActionIpos from object module to NLA module
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "Armature.h"
|
#include "Armature.h"
|
||||||
#include "Bone.h"
|
#include "Bone.h"
|
||||||
|
#include "NLA.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -60,18 +61,18 @@ PyObject *Armature_Init (void);
|
|||||||
/* In Python these will be written to the console when doing a */
|
/* In Python these will be written to the console when doing a */
|
||||||
/* Blender.Armature.__doc__ */
|
/* Blender.Armature.__doc__ */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
char M_Armature_doc[] = "The Blender Armature module\n\n\
|
static char M_Armature_doc[] = "The Blender Armature module\n\n\
|
||||||
This module provides control over **Armature Data** objects in Blender.\n";
|
This module provides control over **Armature Data** objects in Blender.\n";
|
||||||
|
|
||||||
char M_Armature_New_doc[] = "(name) - return a new Armature datablock of \n\
|
static char M_Armature_New_doc[] = "(name) - return a new Armature datablock of \n\
|
||||||
optional name 'name'.";
|
optional name 'name'.";
|
||||||
|
|
||||||
char M_Armature_Get_doc[] =
|
static char M_Armature_Get_doc[] =
|
||||||
"(name) - return the armature with the name 'name', \
|
"(name) - return the armature with the name 'name', \
|
||||||
returns None if not found.\n If 'name' is not specified, \
|
returns None if not found.\n If 'name' is not specified, \
|
||||||
it returns a list of all armatures in the\ncurrent scene.";
|
it returns a list of all armatures in the\ncurrent scene.";
|
||||||
|
|
||||||
char M_Armature_get_doc[] = "(name) - DEPRECATED. Use 'Get' instead. \
|
static char M_Armature_get_doc[] = "(name) - DEPRECATED. Use 'Get' instead. \
|
||||||
return the armature with the name 'name', \
|
return the armature with the name 'name', \
|
||||||
returns None if not found.\n If 'name' is not specified, \
|
returns None if not found.\n If 'name' is not specified, \
|
||||||
it returns a list of all armatures in the\ncurrent scene.";
|
it returns a list of all armatures in the\ncurrent scene.";
|
||||||
@@ -179,9 +180,10 @@ M_Armature_New (PyObject * self, PyObject * args, PyObject * keywords)
|
|||||||
/* now create the wrapper obj in Python */
|
/* now create the wrapper obj in Python */
|
||||||
py_armature = (BPy_Armature *)PyObject_NEW(BPy_Armature, &Armature_Type);
|
py_armature = (BPy_Armature *)PyObject_NEW(BPy_Armature, &Armature_Type);
|
||||||
}
|
}
|
||||||
else
|
else{
|
||||||
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
"couldn't create Armature Data in Blender"));
|
"couldn't create Armature Data in Blender"));
|
||||||
|
}
|
||||||
|
|
||||||
if (py_armature == NULL)
|
if (py_armature == NULL)
|
||||||
return (EXPP_ReturnPyObjError (PyExc_MemoryError,
|
return (EXPP_ReturnPyObjError (PyExc_MemoryError,
|
||||||
@@ -296,6 +298,7 @@ Armature_Init (void)
|
|||||||
/* Add the Bone submodule to this module */
|
/* Add the Bone submodule to this module */
|
||||||
dict = PyModule_GetDict (submodule);
|
dict = PyModule_GetDict (submodule);
|
||||||
PyDict_SetItemString (dict, "Bone", Bone_Init ());
|
PyDict_SetItemString (dict, "Bone", Bone_Init ());
|
||||||
|
PyDict_SetItemString (dict, "NLA", NLA_Init ());
|
||||||
|
|
||||||
return (submodule);
|
return (submodule);
|
||||||
}
|
}
|
||||||
@@ -391,6 +394,24 @@ doesBoneName_exist(char *name, bArmature* arm)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
testChildInChildbase(Bone *bone, Bone *test)
|
||||||
|
{
|
||||||
|
Bone *child;
|
||||||
|
for(child = bone->childbase.first; child; child = child->next){
|
||||||
|
if(child == test){
|
||||||
|
return 1;
|
||||||
|
}else{
|
||||||
|
if(child->childbase.first != NULL){
|
||||||
|
if(testChildInChildbase(child, test)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testBoneInArmature(bArmature *arm, Bone *test)
|
testBoneInArmature(bArmature *arm, Bone *test)
|
||||||
{
|
{
|
||||||
@@ -399,6 +420,12 @@ testBoneInArmature(bArmature *arm, Bone *test)
|
|||||||
for(root = arm->bonebase.first; root; root = root->next){
|
for(root = arm->bonebase.first; root; root = root->next){
|
||||||
if(root == test){
|
if(root == test){
|
||||||
return 1;
|
return 1;
|
||||||
|
}else{
|
||||||
|
if(root->childbase.first != NULL){
|
||||||
|
if(testChildInChildbase(root, test)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,7 +459,7 @@ static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args)
|
|||||||
|
|
||||||
//add to parent's childbase
|
//add to parent's childbase
|
||||||
BLI_addtail (&py_bone->bone->parent->childbase, py_bone->bone);
|
BLI_addtail (&py_bone->bone->parent->childbase, py_bone->bone);
|
||||||
|
|
||||||
//get the worldspace coords for the parent
|
//get the worldspace coords for the parent
|
||||||
get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 0,0);
|
get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 0,0);
|
||||||
|
|
||||||
|
|||||||
@@ -38,12 +38,17 @@
|
|||||||
#include <BKE_library.h>
|
#include <BKE_library.h>
|
||||||
#include <MEM_guardedalloc.h>
|
#include <MEM_guardedalloc.h>
|
||||||
#include <BLI_blenlib.h>
|
#include <BLI_blenlib.h>
|
||||||
|
#include <DNA_action_types.h>
|
||||||
|
#include <BIF_poseobject.h>
|
||||||
|
#include <BKE_action.h>
|
||||||
|
#include <BSE_editaction.h>
|
||||||
|
#include <BKE_constraint.h>
|
||||||
|
|
||||||
#include "constant.h"
|
#include "constant.h"
|
||||||
#include "gen_utils.h"
|
#include "gen_utils.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
#include "quat.h"
|
#include "quat.h"
|
||||||
|
#include "NLA.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Python API function prototypes for the Bone module. */
|
/* Python API function prototypes for the Bone module. */
|
||||||
@@ -102,6 +107,7 @@ static PyObject *Bone_setSize (BPy_Bone * self, PyObject * args);
|
|||||||
static PyObject *Bone_setQuat (BPy_Bone * self, PyObject * args);
|
static PyObject *Bone_setQuat (BPy_Bone * self, PyObject * args);
|
||||||
static PyObject *Bone_setParent(BPy_Bone *self, PyObject *args);
|
static PyObject *Bone_setParent(BPy_Bone *self, PyObject *args);
|
||||||
static PyObject *Bone_setWeight(BPy_Bone *self, PyObject *args);
|
static PyObject *Bone_setWeight(BPy_Bone *self, PyObject *args);
|
||||||
|
static PyObject *Bone_setPose (BPy_Bone *self, PyObject *args);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Python BPy_Bone methods table: */
|
/* Python BPy_Bone methods table: */
|
||||||
@@ -157,6 +163,8 @@ static PyMethodDef BPy_Bone_methods[] = {
|
|||||||
"() - set the Bone parent of this one."},
|
"() - set the Bone parent of this one."},
|
||||||
{"setWeight", (PyCFunction)Bone_setWeight, METH_VARARGS,
|
{"setWeight", (PyCFunction)Bone_setWeight, METH_VARARGS,
|
||||||
"() - set the Bone weight."},
|
"() - set the Bone weight."},
|
||||||
|
{"setPose", (PyCFunction)Bone_setPose, METH_VARARGS,
|
||||||
|
"() - set a pose for this bone at a frame."},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -254,6 +262,10 @@ Bone_Init (void)
|
|||||||
submodule = Py_InitModule3 ("Blender.Armature.Bone",
|
submodule = Py_InitModule3 ("Blender.Armature.Bone",
|
||||||
M_Bone_methods, M_Bone_doc);
|
M_Bone_methods, M_Bone_doc);
|
||||||
|
|
||||||
|
PyModule_AddIntConstant(submodule, "ROT", POSE_ROT);
|
||||||
|
PyModule_AddIntConstant(submodule, "LOC", POSE_LOC);
|
||||||
|
PyModule_AddIntConstant(submodule, "SIZE", POSE_SIZE);
|
||||||
|
|
||||||
return (submodule);
|
return (submodule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,7 +740,7 @@ Bone_setWeight(BPy_Bone *self, PyObject *args)
|
|||||||
float weight;
|
float weight;
|
||||||
|
|
||||||
if (!self->bone)
|
if (!self->bone)
|
||||||
(EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
"couldn't get attribute from a NULL bone"));
|
"couldn't get attribute from a NULL bone"));
|
||||||
|
|
||||||
if (!PyArg_ParseTuple (args, "f", &weight))
|
if (!PyArg_ParseTuple (args, "f", &weight))
|
||||||
@@ -753,7 +765,7 @@ Bone_clearParent(BPy_Bone *self)
|
|||||||
float M_boneObjectspace[4][4];
|
float M_boneObjectspace[4][4];
|
||||||
|
|
||||||
if (!self->bone)
|
if (!self->bone)
|
||||||
(EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
|
||||||
|
|
||||||
if(self->bone->parent == NULL)
|
if(self->bone->parent == NULL)
|
||||||
return EXPP_incr_ret(Py_None);
|
return EXPP_incr_ret(Py_None);
|
||||||
@@ -810,46 +822,43 @@ Bone_clearParent(BPy_Bone *self)
|
|||||||
static PyObject *
|
static PyObject *
|
||||||
Bone_clearChildren(BPy_Bone *self)
|
Bone_clearChildren(BPy_Bone *self)
|
||||||
{
|
{
|
||||||
|
Bone *root = NULL;
|
||||||
Bone *child = NULL;
|
Bone *child = NULL;
|
||||||
bArmature *arm = NULL;
|
bArmature *arm = NULL;
|
||||||
Bone *bone = NULL;
|
Bone *bone = NULL;
|
||||||
Bone *parent = NULL;
|
|
||||||
Bone *prev = NULL;
|
Bone *prev = NULL;
|
||||||
Bone *next = NULL;
|
Bone *next = NULL;
|
||||||
float M_boneObjectspace[4][4];
|
float M_boneObjectspace[4][4];
|
||||||
int first;
|
int first;
|
||||||
|
|
||||||
if (!self->bone)
|
if (!self->bone)
|
||||||
(EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
|
||||||
|
|
||||||
if(self->bone->childbase.first == NULL)
|
if(self->bone->childbase.first == NULL)
|
||||||
return EXPP_incr_ret(Py_None);
|
return EXPP_incr_ret(Py_None);
|
||||||
|
|
||||||
//get the root bone
|
//is this bone a part of an armature....
|
||||||
parent = bone->parent;
|
//get root bone for testing
|
||||||
|
root = self->bone->parent;
|
||||||
if(parent != NULL){
|
if(root != NULL){
|
||||||
while(parent->parent != NULL){
|
while (root->parent != NULL){
|
||||||
parent = parent->parent;
|
root = root->parent;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
parent = bone;
|
root = self->bone;
|
||||||
}
|
}
|
||||||
|
//test armatures for root bone
|
||||||
//get the armature
|
for(arm= G.main->armature.first; arm; arm = arm->id.next){
|
||||||
for (arm = G.main->armature.first; arm; arm = arm->id.next) {
|
for(bone = arm->bonebase.first; bone; bone = bone->next){
|
||||||
for(bone = arm->bonebase.first; bone; bone = bone->next){
|
if(bone == root)
|
||||||
if(parent == bone){
|
break;
|
||||||
//we found the correct armature
|
}
|
||||||
goto gotArmature;
|
if(bone == root)
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gotArmature:
|
|
||||||
|
|
||||||
if(arm == NULL)
|
if(arm == NULL)
|
||||||
(EXPP_ReturnPyObjError (PyExc_RuntimeError, "couldn't find armature that contains this bone"));
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "couldn't find armature that contains this bone"));
|
||||||
|
|
||||||
//now get rid of the parent transformation
|
//now get rid of the parent transformation
|
||||||
get_objectspace_bone_matrix(self->bone, M_boneObjectspace, 0,0);
|
get_objectspace_bone_matrix(self->bone, M_boneObjectspace, 0,0);
|
||||||
@@ -888,7 +897,7 @@ static PyObject *
|
|||||||
Bone_hide(BPy_Bone *self)
|
Bone_hide(BPy_Bone *self)
|
||||||
{
|
{
|
||||||
if (!self->bone)
|
if (!self->bone)
|
||||||
(EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
|
||||||
|
|
||||||
if(!(self->bone->flag & BONE_HIDDEN))
|
if(!(self->bone->flag & BONE_HIDDEN))
|
||||||
self->bone->flag |= BONE_HIDDEN;
|
self->bone->flag |= BONE_HIDDEN;
|
||||||
@@ -902,7 +911,7 @@ static PyObject *
|
|||||||
Bone_unhide(BPy_Bone *self)
|
Bone_unhide(BPy_Bone *self)
|
||||||
{
|
{
|
||||||
if (!self->bone)
|
if (!self->bone)
|
||||||
(EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
|
||||||
|
|
||||||
if(self->bone->flag & BONE_HIDDEN)
|
if(self->bone->flag & BONE_HIDDEN)
|
||||||
self->bone->flag &= ~BONE_HIDDEN;
|
self->bone->flag &= ~BONE_HIDDEN;
|
||||||
@@ -912,7 +921,144 @@ Bone_unhide(BPy_Bone *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
Bone_setPose (BPy_Bone *self, PyObject *args)
|
||||||
|
{
|
||||||
|
Bone *root = NULL;
|
||||||
|
bPoseChannel *chan = NULL;
|
||||||
|
bPoseChannel *setChan = NULL;
|
||||||
|
bPoseChannel *test = NULL;
|
||||||
|
Object *object =NULL;
|
||||||
|
bArmature *arm = NULL;
|
||||||
|
Bone *bone = NULL;
|
||||||
|
PyObject *flaglist = NULL;
|
||||||
|
PyObject *item = NULL;
|
||||||
|
BPy_Action *py_action = NULL;
|
||||||
|
int x;
|
||||||
|
int flagValue = 0;
|
||||||
|
int makeCurve = 1;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple (args, "O!|O!", &PyList_Type, &flaglist, &Action_Type, &py_action))
|
||||||
|
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
|
||||||
|
"expected list of flags and optional action"));
|
||||||
|
|
||||||
|
for(x = 0; x < PyList_Size(flaglist); x++){
|
||||||
|
item = PyList_GetItem(flaglist, x);
|
||||||
|
if(PyInt_Check(item)){
|
||||||
|
flagValue |= PyInt_AsLong(item);
|
||||||
|
}else{
|
||||||
|
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
|
||||||
|
"expected list of flags (ints)"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//is this bone a part of an armature....
|
||||||
|
//get root bone for testing
|
||||||
|
root = self->bone->parent;
|
||||||
|
if(root != NULL){
|
||||||
|
while (root->parent != NULL){
|
||||||
|
root = root->parent;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
root = self->bone;
|
||||||
|
}
|
||||||
|
//test armatures for root bone
|
||||||
|
for(arm= G.main->armature.first; arm; arm = arm->id.next){
|
||||||
|
for(bone = arm->bonebase.first; bone; bone = bone->next){
|
||||||
|
if(bone == root)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(bone == root)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(arm == NULL)
|
||||||
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"bone must belong to an armature to set it's pose!"));
|
||||||
|
|
||||||
|
//find if armature is object linked....
|
||||||
|
for(object = G.main->object.first; object; object = object->id.next){
|
||||||
|
if(object->data == arm){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(object == NULL)
|
||||||
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"armature must be linked to an object to set a pose!"));
|
||||||
|
|
||||||
|
//set the active action as this one
|
||||||
|
if(py_action !=NULL){
|
||||||
|
if(py_action->action != NULL){
|
||||||
|
object->action = py_action->action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if object doesn't have a pose create one
|
||||||
|
if (!object->pose)
|
||||||
|
object->pose = MEM_callocN(sizeof(bPose), "Pose");
|
||||||
|
|
||||||
|
//if bone does have a channel create one
|
||||||
|
verify_pose_channel(object->pose, self->bone->name);
|
||||||
|
|
||||||
|
//create temp Pose Channel
|
||||||
|
chan = MEM_callocN(sizeof(bPoseChannel), "PoseChannel");
|
||||||
|
//set the variables for this pose
|
||||||
|
memcpy (chan->loc, self->bone->loc, sizeof (chan->loc));
|
||||||
|
memcpy (chan->quat, self->bone->quat, sizeof (chan->quat));
|
||||||
|
memcpy (chan->size, self->bone->size, sizeof (chan->size));
|
||||||
|
strcpy (chan->name, self->bone->name);
|
||||||
|
chan->flag |= flagValue;
|
||||||
|
|
||||||
|
//set it to the channel
|
||||||
|
setChan = set_pose_channel(object->pose, chan);
|
||||||
|
|
||||||
|
//frees unlinked pose/bone channels from object
|
||||||
|
collect_pose_garbage(object);
|
||||||
|
|
||||||
|
//create an action if one not already assigned to object
|
||||||
|
if (!py_action && !object->action){
|
||||||
|
object->action = (bAction*)add_empty_action();
|
||||||
|
object->ipowin= ID_AC;
|
||||||
|
}else{
|
||||||
|
//test if posechannel is already in action
|
||||||
|
for(test = object->action->chanbase.first; test; test = test->next){
|
||||||
|
if(test == setChan)
|
||||||
|
makeCurve = 0; //already there
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//set posekey flag
|
||||||
|
filter_pose_keys ();
|
||||||
|
|
||||||
|
//set action keys
|
||||||
|
if (setChan->flag & POSE_ROT){
|
||||||
|
set_action_key(object->action, setChan, AC_QUAT_X, makeCurve);
|
||||||
|
set_action_key(object->action, setChan, AC_QUAT_Y, makeCurve);
|
||||||
|
set_action_key(object->action, setChan, AC_QUAT_Z, makeCurve);
|
||||||
|
set_action_key(object->action, setChan, AC_QUAT_W, makeCurve);
|
||||||
|
}
|
||||||
|
if (setChan->flag & POSE_SIZE){
|
||||||
|
set_action_key(object->action, setChan, AC_SIZE_X, makeCurve);
|
||||||
|
set_action_key(object->action, setChan, AC_SIZE_Y, makeCurve);
|
||||||
|
set_action_key(object->action, setChan, AC_SIZE_Z, makeCurve);
|
||||||
|
}
|
||||||
|
if (setChan->flag & POSE_LOC){
|
||||||
|
set_action_key(object->action, setChan, AC_LOC_X, makeCurve);
|
||||||
|
set_action_key(object->action, setChan, AC_LOC_Y, makeCurve);
|
||||||
|
set_action_key(object->action, setChan, AC_LOC_Z, makeCurve);
|
||||||
|
}
|
||||||
|
|
||||||
|
//rebuild ipos
|
||||||
|
remake_action_ipos(object->action);
|
||||||
|
|
||||||
|
//rebuild displists
|
||||||
|
rebuild_all_armature_displists();
|
||||||
|
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Function: Bone_dealloc */
|
/* Function: Bone_dealloc */
|
||||||
/* Description: This is a callback function for the BPy_Bone type. It is */
|
/* Description: This is a callback function for the BPy_Bone type. It is */
|
||||||
|
|||||||
@@ -33,20 +33,16 @@
|
|||||||
#define EXPP_BONE_H
|
#define EXPP_BONE_H
|
||||||
|
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
|
||||||
#include <DNA_armature_types.h>
|
#include <DNA_armature_types.h>
|
||||||
|
|
||||||
/** Bone module initialization function. */
|
/** Bone module initialization function. */
|
||||||
PyObject *Bone_Init (void);
|
PyObject *Bone_Init (void);
|
||||||
|
|
||||||
|
|
||||||
/** Python BPy_Bone structure definition. */
|
/** Python BPy_Bone structure definition. */
|
||||||
typedef struct
|
typedef struct{
|
||||||
{
|
PyObject_HEAD
|
||||||
PyObject_HEAD Bone *bone;
|
Bone *bone;
|
||||||
}
|
}BPy_Bone;
|
||||||
BPy_Bone;
|
|
||||||
|
|
||||||
|
|
||||||
PyObject *Bone_CreatePyObject (struct Bone *obj);
|
PyObject *Bone_CreatePyObject (struct Bone *obj);
|
||||||
int Bone_CheckPyObject (PyObject * py_obj);
|
int Bone_CheckPyObject (PyObject * py_obj);
|
||||||
|
|||||||
468
source/blender/python/api2_2x/NLA.c
Normal file
468
source/blender/python/api2_2x/NLA.c
Normal file
@@ -0,0 +1,468 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* ***** 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.
|
||||||
|
*
|
||||||
|
* This is a new part of Blender.
|
||||||
|
*
|
||||||
|
* Contributor(s): Joseph Gilbert
|
||||||
|
*
|
||||||
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "NLA.h"
|
||||||
|
#include "Object.h"
|
||||||
|
#include <BKE_action.h>
|
||||||
|
#include <BKE_global.h>
|
||||||
|
#include <BKE_main.h>
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Python API function prototypes for the NLA module. */
|
||||||
|
/*****************************************************************************/
|
||||||
|
static PyObject *M_NLA_NewAction (PyObject * self, PyObject * args);
|
||||||
|
static PyObject *M_NLA_CopyAction (PyObject * self, PyObject * args);
|
||||||
|
static PyObject *M_NLA_GetActions(PyObject* self);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* The following string definitions are used for documentation strings. */
|
||||||
|
/* In Python these will be written to the console when doing a */
|
||||||
|
/* Blender.Armature.NLA.__doc__ */
|
||||||
|
/*****************************************************************************/
|
||||||
|
char M_NLA_doc[] = "The Blender NLA module -This module provides control over Armature keyframing in Blender.";
|
||||||
|
char M_NLA_NewAction_doc[] = "(name) - Create new action for linking to an object.";
|
||||||
|
char M_NLA_CopyAction_doc[] = "(name) - Copy action and return copy.";
|
||||||
|
char M_NLA_GetActions_doc[] = "(name) - Returns a dictionary of actions.";
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Python method structure definition for Blender.Armature.NLA module: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
struct PyMethodDef M_NLA_methods[] = {
|
||||||
|
{"NewAction", (PyCFunction) M_NLA_NewAction, METH_VARARGS,
|
||||||
|
M_NLA_NewAction_doc},
|
||||||
|
{"CopyAction", (PyCFunction) M_NLA_CopyAction, METH_VARARGS,
|
||||||
|
M_NLA_CopyAction_doc},
|
||||||
|
{"GetActions", (PyCFunction) M_NLA_GetActions, METH_NOARGS,
|
||||||
|
M_NLA_GetActions_doc},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Python BPy_Action methods declarations: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
static PyObject *Action_getName (BPy_Action * self);
|
||||||
|
static PyObject *Action_setName (BPy_Action * self, PyObject * args);
|
||||||
|
static PyObject *Action_setActive (BPy_Action * self, PyObject * args);
|
||||||
|
static PyObject *Action_getChannelIpo(BPy_Action * self, PyObject * args);
|
||||||
|
static PyObject *Action_removeChannel(BPy_Action * self, PyObject * args);
|
||||||
|
static PyObject *Action_getAllChannelIpos(BPy_Action*self);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Python BPy_Action methods table: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
static PyMethodDef BPy_Action_methods[] = {
|
||||||
|
/* name, method, flags, doc */
|
||||||
|
{"getName", (PyCFunction) Action_getName, METH_NOARGS,
|
||||||
|
"() - return Action name"},
|
||||||
|
{"setName", (PyCFunction) Action_setName, METH_VARARGS,
|
||||||
|
"(str) - rename Action"},
|
||||||
|
{"setActive", (PyCFunction) Action_setActive, METH_VARARGS,
|
||||||
|
"(str) -set this action as the active action for an object"},
|
||||||
|
{"getChannelIpo", (PyCFunction) Action_getChannelIpo, METH_VARARGS,
|
||||||
|
"(str) -get the Ipo from a named action channel in this action"},
|
||||||
|
{"removeChannel", (PyCFunction) Action_removeChannel, METH_VARARGS,
|
||||||
|
"(str) -remove the channel from the action"},
|
||||||
|
{"getAllChannelIpos", (PyCFunction)Action_getAllChannelIpos, METH_NOARGS,
|
||||||
|
"() - Return a dict of (name:ipo)-keys containing each channel in the object's action"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Python TypeAction callback function prototypes: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
static void Action_dealloc (BPy_Action * bone);
|
||||||
|
static PyObject *Action_getAttr (BPy_Action * bone, char *name);
|
||||||
|
static int Action_setAttr (BPy_Action * bone, char *name, PyObject * v);
|
||||||
|
static PyObject *Action_repr (BPy_Action * bone);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Python TypeAction structure definition: */
|
||||||
|
/*****************************************************************************/
|
||||||
|
PyTypeObject Action_Type = {
|
||||||
|
PyObject_HEAD_INIT (NULL) 0, /* ob_size */
|
||||||
|
"Blender Action", /* tp_name */
|
||||||
|
sizeof (BPy_Action), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
/* methods */
|
||||||
|
(destructor) Action_dealloc, /* tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
(getattrfunc) Action_getAttr, /* tp_getattr */
|
||||||
|
(setattrfunc) Action_setAttr, /* tp_setattr */
|
||||||
|
0, /* tp_compare */
|
||||||
|
(reprfunc) Action_repr, /* tp_repr */
|
||||||
|
0, /* tp_as_number */
|
||||||
|
0, /* tp_as_sequence */
|
||||||
|
0, /* tp_as_mapping */
|
||||||
|
0, /* tp_as_hash */
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
0, /* tp_doc */
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
BPy_Action_methods, /* tp_methods */
|
||||||
|
0, /* tp_members */
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
static PyObject *
|
||||||
|
M_NLA_NewAction (PyObject * self, PyObject * args)
|
||||||
|
{
|
||||||
|
char *name_str = "DefaultAction";
|
||||||
|
BPy_Action *py_action = NULL; /* for Action Data object wrapper in Python */
|
||||||
|
bAction *bl_action = NULL; /* for actual Action Data we create in Blender */
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple (args, "|s", &name_str)){
|
||||||
|
EXPP_ReturnPyObjError (PyExc_AttributeError,
|
||||||
|
"expected string or nothing");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create new action globally
|
||||||
|
bl_action = alloc_libblock(&G.main->action, ID_AC, name_str);
|
||||||
|
bl_action->id.flag |= LIB_FAKEUSER;
|
||||||
|
bl_action->id.us++;
|
||||||
|
|
||||||
|
// now create the wrapper obj in Python
|
||||||
|
if (bl_action)
|
||||||
|
py_action = (BPy_Action *) PyObject_NEW (BPy_Action, &Action_Type);
|
||||||
|
else{
|
||||||
|
EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"couldn't create Action Data in Blender");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (py_action == NULL){
|
||||||
|
EXPP_ReturnPyObjError (PyExc_MemoryError,
|
||||||
|
"couldn't create Action Data object");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
py_action->action = bl_action; // link Python action wrapper with Blender Action
|
||||||
|
|
||||||
|
Py_INCREF(py_action);
|
||||||
|
return (PyObject *) py_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
M_NLA_CopyAction(PyObject* self, PyObject * args)
|
||||||
|
{
|
||||||
|
BPy_Action *py_action = NULL;
|
||||||
|
bAction *copyAction = NULL;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple (args, "O!", &Action_Type, &py_action)){
|
||||||
|
EXPP_ReturnPyObjError (PyExc_AttributeError,
|
||||||
|
"expected python action type");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
copyAction = copy_action(py_action->action);
|
||||||
|
return Action_CreatePyObject (copyAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
M_NLA_GetActions(PyObject* self)
|
||||||
|
{
|
||||||
|
PyObject *dict=PyDict_New ();
|
||||||
|
bAction *action = NULL;
|
||||||
|
|
||||||
|
for(action = G.main->action.first; action; action = action->id.next){
|
||||||
|
PyObject * py_action = Action_CreatePyObject (action);
|
||||||
|
if (py_action) {
|
||||||
|
// Insert dict entry using the bone name as key
|
||||||
|
if (PyDict_SetItemString (dict, action->id.name + 2, py_action) !=0) {
|
||||||
|
Py_DECREF (py_action);
|
||||||
|
Py_DECREF ( dict );
|
||||||
|
|
||||||
|
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"NLA_GetActions: couldn't set dict item");
|
||||||
|
}
|
||||||
|
Py_DECREF (py_action);
|
||||||
|
} else {
|
||||||
|
Py_DECREF ( dict );
|
||||||
|
return (PythonReturnErrorObject (PyExc_RuntimeError,
|
||||||
|
"NLA_GetActions: could not create Action object"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Function: NLA_Init */
|
||||||
|
/*****************************************************************************/
|
||||||
|
PyObject *
|
||||||
|
NLA_Init (void)
|
||||||
|
{
|
||||||
|
PyObject *submodule;
|
||||||
|
|
||||||
|
Action_Type.ob_type = &PyType_Type;
|
||||||
|
|
||||||
|
submodule = Py_InitModule3 ("Blender.Armature.NLA",
|
||||||
|
M_NLA_methods, M_NLA_doc);
|
||||||
|
|
||||||
|
return (submodule);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
static PyObject *
|
||||||
|
Action_getName (BPy_Action * self)
|
||||||
|
{
|
||||||
|
PyObject *attr = NULL;
|
||||||
|
|
||||||
|
if (!self->action)
|
||||||
|
(EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"couldn't get attribute from a NULL action"));
|
||||||
|
|
||||||
|
attr = PyString_FromString (self->action->id.name+2);
|
||||||
|
|
||||||
|
if (attr)
|
||||||
|
return attr;
|
||||||
|
|
||||||
|
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"couldn't get Action.name attribute"));
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
static PyObject *
|
||||||
|
Action_setName (BPy_Action * self, PyObject * args)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
if (!self->action)
|
||||||
|
(EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"couldn't get attribute from a NULL action"));
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple (args, "s", &name))
|
||||||
|
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
|
||||||
|
"expected string argument"));
|
||||||
|
|
||||||
|
//change name
|
||||||
|
strcpy(self->action->id.name+2, name);
|
||||||
|
|
||||||
|
Py_INCREF (Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
Action_setActive(BPy_Action * self, PyObject * args)
|
||||||
|
{
|
||||||
|
BPy_Object *object;
|
||||||
|
|
||||||
|
if (!self->action)
|
||||||
|
(EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"couldn't get attribute from a NULL action"));
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple (args, "O!", &Object_Type, &object))
|
||||||
|
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
|
||||||
|
"expected python object argument"));
|
||||||
|
|
||||||
|
if(object->object->type != OB_ARMATURE) {
|
||||||
|
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
|
||||||
|
"object not of type armature"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//set the active action to object
|
||||||
|
object->object->action = self->action;
|
||||||
|
|
||||||
|
Py_INCREF (Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
Action_getChannelIpo(BPy_Action * self, PyObject * args)
|
||||||
|
{
|
||||||
|
char *chanName;
|
||||||
|
bActionChannel *chan;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTuple(args, "s", &chanName)){
|
||||||
|
EXPP_ReturnPyObjError(PyExc_AttributeError, "string expected");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
chan = get_named_actionchannel(self->action,chanName);
|
||||||
|
if(chan == NULL){
|
||||||
|
EXPP_ReturnPyObjError(PyExc_AttributeError, "no channel with that name...");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//return IPO
|
||||||
|
return Ipo_CreatePyObject (chan->ipo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
Action_removeChannel(BPy_Action * self, PyObject * args)
|
||||||
|
{
|
||||||
|
char *chanName;
|
||||||
|
bActionChannel *chan;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTuple(args, "s", &chanName)){
|
||||||
|
EXPP_ReturnPyObjError(PyExc_AttributeError, "string expected");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
chan = get_named_actionchannel(self->action,chanName);
|
||||||
|
if(chan == NULL){
|
||||||
|
EXPP_ReturnPyObjError(PyExc_AttributeError, "no channel with that name...");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//release ipo
|
||||||
|
if(chan->ipo)
|
||||||
|
chan->ipo->id.us--;
|
||||||
|
|
||||||
|
//remove channel
|
||||||
|
BLI_freelinkN (&self->action->chanbase, chan);
|
||||||
|
|
||||||
|
Py_INCREF (Py_None);
|
||||||
|
return (Py_None);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *Action_getAllChannelIpos (BPy_Action *self)
|
||||||
|
{
|
||||||
|
PyObject *dict=PyDict_New ();
|
||||||
|
bActionChannel *chan = NULL;
|
||||||
|
|
||||||
|
for(chan = self->action->chanbase.first; chan; chan = chan->next){
|
||||||
|
PyObject * ipo_attr = Ipo_CreatePyObject (chan->ipo);
|
||||||
|
if (ipo_attr) {
|
||||||
|
// Insert dict entry using the bone name as key
|
||||||
|
if (PyDict_SetItemString (dict, chan->name, ipo_attr) !=0) {
|
||||||
|
Py_DECREF ( ipo_attr );
|
||||||
|
Py_DECREF ( dict );
|
||||||
|
|
||||||
|
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"Action_getAllChannelIpos: couldn't set dict item");
|
||||||
|
}
|
||||||
|
Py_DECREF (ipo_attr);
|
||||||
|
} else {
|
||||||
|
Py_DECREF ( dict );
|
||||||
|
return (PythonReturnErrorObject (PyExc_RuntimeError,
|
||||||
|
"Action_getAllChannelIpos: could not create Ipo object"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
static void
|
||||||
|
Action_dealloc (BPy_Action * self)
|
||||||
|
{
|
||||||
|
PyObject_DEL (self);
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
static PyObject *
|
||||||
|
Action_getAttr (BPy_Action * self, char *name)
|
||||||
|
{
|
||||||
|
PyObject *attr = Py_None;
|
||||||
|
|
||||||
|
if (strcmp (name, "name") == 0)
|
||||||
|
attr = Action_getName (self);
|
||||||
|
else if (strcmp (name, "__members__") == 0) {
|
||||||
|
attr = Py_BuildValue ("[s]",
|
||||||
|
"name");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attr)
|
||||||
|
return (EXPP_ReturnPyObjError (PyExc_MemoryError,
|
||||||
|
"couldn't create PyObject"));
|
||||||
|
|
||||||
|
if (attr != Py_None)
|
||||||
|
return attr; /* member attribute found, return it */
|
||||||
|
|
||||||
|
/* not an attribute, search the methods table */
|
||||||
|
return Py_FindMethod (BPy_Action_methods, (PyObject *) self, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
static int
|
||||||
|
Action_setAttr (BPy_Action * self, char *name, PyObject * value)
|
||||||
|
{
|
||||||
|
PyObject *valtuple;
|
||||||
|
PyObject *error = NULL;
|
||||||
|
|
||||||
|
valtuple = Py_BuildValue ("(O)", value); /* the set* functions expect a tuple */
|
||||||
|
|
||||||
|
if (!valtuple)
|
||||||
|
return EXPP_ReturnIntError (PyExc_MemoryError,
|
||||||
|
"ActionSetAttr: couldn't create tuple");
|
||||||
|
|
||||||
|
if (strcmp (name, "name") == 0)
|
||||||
|
error = Action_setName (self, valtuple);
|
||||||
|
else
|
||||||
|
{ /* Error */
|
||||||
|
Py_DECREF (valtuple);
|
||||||
|
|
||||||
|
/* ... member with the given name was found */
|
||||||
|
return (EXPP_ReturnIntError (PyExc_KeyError, "attribute not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF (valtuple);
|
||||||
|
|
||||||
|
if (error != Py_None)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
Py_DECREF (Py_None); /* was incref'ed by the called Action_set* function */
|
||||||
|
return 0; /* normal exit */
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
static PyObject *
|
||||||
|
Action_repr (BPy_Action * self)
|
||||||
|
{
|
||||||
|
if (self->action)
|
||||||
|
return PyString_FromFormat ("[Action \"%s\"]", self->action->id.name + 2);
|
||||||
|
else
|
||||||
|
return PyString_FromString ("NULL");
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
PyObject *
|
||||||
|
Action_CreatePyObject (struct bAction * act)
|
||||||
|
{
|
||||||
|
BPy_Action *blen_action;
|
||||||
|
|
||||||
|
blen_action = (BPy_Action *) PyObject_NEW (BPy_Action, &Action_Type);
|
||||||
|
|
||||||
|
if (blen_action == NULL)
|
||||||
|
{
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
blen_action->action = act;
|
||||||
|
return ((PyObject *) blen_action);
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
Action_CheckPyObject (PyObject * py_obj)
|
||||||
|
{
|
||||||
|
return (py_obj->ob_type == &Action_Type);
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
struct bAction *
|
||||||
|
Action_FromPyObject (PyObject * py_obj)
|
||||||
|
{
|
||||||
|
BPy_Action *blen_obj;
|
||||||
|
|
||||||
|
blen_obj = (BPy_Action *) py_obj;
|
||||||
|
return (blen_obj->action);
|
||||||
|
}
|
||||||
53
source/blender/python/api2_2x/NLA.h
Normal file
53
source/blender/python/api2_2x/NLA.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* ***** 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.
|
||||||
|
*
|
||||||
|
* This is a new part of Blender.
|
||||||
|
*
|
||||||
|
* Contributor(s): Joseph Gilbert
|
||||||
|
*
|
||||||
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXPP_NLA_H
|
||||||
|
#define EXPP_NLA_H
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
#include <DNA_action_types.h>
|
||||||
|
|
||||||
|
/** NLA module initialization function. */
|
||||||
|
PyObject *NLA_Init (void);
|
||||||
|
|
||||||
|
/** Python BPy_NLA structure definition. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PyObject_HEAD
|
||||||
|
bAction *action;
|
||||||
|
}
|
||||||
|
BPy_Action;
|
||||||
|
|
||||||
|
PyObject *Action_CreatePyObject (struct bAction *action);
|
||||||
|
int Action_CheckPyObject (PyObject * py_obj);
|
||||||
|
bAction *Action_FromPyObject (PyObject * py_obj);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
#include "NLA.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Python API function prototypes for the Blender module. */
|
/* Python API function prototypes for the Blender module. */
|
||||||
@@ -89,7 +90,6 @@ struct PyMethodDef M_Object_methods[] = {
|
|||||||
static PyObject *Object_buildParts (BPy_Object *self);
|
static PyObject *Object_buildParts (BPy_Object *self);
|
||||||
static PyObject *Object_clearIpo (BPy_Object *self);
|
static PyObject *Object_clearIpo (BPy_Object *self);
|
||||||
static PyObject *Object_clrParent (BPy_Object *self, PyObject *args);
|
static PyObject *Object_clrParent (BPy_Object *self, PyObject *args);
|
||||||
static PyObject *Object_getActionIpos (BPy_Object *self);
|
|
||||||
static PyObject *Object_getData (BPy_Object *self);
|
static PyObject *Object_getData (BPy_Object *self);
|
||||||
static PyObject *Object_getDeltaLocation (BPy_Object *self);
|
static PyObject *Object_getDeltaLocation (BPy_Object *self);
|
||||||
static PyObject *Object_getDrawMode (BPy_Object *self);
|
static PyObject *Object_getDrawMode (BPy_Object *self);
|
||||||
@@ -107,6 +107,7 @@ static PyObject *Object_getTimeOffset (BPy_Object *self);
|
|||||||
static PyObject *Object_getTracked (BPy_Object *self);
|
static PyObject *Object_getTracked (BPy_Object *self);
|
||||||
static PyObject *Object_getType (BPy_Object *self);
|
static PyObject *Object_getType (BPy_Object *self);
|
||||||
static PyObject *Object_getBoundBox (BPy_Object *self);
|
static PyObject *Object_getBoundBox (BPy_Object *self);
|
||||||
|
static PyObject *Object_getAction (BPy_Object *self);
|
||||||
static PyObject *Object_makeDisplayList (BPy_Object *self);
|
static PyObject *Object_makeDisplayList (BPy_Object *self);
|
||||||
static PyObject *Object_link (BPy_Object *self, PyObject *args);
|
static PyObject *Object_link (BPy_Object *self, PyObject *args);
|
||||||
static PyObject *Object_makeParent (BPy_Object *self, PyObject *args);
|
static PyObject *Object_makeParent (BPy_Object *self, PyObject *args);
|
||||||
@@ -137,8 +138,6 @@ static PyMethodDef BPy_Object_methods[] = {
|
|||||||
"Clears parent object. Optionally specify:\n\
|
"Clears parent object. Optionally specify:\n\
|
||||||
mode\n\t2: Keep object transform\nfast\n\t>0: Don't update scene \
|
mode\n\t2: Keep object transform\nfast\n\t>0: Don't update scene \
|
||||||
hierarchy (faster)"},
|
hierarchy (faster)"},
|
||||||
{"getActionIpos", (PyCFunction)Object_getActionIpos, METH_NOARGS,
|
|
||||||
"() - Return a dict of (name:ipo)-keys containing each channel in the object's action"},
|
|
||||||
{"getData", (PyCFunction)Object_getData, METH_NOARGS,
|
{"getData", (PyCFunction)Object_getData, METH_NOARGS,
|
||||||
"Returns the datablock object containing the object's data, e.g. Mesh"},
|
"Returns the datablock object containing the object's data, e.g. Mesh"},
|
||||||
{"getDeltaLocation", (PyCFunction)Object_getDeltaLocation, METH_NOARGS,
|
{"getDeltaLocation", (PyCFunction)Object_getDeltaLocation, METH_NOARGS,
|
||||||
@@ -147,6 +146,8 @@ hierarchy (faster)"},
|
|||||||
"Returns the object draw modes"},
|
"Returns the object draw modes"},
|
||||||
{"getDrawType", (PyCFunction)Object_getDrawType, METH_NOARGS,
|
{"getDrawType", (PyCFunction)Object_getDrawType, METH_NOARGS,
|
||||||
"Returns the object draw type"},
|
"Returns the object draw type"},
|
||||||
|
{"getAction", (PyCFunction)Object_getAction, METH_NOARGS,
|
||||||
|
"Returns the active action for this object"},
|
||||||
{"getEuler", (PyCFunction)Object_getEuler, METH_NOARGS,
|
{"getEuler", (PyCFunction)Object_getEuler, METH_NOARGS,
|
||||||
"Returns the object's rotation as Euler rotation vector\n\
|
"Returns the object's rotation as Euler rotation vector\n\
|
||||||
(rotX, rotY, rotZ)"},
|
(rotX, rotY, rotZ)"},
|
||||||
@@ -645,59 +646,6 @@ int EXPP_add_obdata(struct Object *object)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *Object_getActionIpos (BPy_Object *self)
|
|
||||||
{
|
|
||||||
Object *obj=self->object;
|
|
||||||
PyObject *dict=PyDict_New ();
|
|
||||||
bAction *action = NULL;
|
|
||||||
bActionChannel *bone = NULL;
|
|
||||||
|
|
||||||
if (obj->type==OB_ARMATURE) {
|
|
||||||
|
|
||||||
if (obj->action!=0) {
|
|
||||||
|
|
||||||
action = obj->action;
|
|
||||||
bone = (bActionChannel*)(action->chanbase.first);
|
|
||||||
|
|
||||||
// Go through the list of bones
|
|
||||||
while (bone!=0) {
|
|
||||||
|
|
||||||
// Does this bone have an ipo?
|
|
||||||
if (bone->ipo!=0) {
|
|
||||||
|
|
||||||
PyObject *ipo_attr=Ipo_CreatePyObject (bone->ipo);
|
|
||||||
|
|
||||||
if (ipo_attr) {
|
|
||||||
|
|
||||||
// Insert dict entry using the bone name as key
|
|
||||||
if (PyDict_SetItemString (dict, bone->name, ipo_attr)!=0) {
|
|
||||||
Py_DECREF ( ipo_attr );
|
|
||||||
Py_DECREF ( dict );
|
|
||||||
|
|
||||||
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
|
||||||
"Object_getActionIpos: couldn't set dict item");
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_DECREF (ipo_attr);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Py_DECREF ( dict );
|
|
||||||
|
|
||||||
return (PythonReturnErrorObject (PyExc_RuntimeError,
|
|
||||||
"Object_getActionIpos: could not create Ipo object"));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bone=bone->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static PyObject *Object_getData (BPy_Object *self)
|
static PyObject *Object_getData (BPy_Object *self)
|
||||||
{
|
{
|
||||||
@@ -791,6 +739,18 @@ static PyObject *Object_getDrawMode (BPy_Object *self)
|
|||||||
"couldn't get Object.drawMode attribute"));
|
"couldn't get Object.drawMode attribute"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *Object_getAction (BPy_Object *self)
|
||||||
|
{
|
||||||
|
BPy_Action *py_action = NULL;
|
||||||
|
|
||||||
|
if(!self->object->action){
|
||||||
|
Py_INCREF (Py_None);
|
||||||
|
return (Py_None);
|
||||||
|
}else{
|
||||||
|
return Action_CreatePyObject (self->object->action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *Object_getDrawType (BPy_Object *self)
|
static PyObject *Object_getDrawType (BPy_Object *self)
|
||||||
{
|
{
|
||||||
PyObject *attr = Py_BuildValue ("b", self->object->dt);
|
PyObject *attr = Py_BuildValue ("b", self->object->dt);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ PyObject *Types_Init (void)
|
|||||||
* do it now, we get an easy way to crash Blender. Maybe we'd better
|
* do it now, we get an easy way to crash Blender. Maybe we'd better
|
||||||
* have an Init function for all these internal types that more than one
|
* have an Init function for all these internal types that more than one
|
||||||
* module can use. We could call it after setting the Blender dictionary */
|
* module can use. We could call it after setting the Blender dictionary */
|
||||||
|
Action_Type.ob_type = &PyType_Type;
|
||||||
matrix_Type.ob_type = &PyType_Type;
|
matrix_Type.ob_type = &PyType_Type;
|
||||||
vector_Type.ob_type = &PyType_Type;
|
vector_Type.ob_type = &PyType_Type;
|
||||||
euler_Type.ob_type = &PyType_Type;
|
euler_Type.ob_type = &PyType_Type;
|
||||||
@@ -111,6 +112,7 @@ PyObject *Types_Init (void)
|
|||||||
PyDict_SetItemString(dict, "eulerType", (PyObject *)&euler_Type);
|
PyDict_SetItemString(dict, "eulerType", (PyObject *)&euler_Type);
|
||||||
PyDict_SetItemString(dict, "quaternionType", (PyObject *)&quaternion_Type);
|
PyDict_SetItemString(dict, "quaternionType", (PyObject *)&quaternion_Type);
|
||||||
PyDict_SetItemString(dict, "BezTripleType", (PyObject *)&BezTriple_Type);
|
PyDict_SetItemString(dict, "BezTripleType", (PyObject *)&BezTriple_Type);
|
||||||
|
PyDict_SetItemString(dict, "ActionType", (PyObject *)&Action_Type);
|
||||||
|
|
||||||
return submodule;
|
return submodule;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,5 +50,6 @@ extern PyTypeObject buffer_Type, rgbTuple_Type,
|
|||||||
constant_Type, BezTriple_Type;
|
constant_Type, BezTriple_Type;
|
||||||
|
|
||||||
extern PyTypeObject vector_Type, matrix_Type, euler_Type, quaternion_Type;
|
extern PyTypeObject vector_Type, matrix_Type, euler_Type, quaternion_Type;
|
||||||
|
extern PyTypeObject Action_Type;
|
||||||
|
|
||||||
#endif /* EXPP_TYPES_H */
|
#endif /* EXPP_TYPES_H */
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
#include <DNA_image_types.h>
|
#include <DNA_image_types.h>
|
||||||
#include <DNA_text_types.h>
|
#include <DNA_text_types.h>
|
||||||
#include <DNA_world_types.h>
|
#include <DNA_world_types.h>
|
||||||
|
#include <DNA_action_types.h>
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
@@ -188,6 +189,6 @@ PyObject * Window_Init (void);
|
|||||||
PyObject * Draw_Init (void);
|
PyObject * Draw_Init (void);
|
||||||
PyObject * BGL_Init (void);
|
PyObject * BGL_Init (void);
|
||||||
PyObject * Mathutils_Init (void);
|
PyObject * Mathutils_Init (void);
|
||||||
|
PyObject * NLA_Init (void);
|
||||||
|
|
||||||
#endif /* EXPP_modules_h */
|
#endif /* EXPP_modules_h */
|
||||||
|
|||||||
Reference in New Issue
Block a user