Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Gilbert <ascotan@gmail.com>2004-04-04 12:34:43 +0400
committerJoseph Gilbert <ascotan@gmail.com>2004-04-04 12:34:43 +0400
commit32b0677d96a2cd533e585a4b59e40ae1189d40e2 (patch)
tree66a96564fd7e6ff3b48bbd9248138d75ce21dc0f
parent3b680da036dd53f63fa00075d5a25740487aab09 (diff)
- added support for adding/parenting bones to armatures
- fixed getArmatureIpo compiling error
-rw-r--r--source/blender/python/api2_2x/Armature.c174
-rw-r--r--source/blender/python/api2_2x/Armature.h9
-rw-r--r--source/blender/python/api2_2x/Bone.c61
-rw-r--r--source/blender/python/api2_2x/Object.c15
-rw-r--r--source/blender/python/api2_2x/Object.h1
5 files changed, 189 insertions, 71 deletions
diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c
index 6bc5bd34c54..a5b24bcada5 100644
--- a/source/blender/python/api2_2x/Armature.c
+++ b/source/blender/python/api2_2x/Armature.c
@@ -40,10 +40,12 @@
#include <BKE_armature.h>
#include <BKE_library.h>
#include <BLI_blenlib.h>
+#include <BLI_arithb.h>
#include "constant.h"
#include "gen_utils.h"
#include "modules.h"
+#include "Types.h"
/*****************************************************************************/
/* Python API function prototypes for the Armature module. */
@@ -90,6 +92,7 @@ struct PyMethodDef M_Armature_methods[] = {
/*****************************************************************************/
static PyObject *Armature_getName (BPy_Armature * self);
static PyObject *Armature_getBones (BPy_Armature * self);
+static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args);
static PyObject *Armature_setName (BPy_Armature * self, PyObject * args);
/* static PyObject *Armature_setBones(BPy_Armature *self, PyObject *args); */
@@ -104,6 +107,8 @@ static PyMethodDef BPy_Armature_methods[] = {
"() - return Armature root bones"},
{"setName", (PyCFunction) Armature_setName, METH_VARARGS,
"(str) - rename Armature"},
+ {"addBone", (PyCFunction)Armature_addBone, METH_VARARGS,
+ "(bone)-add bone"},
/* {"setBones", (PyCFunction)Armature_setBones, METH_VARARGS,
"(list of bones) - replace the whole bone list of the armature"},
*/
@@ -120,6 +125,7 @@ static int Armature_setAttr (BPy_Armature * armature, char *name,
static int Armature_compare (BPy_Armature * a1, BPy_Armature * a2);
static PyObject *Armature_repr (BPy_Armature * armature);
+static int doesBoneName_exist(char *name, bArmature* arm);
/*****************************************************************************/
/* Python TypeArmature structure definition: */
/*****************************************************************************/
@@ -154,47 +160,42 @@ PyTypeObject Armature_Type = {
static PyObject *
M_Armature_New (PyObject * self, PyObject * args, PyObject * keywords)
{
- char *type_str = "Armature";
- char *name_str = "ArmatureData";
- static char *kwlist[] = { "type_str", "name_str", NULL };
- BPy_Armature *py_armature; /* for Armature Data object wrapper in Python */
- bArmature *bl_armature; /* for actual Armature Data we create in Blender */
- char buf[21];
+ char *name_str = "ArmatureData";
+ BPy_Armature *py_armature; /* for Armature Data object wrapper in Python */
+ bArmature *bl_armature; /* for actual Armature Data we create in Blender */
+ char buf[21];
- if (!PyArg_ParseTupleAndKeywords (args, keywords, "|ss", kwlist,
- &type_str, &name_str))
+ if (!PyArg_ParseTuple(args, "|s", &name_str))
return (EXPP_ReturnPyObjError (PyExc_AttributeError,
- "expected string(s) or empty argument"));
-
- bl_armature = add_armature (); /* first create in Blender */
- if (bl_armature)
- {
- /* return user count to zero because add_armature() inc'd it */
- bl_armature->id.us = 0;
- /* now create the wrapper obj in Python */
- py_armature =
- (BPy_Armature *) PyObject_NEW (BPy_Armature, &Armature_Type);
- }
+ "expected string or empty argument"));
+
+ bl_armature = add_armature(); /* first create in Blender */
+
+ if (bl_armature){
+ /* return user count to zero because add_armature() inc'd it */
+ bl_armature->id.us = 0;
+ /* now create the wrapper obj in Python */
+ py_armature = (BPy_Armature *)PyObject_NEW(BPy_Armature, &Armature_Type);
+ }
else
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
- "couldn't create Armature Data in Blender"));
+ "couldn't create Armature Data in Blender"));
if (py_armature == NULL)
return (EXPP_ReturnPyObjError (PyExc_MemoryError,
- "couldn't create Armature Data object"));
+ "couldn't create ArmaturePyObject"));
/* link Python armature wrapper with Blender Armature: */
py_armature->armature = bl_armature;
- if (strcmp (name_str, "ArmatureData") == 0)
- return (PyObject *) py_armature;
- else
- { /* user gave us a name for the armature, use it */
- PyOS_snprintf (buf, sizeof (buf), "%s", name_str);
- rename_id (&bl_armature->id, buf);
- }
+ if (strcmp(name_str, "ArmatureData") == 0)
+ return (PyObject *)py_armature;
+ else { /* user gave us a name for the armature, use it */
+ PyOS_snprintf(buf, sizeof(buf), "%s", name_str);
+ rename_id(&bl_armature->id, buf);
+ }
- return (PyObject *) py_armature;
+ return (PyObject *)py_armature;
}
/*****************************************************************************/
@@ -340,6 +341,107 @@ Armature_getBones (BPy_Armature * self)
return listbones;
}
+static void
+unique_BoneName(char *name, bArmature* arm)
+{
+ char tempname[64];
+ int number;
+ char *dot;
+
+ if (doesBoneName_exist(name, arm)){
+ /* Strip off the suffix */
+ dot=strchr(name, '.');
+ if (dot)
+ *dot=0;
+
+ for (number = 1; number <=999; number++){
+ sprintf (tempname, "%s.%03d", name, number);
+ if (!doesBoneName_exist(tempname, arm)){
+ strcpy (name, tempname);
+ return;
+ }
+ }
+ }
+}
+
+static int
+doesBoneName_exist(char *name, bArmature* arm)
+{
+ Bone *parent = NULL;
+ Bone *child = NULL;
+
+ for (parent = arm->bonebase.first; parent; parent = parent->next){
+ if (!strcmp (name, parent->name))
+ return 1;
+ for (child = parent->childbase.first; child; child = child->next){
+ if (!strcmp (name, child->name))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static PyObject *Armature_addBone(BPy_Armature *self, PyObject *args)
+{
+ BPy_Bone* py_bone = NULL;
+ float M_boneObjectspace[4][4];
+ float M_parentRest[4][4];
+ float iM_parentRest[4][4];
+ float delta[3];
+ float rootHead[3];
+ float rootTail[3];
+
+
+ if (!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone))
+ return (EXPP_ReturnPyObjError (PyExc_TypeError,
+ "expected bone object argument (or nothing)"));
+
+ if(py_bone != NULL)
+ if(!py_bone->bone)
+ return (EXPP_ReturnPyObjError (PyExc_TypeError, "bone contains no data!"));
+
+ //make sure the name is unique for this armature
+ unique_BoneName(py_bone->bone->name, self->armature);
+
+ //if bone has a parent....
+ if(py_bone->bone->parent){
+
+ //add to parent's childbase
+ BLI_addtail (&py_bone->bone->parent->childbase, py_bone->bone);
+
+ //get the worldspace coords for the parent
+ get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 1,0);
+ rootHead[0] = M_boneObjectspace[3][0];
+ rootHead[1] = M_boneObjectspace[3][1];
+ rootHead[2] = M_boneObjectspace[3][2];
+ get_objectspace_bone_matrix(py_bone->bone->parent, M_boneObjectspace, 0,0);
+ rootTail[0] = M_boneObjectspace[3][0];
+ rootTail[1] = M_boneObjectspace[3][1];
+ rootTail[2] = M_boneObjectspace[3][2];
+
+ //rest matrix of parent
+ VecSubf (delta, rootTail, rootHead);
+ make_boneMatrixvr(M_parentRest, delta, py_bone->bone->parent->roll);
+
+ // Invert the parent rest matrix
+ Mat4Invert (iM_parentRest, M_parentRest);
+
+ // Get the new head and tail
+ VecSubf (py_bone->bone->head, py_bone->bone->head, rootTail);
+ VecSubf (py_bone->bone->tail, py_bone->bone->tail, rootTail);
+
+ //transformation of local bone
+ Mat4MulVecfl(iM_parentRest, py_bone->bone->head);
+ Mat4MulVecfl(iM_parentRest, py_bone->bone->tail);
+
+ }else //no parent....
+ BLI_addtail (&self->armature->bonebase,py_bone->bone);
+
+ precalc_bonelist_irestmats(&self->armature->bonebase);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
static PyObject *
Armature_setName (BPy_Armature * self, PyObject * args)
@@ -359,19 +461,6 @@ Armature_setName (BPy_Armature * self, PyObject * args)
return Py_None;
}
-
-#if 0
-static PyObject *
-Armature_setBones (BPy_Armature * self, PyObject * args)
-{
- /* TODO: Implement me! */
- printf ("ERROR: Armature_setBones NOT implemented yet!\n");
- Py_INCREF (Py_None);
- return Py_None;
-
-}
-#endif
-
/*****************************************************************************/
/* Function: Armature_dealloc */
/* Description: This is a callback function for the BPy_Armature type. It is */
@@ -498,6 +587,7 @@ Armature_CreatePyObject (struct bArmature * obj)
return (NULL);
}
blen_armature->armature = obj;
+
return ((PyObject *) blen_armature);
}
diff --git a/source/blender/python/api2_2x/Armature.h b/source/blender/python/api2_2x/Armature.h
index f74f9ee6661..7f74f69c9d1 100644
--- a/source/blender/python/api2_2x/Armature.h
+++ b/source/blender/python/api2_2x/Armature.h
@@ -39,10 +39,9 @@
/* Python BPy_Armature structure definition: */
/*****************************************************************************/
-typedef struct
-{
- PyObject_HEAD bArmature * armature;
-}
-BPy_Armature;
+typedef struct {
+ PyObject_HEAD
+ bArmature *armature;
+} BPy_Armature;
#endif /* EXPP_ARMATURE_H */
diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c
index b1d1ddc6446..e5484b738ed 100644
--- a/source/blender/python/api2_2x/Bone.c
+++ b/source/blender/python/api2_2x/Bone.c
@@ -36,6 +36,7 @@
#include <BKE_object.h>
#include <BKE_armature.h>
#include <BKE_library.h>
+#include <MEM_guardedalloc.h>
#include "constant.h"
#include "gen_utils.h"
@@ -92,8 +93,7 @@ static PyObject *Bone_setTail (BPy_Bone * self, PyObject * args);
static PyObject *Bone_setLoc (BPy_Bone * self, PyObject * args);
static PyObject *Bone_setSize (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_setChildren(BPy_Bone *self, PyObject *args); */
+static PyObject *Bone_setParent(BPy_Bone *self, PyObject *args);
/*****************************************************************************/
/* Python BPy_Bone methods table: */
@@ -135,12 +135,8 @@ static PyMethodDef BPy_Bone_methods[] = {
"(float,float,float) - set Bone size"},
{"setQuat", (PyCFunction) Bone_setQuat, METH_VARARGS,
"(float,float,float,float) - set Bone quat"},
-#if 0
- {"setParent", (PyCFunction) Bone_setParent, METH_NOARGS,
+ {"setParent", (PyCFunction)Bone_setParent, METH_VARARGS,
"() - set the Bone parent of this one."},
- {"setChildren", (PyCFunction) Bone_setChildren, METH_NOARGS,
- "() - replace the children list of the bone."},
-#endif
{NULL, NULL, 0, NULL}
};
@@ -184,6 +180,7 @@ PyTypeObject Bone_Type = {
/* Function: M_Bone_New */
/* Python equivalent: Blender.Armature.Bone.New */
/*****************************************************************************/
+
static PyObject *
M_Bone_New (PyObject * self, PyObject * args, PyObject * keywords)
{
@@ -196,10 +193,17 @@ M_Bone_New (PyObject * self, PyObject * args, PyObject * keywords)
"expected string or empty argument"));
/* Create the C structure for the newq bone */
- bl_bone = (Bone *) malloc (sizeof (Bone));
+ bl_bone = (Bone *) MEM_callocN(sizeof (Bone), "bone");
strncpy (bl_bone->name, name_str, sizeof (bl_bone->name));
- if (bl_bone) /* now create the wrapper obj in Python */
+ bl_bone->dist=1.0;
+ bl_bone->weight=1.0;
+ bl_bone->flag=32;
+ bl_bone->parent = NULL;
+ bl_bone->roll = 0.0;
+
+ // now create the wrapper obj in Python
+ if (bl_bone)
py_bone = (BPy_Bone *) PyObject_NEW (BPy_Bone, &Bone_Type);
else
return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
@@ -209,16 +213,9 @@ M_Bone_New (PyObject * self, PyObject * args, PyObject * keywords)
return (EXPP_ReturnPyObjError (PyExc_MemoryError,
"couldn't create Bone Data object"));
- py_bone->bone = bl_bone; /* link Python bone wrapper with Blender Bone */
-
- if (strcmp (name_str, "BoneData") == 0)
- return (PyObject *) py_bone;
- else
- { /* user gave us a name for the bone, use it */
- /* TODO: check that name is not already in use? */
- PyOS_snprintf (bl_bone->name, sizeof (bl_bone->name), "%s", name_str);
- }
-
+ py_bone->bone = bl_bone; // link Python bone wrapper with Blender Bone
+
+ Py_INCREF(py_bone);
return (PyObject *) py_bone;
}
@@ -379,7 +376,6 @@ Bone_getQuat (BPy_Bone * self)
"couldn't get Bone.tail attribute"));
}
-
static PyObject *
Bone_hasParent (BPy_Bone * self)
{
@@ -495,7 +491,6 @@ Bone_setRoll (BPy_Bone * self, PyObject * args)
return Py_None;
}
-
static PyObject *
Bone_setHead (BPy_Bone * self, PyObject * args)
{
@@ -636,6 +631,27 @@ Bone_setQuat (BPy_Bone * self, PyObject * args)
return Py_None;
}
+static PyObject *
+Bone_setParent(BPy_Bone *self, PyObject *args)
+{
+ BPy_Bone* py_bone;
+
+ if (!self->bone)
+ (EXPP_ReturnPyObjError (PyExc_RuntimeError, "bone contains no data!"));
+
+ if (!PyArg_ParseTuple(args, "O", &py_bone))
+ return (EXPP_ReturnPyObjError (PyExc_TypeError, "expected bone object argument"));
+
+ if(!py_bone->bone)
+ return (EXPP_ReturnPyObjError (PyExc_TypeError, "bone contains no data!"));
+
+ //set the parent of self
+ self->bone->parent = py_bone->bone;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
/*****************************************************************************/
/* Function: Bone_dealloc */
/* Description: This is a callback function for the BPy_Bone type. It is */
@@ -644,7 +660,8 @@ Bone_setQuat (BPy_Bone * self, PyObject * args)
static void
Bone_dealloc (BPy_Bone * self)
{
- PyObject_DEL (self);
+ MEM_freeN(self->bone);
+ PyObject_DEL (self);
}
/*****************************************************************************/
diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c
index f5514cf3350..4d2108180ed 100644
--- a/source/blender/python/api2_2x/Object.c
+++ b/source/blender/python/api2_2x/Object.c
@@ -649,13 +649,15 @@ 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) {
- bAction *action=obj->action;
- bActionChannel *bone=(bActionChannel*)(action->chanbase.first);
+ action = obj->action;
+ bone = (bActionChannel*)(action->chanbase.first);
// Go through the list of bones
while (bone!=0) {
@@ -1030,6 +1032,8 @@ static PyObject *Object_link (BPy_Object *self, PyObject *args)
return (PythonReturnErrorObject (PyExc_AttributeError,
"expected an object as argument"));
}
+ if (Armature_CheckPyObject (py_data))
+ data = (void *)Armature_FromPyObject (py_data);
if (Camera_CheckPyObject (py_data))
data = (void *)Camera_FromPyObject (py_data);
if (Lamp_CheckPyObject (py_data))
@@ -1054,6 +1058,13 @@ static PyObject *Object_link (BPy_Object *self, PyObject *args)
switch (obj_id)
{
+ case ID_AR:
+ if (self->object->type != OB_ARMATURE)
+ {
+ return (PythonReturnErrorObject (PyExc_AttributeError,
+ "The 'link' object is incompatible with the base object"));
+ }
+ break;
case ID_CA:
if (self->object->type != OB_CAMERA)
{
diff --git a/source/blender/python/api2_2x/Object.h b/source/blender/python/api2_2x/Object.h
index a0127d503ec..aad0af8ba77 100644
--- a/source/blender/python/api2_2x/Object.h
+++ b/source/blender/python/api2_2x/Object.h
@@ -56,6 +56,7 @@
#include <DNA_scene_types.h>
#include <DNA_userdef_types.h>
#include <DNA_view3d_types.h>
+#include <DNA_action_types.h>
#include "bpy_types.h"
#include "gen_utils.h"