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>2005-12-12 21:46:26 +0300
committerJoseph Gilbert <ascotan@gmail.com>2005-12-12 21:46:26 +0300
commit9ae9527c519716051a26a56c02a9b63af1f827b4 (patch)
treef4ef50f37a681dd2cd4927702ee80d7267eedd91 /source/blender/python/api2_2x/Bone.c
parentd32b100464d3d1778a76ae00354ed5885acd574c (diff)
- Armature/Bone API for python
* this resolves a number of outstanding issues with the armature api and gets this ready for release - add/remove bones possible - rolls work correctly now! - ik'ing to parent should work - flags for tip/root/bone selection - etc.
Diffstat (limited to 'source/blender/python/api2_2x/Bone.c')
-rw-r--r--source/blender/python/api2_2x/Bone.c788
1 files changed, 543 insertions, 245 deletions
diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c
index 2fe7faf3b90..d4f59e67ee5 100644
--- a/source/blender/python/api2_2x/Bone.c
+++ b/source/blender/python/api2_2x/Bone.c
@@ -36,6 +36,11 @@
#include "gen_utils.h"
#include "BKE_armature.h"
#include "Mathutils.h"
+#include "BKE_library.h"
+
+//these must come in this order
+#include "DNA_object_types.h" //1
+#include "BIF_editarmature.h" //2
//------------------------ERROR CODES---------------------------------
//This is here just to make me happy and to have more consistant error strings :)
@@ -43,6 +48,8 @@ static const char sEditBoneError[] = "EditBone (internal) - Error: ";
static const char sEditBoneBadArgs[] = "EditBone (internal) - Bad Arguments: ";
static const char sBoneError[] = "Bone - Error: ";
static const char sBoneBadArgs[] = "Bone - Bad Arguments: ";
+static const char sConstListError[] = "ConstantList - Error: ";
+static const char sConstListBadArgs[] = "ConstantList - Bad Arguments: ";
//----------------------(internal)
//gets the bone->roll (which is a localspace roll) and puts it in parentspace
@@ -68,18 +75,53 @@ double boneRoll_ToArmatureSpace(struct Bone *bone)
}
return roll; //result is in radians
}
-//################## EditBone_Type (internal) ########################
+
+//################## EditBone_Type ########################
/*This type is a wrapper for a tempory bone. This is an 'unparented' bone
*object. The armature->bonebase will be calculated from these temporary
*python tracked objects.*/
-//#####################################################################
+//####################################################
//------------------METHOD IMPLEMENTATIONS-----------------------------
+//-------------------------EditBone.hasParent()
+PyObject *EditBone_hasParent(BPy_EditBone *self)
+{
+ if (self->editbone){
+ if (self->editbone->parent)
+ return EXPP_incr_ret(Py_True);
+ else
+ return EXPP_incr_ret(Py_False);
+ }else{
+ goto AttributeError;
+ }
+
+AttributeError:
+ return EXPP_objError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".hasParent: ", "EditBone must be added to the armature first");
+}
+//-------------------------EditBone.clearParent()
+PyObject *EditBone_clearParent(BPy_EditBone *self)
+{
+ if (self->editbone){
+ if (self->editbone->parent)
+ self->editbone->parent = NULL;
+ return EXPP_incr_ret(Py_None);
+ }else{
+ goto AttributeError;
+ }
+
+AttributeError:
+ return EXPP_objError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".clearParent: ", "EditBone must be added to the armature first");
+}
//------------------ATTRIBUTE IMPLEMENTATION---------------------------
//------------------------EditBone.name (get)
static PyObject *EditBone_getName(BPy_EditBone *self, void *closure)
{
- return PyString_FromString(self->name);
+ if (self->editbone)
+ return PyString_FromString(self->editbone->name);
+ else
+ return PyString_FromString(self->name);
}
//------------------------EditBone.name (set)
//check for char[] overflow here...
@@ -90,7 +132,10 @@ static int EditBone_setName(BPy_EditBone *self, PyObject *value, void *closure)
if (!PyArg_Parse(value, "s", &name))
goto AttributeError;
- BLI_strncpy(self->name, name, 32);
+ if (self->editbone)
+ BLI_strncpy(self->editbone->name, name, 32);
+ else
+ BLI_strncpy(self->name, name, 32);
return 0;
AttributeError:
@@ -100,43 +145,116 @@ AttributeError:
//------------------------EditBone.roll (get)
static PyObject *EditBone_getRoll(BPy_EditBone *self, void *closure)
{
- return Py_BuildValue("{s:O}",
- "ARMATURESPACE", PyFloat_FromDouble((self->roll * (180/Py_PI))));
+ if (self->editbone){
+ return Py_BuildValue("f", PyFloat_FromDouble((self->editbone->roll * (180/Py_PI))));
+ }else{
+ return Py_BuildValue("f", PyFloat_FromDouble((self->roll * (180/Py_PI))));
+ }
}
//------------------------EditBone.roll (set)
static int EditBone_setRoll(BPy_EditBone *self, PyObject *value, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return 1;
+ float roll = 0.0f;
+
+ if (!PyArg_Parse(value, "f", &roll))
+ goto AttributeError;
+
+ if (self->editbone){
+ self->editbone->roll = (float)(roll * (Py_PI/180));
+ }else{
+ self->roll = (float)(roll * (Py_PI/180));
+ }
+ return 0;
+
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".roll: ", "expects a float");
}
//------------------------EditBone.head (get)
static PyObject *EditBone_getHead(BPy_EditBone *self, void *closure)
{
- return Py_BuildValue("{s:O, s:O}",
- "BONESPACE", newVectorObject(self->head, 3, Py_WRAP));;
+ if (self->editbone){
+ return newVectorObject(self->editbone->head, 3, Py_WRAP);
+ }else{
+ return newVectorObject(self->head, 3, Py_NEW);
+ }
}
//------------------------EditBone.head (set)
static int EditBone_setHead(BPy_EditBone *self, PyObject *value, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return 1;
+ VectorObject *vec = NULL;
+ int x;
+
+ if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
+ goto AttributeError;
+ if (vec->size != 3)
+ goto AttributeError2;
+
+ if (self->editbone){
+ for (x = 0; x < 3; x++){
+ self->editbone->head[x] = vec->vec[x];
+ }
+ }else{
+ for (x = 0; x < 3; x++){
+ self->head[x] = vec->vec[x];
+ }
+ }
+ return 0;
+
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".head: ", "expects a Vector Object");
+
+AttributeError2:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".head: ", "Vector Object needs to be (x,y,z)");
}
//------------------------EditBone.tail (get)
static PyObject *EditBone_getTail(BPy_EditBone *self, void *closure)
{
- return Py_BuildValue("{s:O, s:O}",
- "BONESPACE", newVectorObject(self->tail, 3, Py_WRAP));
+ if (self->editbone){
+ return newVectorObject(self->editbone->tail, 3, Py_WRAP);
+ }else{
+ return newVectorObject(self->tail, 3, Py_NEW);
+ }
}
//------------------------EditBone.tail (set)
static int EditBone_setTail(BPy_EditBone *self, PyObject *value, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return 1;
+ VectorObject *vec = NULL;
+ int x;
+
+ if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
+ goto AttributeError;
+ if (vec->size != 3)
+ goto AttributeError2;
+
+ if (self->editbone){
+ for (x = 0; x < 3; x++){
+ self->editbone->tail[x] = vec->vec[x];
+ }
+ }else{
+ for (x = 0; x < 3; x++){
+ self->tail[x] = vec->vec[x];
+ }
+ }
+ return 0;
+
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".tail: ", "expects a Vector Object");
+
+AttributeError2:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".tail: ", "Vector Object needs to be (x,y,z)");
}
//------------------------EditBone.weight (get)
static PyObject *EditBone_getWeight(BPy_EditBone *self, void *closure)
{
- return PyFloat_FromDouble(self->weight);
+ if (self->editbone)
+ return PyFloat_FromDouble(self->editbone->weight);
+ else
+ return PyFloat_FromDouble(self->weight);
}
//------------------------EditBone.weight (set)
static int EditBone_setWeight(BPy_EditBone *self, PyObject *value, void *closure)
@@ -147,7 +265,10 @@ static int EditBone_setWeight(BPy_EditBone *self, PyObject *value, void *closure
goto AttributeError;
CLAMP(weight, 0.0f, 1000.0f);
- self->weight = weight;
+ if (self->editbone)
+ self->editbone->weight = weight;
+ else
+ self->weight = weight;
return 0;
AttributeError:
@@ -157,7 +278,10 @@ AttributeError:
//------------------------EditBone.deform_dist (get)
static PyObject *EditBone_getDeform_dist(BPy_EditBone *self, void *closure)
{
- return PyFloat_FromDouble(self->dist);
+ if (self->editbone)
+ return PyFloat_FromDouble(self->editbone->dist);
+ else
+ return PyFloat_FromDouble(self->dist);
}
//------------------------EditBone.deform_dist (set)
static int EditBone_setDeform_dist(BPy_EditBone *self, PyObject *value, void *closure)
@@ -168,7 +292,10 @@ static int EditBone_setDeform_dist(BPy_EditBone *self, PyObject *value, void *cl
goto AttributeError;
CLAMP(deform, 0.0f, 1000.0f);
- self->dist = deform;
+ if (self->editbone)
+ self->editbone->dist = deform;
+ else
+ self->dist = deform;
return 0;
AttributeError:
@@ -178,7 +305,10 @@ AttributeError:
//------------------------EditBone.subdivisions (get)
static PyObject *EditBone_getSubdivisions(BPy_EditBone *self, void *closure)
{
- return PyInt_FromLong(self->segments);
+ if (self->editbone)
+ return PyInt_FromLong(self->editbone->segments);
+ else
+ return PyInt_FromLong(self->segments);
}
//------------------------EditBone.subdivisions (set)
static int EditBone_setSubdivisions(BPy_EditBone *self, PyObject *value, void *closure)
@@ -189,7 +319,10 @@ static int EditBone_setSubdivisions(BPy_EditBone *self, PyObject *value, void *c
goto AttributeError;
CLAMP(segs, 1, 32);
- self->segments = (short)segs;
+ if (self->editbone)
+ self->editbone->segments = (short)segs;
+ else
+ self->segments = (short)segs;
return 0;
AttributeError:
@@ -202,29 +335,76 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
PyObject *list = NULL;
list = PyList_New(0);
- if (list == NULL)
+ if (!list)
goto RuntimeError;
- if(self->flag & BONE_CONNECTED)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
- goto RuntimeError;
- if(self->flag & BONE_HINGE)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
- goto RuntimeError;
- if(self->flag & BONE_NO_DEFORM)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
- goto RuntimeError;
- if(self->flag & BONE_MULT_VG_ENV)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
- goto RuntimeError;
- if(self->flag & BONE_HIDDEN_A)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
- goto RuntimeError;
+ if(self->editbone){
+ if(self->editbone->flag & BONE_CONNECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_HINGE)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_NO_DEFORM)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_MULT_VG_ENV)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_HIDDEN_A)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_ROOTSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_SELECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_TIPSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
+ goto RuntimeError;
+ }else{
+ if(self->flag & BONE_CONNECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_HINGE)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_NO_DEFORM)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_MULT_VG_ENV)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_HIDDEN_A)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_ROOTSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_SELECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_TIPSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
+ goto RuntimeError;
+ }
return EXPP_incr_ret(list);
@@ -240,13 +420,14 @@ static int EditBone_CheckValidConstant(PyObject *constant)
if (constant){
if (BPy_Constant_Check(constant)){
name = PyDict_GetItemString(((BPy_constant*)constant)->dict, "name");
- if (!name) return 0;
- if (!(STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM")
- || STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))){
- return 0;
- }else{
- return 1;
- }
+ if (!name)
+ return 0;
+ if (!STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM") &&
+ !STREQ3(PyString_AsString(name), "ROOT_SELECTED", "BONE_SELECTED", "TIP_SELECTED") &&
+ !STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))
+ return 0;
+ else
+ return 1;
}else{
return 0;
}
@@ -275,7 +456,19 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur
goto AttributeError2;
}
}
- self->flag = new_flag;
+
+ //set the options
+ if(self->editbone){
+ //make sure the 'connected' property is set up correctly
+ if (new_flag & BONE_CONNECTED)
+ if(!self->editbone->parent)
+ goto AttributeError3;
+ else
+ VECCOPY(self->editbone->head, self->editbone->parent->tail);
+ self->editbone->flag = new_flag;
+ }else{
+ self->flag = new_flag;
+ }
return 0;
}else if (BPy_Constant_Check(value)){
if (!EditBone_CheckValidConstant(value))
@@ -283,7 +476,18 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur
val = PyDict_GetItemString(((BPy_constant*)value)->dict, "value");
if (PyInt_Check(val)){
numeric_value = (int)PyInt_AS_LONG(val);
- self->flag = numeric_value;
+
+ if(self->editbone){
+ //make sure the 'connected' property is set up correctly
+ if (numeric_value & BONE_CONNECTED)
+ if(!self->editbone->parent)
+ goto AttributeError3;
+ else
+ VECCOPY(self->editbone->head, self->editbone->parent->tail);
+ self->editbone->flag = numeric_value;
+ }else{
+ self->flag = numeric_value;
+ }
return 0;
}else{
goto AttributeError2;
@@ -294,64 +498,112 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur
AttributeError1:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
- sEditBoneError, ".options(): ", "Expects a constant or list of constants");
-
+ sEditBoneError, ".options: ", "Expects a constant or list of constants");
AttributeError2:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
- sEditBoneError, ".options(): ", "Please use a constant defined in the Armature module");
+ sEditBoneError, ".options: ", "Please use a constant defined in the Armature module");
+AttributeError3:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".options: ", "You can't connect to parent because no parent is set");
}
//------------------------EditBone.parent (get)
static PyObject *EditBone_getParent(BPy_EditBone *self, void *closure)
{
- //if (!STREQ(self->parent, ""))
- // return PyString_FromString(PyBone_FromBone(self->parent));
- //else
- printf("Sorry this isn't implemented yet.... :/");
- return EXPP_incr_ret(Py_None);
+ if (self->editbone){
+ if (self->editbone->parent)
+ return PyEditBone_FromEditBone(self->editbone->parent);
+ else
+ return EXPP_incr_ret(Py_None);
+ }else{
+ return EXPP_incr_ret(Py_None); //not in the list yet can't have a parent
+ }
}
//------------------------EditBone.parent (set)
static int EditBone_setParent(BPy_EditBone *self, PyObject *value, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return 1;
-}
+ BPy_EditBone *parent = NULL;
+
+ if (!PyArg_Parse(value, "O!", &EditBone_Type, &parent))
+ goto AttributeError;
+
+ if (!parent->editbone)
+ goto AttributeError2;
-//------------------------EditBone.children (get)
-static PyObject *EditBone_getChildren(BPy_EditBone *self, void *closure)
+ if (self->editbone){
+ self->editbone->parent = parent->editbone;
+ }else{
+ self->parent = parent->editbone;
+ }
+ return 0;
+
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".parent: ", "expects a EditBone Object");
+
+AttributeError2:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".parent: ", "This object is not in the armature's bone list!");
+}
+//------------------------EditBone.matrix (get)
+static PyObject *EditBone_getMatrix(BPy_EditBone *self, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return EXPP_incr_ret(Py_None);
+ float boneMatrix[3][3];
+ float axis[3];
+
+ if (self->editbone){
+ VECSUB(axis, self->editbone->tail, self->editbone->head);
+ vec_roll_to_mat3(axis, self->editbone->roll, boneMatrix);
+ }else{
+ VECSUB(axis, self->tail, self->head);
+ vec_roll_to_mat3(axis, self->roll, boneMatrix);
+ }
+
+ return newMatrixObject((float*)boneMatrix, 3, 3, Py_NEW);
}
-//------------------------EditBone.children (set)
-static int EditBone_setChildren(BPy_EditBone *self, PyObject *value, void *closure)
+//------------------------EditBone.matrix (set)
+static int EditBone_setMatrix(BPy_EditBone *self, PyObject *value, void *closure)
{
printf("Sorry this isn't implemented yet.... :/");
return 1;
}
-//------------------------EditBone.matrix (get)
-static PyObject *EditBone_getMatrix(BPy_EditBone *self, void *closure)
+//------------------------Bone.length (get)
+static PyObject *EditBone_getLength(BPy_EditBone *self, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return EXPP_incr_ret(Py_None);
+ float delta[3];
+ double dot = 0.0f;
+ int x;
+
+ if (self->editbone){
+ VECSUB(delta, self->editbone->tail, self->editbone->head);
+ for(x = 0; x < 3; x++){
+ dot += (delta[x] * delta[x]);
+ }
+ return PyFloat_FromDouble(sqrt(dot));
+ }else{
+ VECSUB(delta, self->tail, self->head);
+ for(x = 0; x < 3; x++){
+ dot += (delta[x] * delta[x]);
+ }
+ return PyFloat_FromDouble(sqrt(dot));
+ }
}
-//------------------------EditBone.matrix (set)
-static int EditBone_setMatrix(BPy_EditBone *self, PyObject *value, void *closure)
+//------------------------Bone.length (set)
+static int EditBone_setLength(BPy_EditBone *self, PyObject *value, void *closure)
{
printf("Sorry this isn't implemented yet.... :/");
return 1;
}
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
-//TODO: We need to think about the below methods
//------------------------tp_methods
//This contains a list of all methods the object contains
-//static PyMethodDef BPy_Bone_methods[] = {
-// {"clearParent", (PyCFunction) Bone_clearParent, METH_NOARGS,
-// "() - disconnects this bone from it's parent"},
-// {"clearChildren", (PyCFunction) Bone_clearChildren, METH_NOARGS,
-// "() - disconnects all the children from this bone"},
-// {NULL}
-//};
-//------------------------tp_getset
+static PyMethodDef BPy_EditBone_methods[] = {
+ {"hasParent", (PyCFunction) EditBone_hasParent, METH_NOARGS,
+ "() - True/False - Bone has a parent"},
+ {"clearParent", (PyCFunction) EditBone_clearParent, METH_NOARGS,
+ "() - sets the parent to None"},
+ {NULL}
+};
+///------------------------tp_getset
//This contains methods for attributes that require checking
static PyGetSetDef BPy_EditBone_getset[] = {
{"name", (getter)EditBone_getName, (setter)EditBone_setName,
@@ -366,7 +618,7 @@ static PyGetSetDef BPy_EditBone_getset[] = {
"The matrix of the bone", NULL},
{"weight", (getter)EditBone_getWeight, (setter)EditBone_setWeight,
"The weight of the bone in relation to a parented mesh", NULL},
- {"deform_dist", (getter)EditBone_getDeform_dist, (setter)EditBone_setDeform_dist,
+ {"deformDist", (getter)EditBone_getDeform_dist, (setter)EditBone_setDeform_dist,
"The distance at which deformation has effect", NULL},
{"subdivisions", (getter)EditBone_getSubdivisions, (setter)EditBone_setSubdivisions,
"The number of subdivisions (for B-Bones)", NULL},
@@ -374,8 +626,8 @@ static PyGetSetDef BPy_EditBone_getset[] = {
"The options effective on this bone", NULL},
{"parent", (getter)EditBone_getParent, (setter)EditBone_setParent,
"The parent bone of this bone", NULL},
- {"children", (getter)EditBone_getChildren, (setter)EditBone_setChildren,
- "The child bones of this bone", NULL},
+ {"length", (getter)EditBone_getLength, (setter)EditBone_setLength,
+ "The length of this bone", NULL},
{NULL}
};
@@ -383,7 +635,10 @@ static PyGetSetDef BPy_EditBone_getset[] = {
//This is the string representation of the object
static PyObject *EditBone_repr(BPy_EditBone *self)
{
- return PyString_FromFormat( "[EditBone \"%s\"]", self->name );
+ if (self->editbone)
+ return PyString_FromFormat( "[EditBone \"%s\"]", self->editbone->name );
+ else
+ return PyString_FromFormat( "[EditBone \"%s\"]", self->name );
}
//------------------------tp_doc
@@ -395,114 +650,121 @@ designed to act as a wrapper for an 'edit bone'.";
//This methods creates a new object (note it does not initialize it - only the building)
static PyObject *EditBone_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
+ char *name = "myEditBone";
BPy_EditBone *py_editBone = NULL;
- PyObject *py_bone;
- struct Bone *bone;
- int i;
-
- if(!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone))
- goto AttributeError;
+ float head[3], tail[3];
py_editBone = (BPy_EditBone*)type->tp_alloc(type, 0); //new
if (py_editBone == NULL)
goto RuntimeError;
- bone = ((BPy_Bone*)py_bone)->bone;
-
- BLI_strncpy(py_editBone->name, bone->name, 32);
- py_editBone->flag = bone->flag;
- py_editBone->length = bone->length;
- py_editBone->weight = bone->weight;
- py_editBone->dist = bone->dist;
- py_editBone->xwidth = bone->xwidth;
- py_editBone->zwidth = bone->zwidth;
- py_editBone->ease1 = bone->ease1;
- py_editBone->ease2 = bone->ease2;
- py_editBone->rad_head = bone->rad_head;
- py_editBone->rad_tail = bone->rad_tail;
- py_editBone->segments = bone->segments;
- py_editBone->temp = NULL;
-
- if (bone->parent){
- BLI_strncpy(py_editBone->parent, bone->parent->name, 32);
- }else{
- BLI_strncpy(py_editBone->parent, "", 32);
- }
+ //this pointer will be set when this bone is placed in ListBase
+ //otherwise this will act as a py_object
+ py_editBone->editbone = NULL;
- py_editBone->roll = (float)boneRoll_ToArmatureSpace(bone);
+ unique_editbone_name(name);
+ BLI_strncpy(py_editBone->name, name, 32);
+ py_editBone->parent = NULL;
+ py_editBone->weight= 1.0f;
+ py_editBone->dist= 0.25f;
+ py_editBone->xwidth= 0.1f;
+ py_editBone->zwidth= 0.1f;
+ py_editBone->ease1= 1.0f;
+ py_editBone->ease2= 1.0f;
+ py_editBone->rad_head= 0.10f;
+ py_editBone->rad_tail= 0.05f;
+ py_editBone->segments= 1;
+ py_editBone->flag = 0;
+ py_editBone->roll = 0.0f;
+
+ head[0] = head[1] = head[2] = 0.0f;
+ tail[1] = tail[2] = 0.0f;
+ tail[0] = 1.0f;
+ VECCOPY(py_editBone->head, head);
+ VECCOPY(py_editBone->tail, tail);
- for (i = 0; i < 3; i++){
- py_editBone->head[i] = bone->arm_head[i];
- py_editBone->tail[i] = bone->arm_tail[i];
- }
return (PyObject*)py_editBone;
RuntimeError:
return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
sEditBoneError, " __new__: ", "Internal Error");
-AttributeError:
- return EXPP_objError(PyExc_AttributeError, "%s%s%s",
- sEditBoneBadArgs, " __new__: ", "Expects PyBone and optional float");
}
//------------------------tp_dealloc
//This tells how to 'tear-down' our object when ref count hits 0
+//the struct EditBone pointer will be handled by the BPy_BonesDict class
static void EditBone_dealloc(BPy_EditBone * self)
{
- ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ EditBone_Type.tp_free(self);
return;
}
//------------------TYPE_OBECT DEFINITION--------------------------
PyTypeObject EditBone_Type = {
PyObject_HEAD_INIT(NULL) //tp_head
- 0, //tp_internal
- "EditBone", //tp_name
- sizeof(BPy_EditBone), //tp_basicsize
- 0, //tp_itemsize
- (destructor)EditBone_dealloc, //tp_dealloc
- 0, //tp_print
- 0, //tp_getattr
- 0, //tp_setattr
- 0, //tp_compare
- (reprfunc)EditBone_repr, //tp_repr
- 0, //tp_as_number
- 0, //tp_as_sequence
- 0, //tp_as_mapping
- 0, //tp_hash
- 0, //tp_call
- 0, //tp_str
- 0, //tp_getattro
- 0, //tp_setattro
- 0, //tp_as_buffer
- Py_TPFLAGS_DEFAULT, //tp_flags
- BPy_EditBone_doc, //tp_doc
- 0, //tp_traverse
- 0, //tp_clear
- 0, //tp_richcompare
- 0, //tp_weaklistoffset
- 0, //tp_iter
- 0, //tp_iternext
- 0, //tp_methods
- 0, //tp_members
- BPy_EditBone_getset, //tp_getset
- 0, //tp_base
- 0, //tp_dict
- 0, //tp_descr_get
- 0, //tp_descr_set
- 0, //tp_dictoffset
- 0, //tp_init
- 0, //tp_alloc
- (newfunc)EditBone_new, //tp_new
- 0, //tp_free
- 0, //tp_is_gc
- 0, //tp_bases
- 0, //tp_mro
- 0, //tp_cache
- 0, //tp_subclasses
- 0, //tp_weaklist
- 0 //tp_del
+ 0, //tp_internal
+ "EditBone", //tp_name
+ sizeof(BPy_EditBone), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)EditBone_dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //tp_getattr
+ 0, //tp_setattr
+ 0, //tp_compare
+ (reprfunc)EditBone_repr, //tp_repr
+ 0, //tp_as_number
+ 0, //tp_as_sequence
+ 0, //tp_as_mapping
+ 0, //tp_hash
+ 0, //tp_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT, //tp_flags
+ BPy_EditBone_doc, //tp_doc
+ 0, //tp_traverse
+ 0, //tp_clear
+ 0, //tp_richcompare
+ 0, //tp_weaklistoffset
+ 0, //tp_iter
+ 0, //tp_iternext
+ BPy_EditBone_methods, //tp_methods
+ 0, //tp_members
+ BPy_EditBone_getset, //tp_getset
+ 0, //tp_base
+ 0, //tp_dict
+ 0, //tp_descr_get
+ 0, //tp_descr_set
+ 0, //tp_dictoffset
+ 0, //tp_init
+ 0, //tp_alloc
+ (newfunc)EditBone_new, //tp_new
+ 0, //tp_free
+ 0, //tp_is_gc
+ 0, //tp_bases
+ 0, //tp_mro
+ 0, //tp_cache
+ 0, //tp_subclasses
+ 0, //tp_weaklist
+ 0 //tp_del
};
//------------------METHOD IMPLEMENTATIONS--------------------------------
+//-------------------------Bone.hasParent()
+PyObject *Bone_hasParent(BPy_Bone *self)
+{
+ if (self->bone->parent)
+ return EXPP_incr_ret(Py_True);
+ else
+ return EXPP_incr_ret(Py_False);
+}
+//-------------------------Bone.hasChildren()
+PyObject *Bone_hasChildren(BPy_Bone *self)
+{
+ if (self->bone->childbase.first)
+ return EXPP_incr_ret(Py_True);
+ else
+ return EXPP_incr_ret(Py_False);
+}
//------------------ATTRIBUTE IMPLEMENTATIONS-----------------------------
//------------------------Bone.name (get)
static PyObject *Bone_getName(BPy_Bone *self, void *closure)
@@ -514,7 +776,7 @@ static PyObject *Bone_getName(BPy_Bone *self, void *closure)
static int Bone_setName(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.roll (get)
static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
@@ -527,7 +789,7 @@ static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
static int Bone_setRoll(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.head (get)
static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
@@ -540,7 +802,7 @@ static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
static int Bone_setHead(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.tail (get)
static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
@@ -553,7 +815,7 @@ static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
static int Bone_setTail(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.weight (get)
static PyObject *Bone_getWeight(BPy_Bone *self, void *closure)
@@ -564,7 +826,7 @@ static PyObject *Bone_getWeight(BPy_Bone *self, void *closure)
static int Bone_setWeight(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.deform_dist (get)
static PyObject *Bone_getDeform_dist(BPy_Bone *self, void *closure)
@@ -575,7 +837,7 @@ static PyObject *Bone_getDeform_dist(BPy_Bone *self, void *closure)
static int Bone_setDeform_dist(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.subdivisions (get)
static PyObject *Bone_getSubdivisions(BPy_Bone *self, void *closure)
@@ -586,7 +848,7 @@ static PyObject *Bone_getSubdivisions(BPy_Bone *self, void *closure)
static int Bone_setSubdivisions(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.connected (get)
static PyObject *Bone_getOptions(BPy_Bone *self, void *closure)
@@ -617,6 +879,18 @@ static PyObject *Bone_getOptions(BPy_Bone *self, void *closure)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
goto RuntimeError;
+ if(self->bone->flag & BONE_ROOTSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->bone->flag & BONE_SELECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->bone->flag & BONE_TIPSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
+ goto RuntimeError;
return EXPP_incr_ret(list);
@@ -628,7 +902,7 @@ RuntimeError:
static int Bone_setOptions(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.parent (get)
static PyObject *Bone_getParent(BPy_Bone *self, void *closure)
@@ -642,7 +916,7 @@ static PyObject *Bone_getParent(BPy_Bone *self, void *closure)
static int Bone_setParent(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------(internal) PyBone_ChildrenAsList
static int PyBone_ChildrenAsList(PyObject *list, ListBase *bones){
@@ -685,7 +959,7 @@ static PyObject *Bone_getChildren(BPy_Bone *self, void *closure)
static int Bone_setChildren(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.matrix (get)
static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
@@ -698,9 +972,29 @@ static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
static int Bone_setMatrix(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
+}
+//------------------------Bone.length (get)
+static PyObject *Bone_getLength(BPy_Bone *self, void *closure)
+{
+ return Py_BuildValue("f", self->bone->length);
+}
+//------------------------Bone.length (set)
+static int Bone_setLength(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
+//------------------------tp_methods
+//This contains a list of all methods the object contains
+static PyMethodDef BPy_Bone_methods[] = {
+ {"hasParent", (PyCFunction) Bone_hasParent, METH_NOARGS,
+ "() - True/False - Bone has a parent"},
+ {"hasChildren", (PyCFunction) Bone_hasChildren, METH_NOARGS,
+ "() - True/False - Bone has 1 or more children"},
+ {NULL}
+};
//------------------------tp_getset
//This contains methods for attributes that require checking
static PyGetSetDef BPy_Bone_getset[] = {
@@ -726,37 +1020,23 @@ static PyGetSetDef BPy_Bone_getset[] = {
"The parent bone of this bone", NULL},
{"children", (getter)Bone_getChildren, (setter)Bone_setChildren,
"The child bones of this bone", NULL},
+ {"length", (getter)Bone_getLength, (setter)Bone_setLength,
+ "The length of this bone", NULL},
{NULL}
};
-
-//------------------------tp_new
-static PyObject *Bone_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- return EXPP_incr_ret(Py_None);
-}
-
-//------------------------tp_richcompare
-//This method allows the object to use comparison operators
-static PyObject *Bone_richcmpr(BPy_Bone *self, PyObject *v, int op)
-{
- return EXPP_incr_ret(Py_None);
-}
-
//------------------------tp_repr
//This is the string representation of the object
static PyObject *Bone_repr(BPy_Bone *self)
{
return PyString_FromFormat( "[Bone \"%s\"]", self->bone->name );
}
-
//------------------------tp_dealloc
//This tells how to 'tear-down' our object when ref count hits 0
static void Bone_dealloc(BPy_Bone * self)
{
- ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ Bone_Type.tp_free(self);
return;
}
-
//------------------------tp_doc
//The __doc__ string for this object
static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
@@ -764,56 +1044,74 @@ static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
//------------------TYPE_OBECT DEFINITION--------------------------
PyTypeObject Bone_Type = {
- PyObject_HEAD_INIT(NULL) //tp_head
- 0, //tp_internal
- "Bone", //tp_name
- sizeof(BPy_Bone), //tp_basicsize
- 0, //tp_itemsize
- (destructor)Bone_dealloc, //tp_dealloc
- 0, //tp_print
- 0, //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_call
- 0, //tp_str
- 0, //tp_getattro
- 0, //tp_setattro
- 0, //tp_as_buffer
- Py_TPFLAGS_DEFAULT, //tp_flags
- BPy_Bone_doc, //tp_doc
- 0, //tp_traverse
- 0, //tp_clear
- (richcmpfunc)Bone_richcmpr, //tp_richcompare
- 0, //tp_weaklistoffset
- 0, //tp_iter
- 0, //tp_iternext
- 0, //tp_methods
- 0, //tp_members
- BPy_Bone_getset, //tp_getset
- 0, //tp_base
- 0, //tp_dict
- 0, //tp_descr_get
- 0, //tp_descr_set
- 0, //tp_dictoffset
- 0, //tp_init
- 0, //tp_alloc
- (newfunc)Bone_new, //tp_new
- 0, //tp_free
- 0, //tp_is_gc
- 0, //tp_bases
- 0, //tp_mro
- 0, //tp_cache
- 0, //tp_subclasses
- 0, //tp_weaklist
- 0 //tp_del
+ PyObject_HEAD_INIT(NULL) //tp_head
+ 0, //tp_internal
+ "Bone", //tp_name
+ sizeof(BPy_Bone), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)Bone_dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //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_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT, //tp_flags
+ BPy_Bone_doc, //tp_doc
+ 0, //tp_traverse
+ 0, //tp_clear
+ 0, //tp_richcompare
+ 0, //tp_weaklistoffset
+ 0, //tp_iter
+ 0, //tp_iternext
+ BPy_Bone_methods, //tp_methods
+ 0, //tp_members
+ BPy_Bone_getset, //tp_getset
+ 0, //tp_base
+ 0, //tp_dict
+ 0, //tp_descr_get
+ 0, //tp_descr_set
+ 0, //tp_dictoffset
+ 0, //tp_init
+ 0, //tp_alloc
+ 0, //tp_new
+ 0, //tp_free
+ 0, //tp_is_gc
+ 0, //tp_bases
+ 0, //tp_mro
+ 0, //tp_cache
+ 0, //tp_subclasses
+ 0, //tp_weaklist
+ 0 //tp_del
};
//------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
//-----------------(internal)
+//Converts a struct EditBone to a BPy_EditBone
+PyObject *PyEditBone_FromEditBone(struct EditBone *editbone)
+{
+ BPy_EditBone *py_editbone = NULL;
+
+ py_editbone = (BPy_EditBone*)EditBone_Type.tp_alloc(&EditBone_Type, 0); //*new*
+ if (!py_editbone)
+ goto RuntimeError;
+
+ py_editbone->editbone = editbone;
+
+ return (PyObject *) py_editbone;
+
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
+ sEditBoneError, "PyEditBone_FromEditBone: ", "Internal Error Ocurred");
+}
+//-----------------(internal)
//Converts a struct Bone to a BPy_Bone
PyObject *PyBone_FromBone(struct Bone *bone)
{