2
* $Id: Bone.c,v 1.46 2006/07/06 18:53:36 khughes Exp $
2
* $Id: Bone.c 14444 2008-04-16 22:40:48Z hos $
4
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4
* ***** BEGIN GPL LICENSE BLOCK *****
6
6
* This program is free software; you can redistribute it and/or
7
7
* modify it under the terms of the GNU General Public License
8
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version. The Blender
10
* Foundation also sells licenses for use in proprietary software under
11
* the Blender License. See http://www.blender.org/BL/ for information
9
* of the License, or (at your option) any later version.
14
11
* This program is distributed in the hope that it will be useful,
15
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
639
637
printf("Sorry this isn't implemented yet.... :/");
642
//------------------------Bone.headRadius (get)
643
static PyObject *EditBone_getHeadRadius(BPy_EditBone *self, void *closure)
646
if (self->editbone->parent && self->editbone->flag & BONE_CONNECTED)
647
return PyFloat_FromDouble(self->editbone->parent->rad_tail);
649
return PyFloat_FromDouble(self->editbone->rad_head);
651
if (self->parent && self->flag & BONE_CONNECTED)
652
return PyFloat_FromDouble(self->parent->rad_tail);
654
return PyFloat_FromDouble(self->rad_head);
656
//------------------------Bone.headRadius (set)
657
static int EditBone_setHeadRadius(BPy_EditBone *self, PyObject *value, void *closure)
660
if (!PyArg_Parse(value, "f", &radius))
662
CLAMP(radius, 0.0f, 10000.0f);
665
if (self->editbone->parent && self->editbone->flag & BONE_CONNECTED)
666
self->editbone->parent->rad_tail= radius;
668
self->editbone->rad_head= radius;
670
if (self->parent && self->flag & BONE_CONNECTED)
671
self->parent->rad_tail= radius;
673
self->rad_head= radius;
677
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
678
sEditBoneError, ".headRadius: ", "expects a float");
682
//------------------------Bone.tailRadius (get)
683
static PyObject *EditBone_getTailRadius(BPy_EditBone *self, void *closure)
686
return PyFloat_FromDouble(self->editbone->rad_tail);
688
return PyFloat_FromDouble(self->rad_tail);
690
//------------------------Bone.tailRadius (set)
691
static int EditBone_setTailRadius(BPy_EditBone *self, PyObject *value, void *closure)
694
if (!PyArg_Parse(value, "f", &radius))
696
CLAMP(radius, 0.0f, 10000.0f);
699
self->editbone->rad_tail = radius;
701
self->rad_tail = radius;
705
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
706
sEditBoneError, ".tailRadius: ", "expects a float");
709
//------------------------Bone.layerMask (get)
710
static PyObject *EditBone_getLayerMask(BPy_EditBone *self)
712
/* do this extra stuff because the short's bits can be negative values */
713
unsigned short laymask = 0;
714
if (self->editbone) laymask |= self->editbone->layer;
715
else laymask |= self->layer;
716
return PyInt_FromLong((int)laymask);
718
//------------------------Bone.layerMask (set)
719
static int EditBone_setLayerMask(BPy_EditBone *self, PyObject *value)
722
if (!PyInt_Check(value)) {
723
return EXPP_ReturnIntError( PyExc_AttributeError,
724
"expected an integer (bitmask) as argument" );
727
laymask = PyInt_AsLong(value);
729
if (laymask <= 0 || laymask > (1<<16) - 1)
730
return EXPP_ReturnIntError( PyExc_AttributeError,
731
"bitmask must have from 1 up to 16 bits set");
733
if (self->editbone) {
734
self->editbone->layer = 0;
735
self->editbone->layer |= laymask;
738
self->layer |= laymask;
642
744
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
643
745
//------------------------tp_methods
644
746
//This contains a list of all methods the object contains
674
776
"The parent bone of this bone", NULL},
675
777
{"length", (getter)EditBone_getLength, (setter)EditBone_setLength,
676
778
"The length of this bone", NULL},
779
{"tailRadius", (getter)EditBone_getTailRadius, (setter)EditBone_setTailRadius,
780
"Set the radius of this bones tip", NULL},
781
{"headRadius", (getter)EditBone_getHeadRadius, (setter)EditBone_setHeadRadius,
782
"Set the radius of this bones head", NULL},
783
{"layerMask", (getter)EditBone_getLayerMask, (setter)EditBone_setLayerMask,
784
"Layer bitmask", NULL },
677
785
{NULL, NULL, NULL, NULL,NULL}
687
795
return PyString_FromFormat( "[EditBone \"%s\"]", self->name );
798
static int EditBone_compare( BPy_EditBone * a, BPy_EditBone * b )
800
/* if they are not wrapped, then they cant be the same */
801
if (a->editbone==NULL && b->editbone==NULL) return -1;
802
return ( a->editbone == b->editbone ) ? 0 : -1;
690
806
//------------------------tp_doc
691
807
//The __doc__ string for this object
692
808
static char BPy_EditBone_doc[] = "This is an internal subobject of armature\
804
921
py_bone = PyBone_FromBone(bone);
805
922
if (py_bone == NULL)
808
925
if(PyList_Append(list, py_bone) == -1){
811
929
if (bone->childbase.first)
812
PyBone_ChildrenAsList(list, &bone->childbase);
930
if (!PyBone_ChildrenAsList(list, &bone->childbase))
817
return EXPP_intError(PyExc_RuntimeError, "%s%s",
818
sBoneError, "Internal error trying to wrap blender bones!");
820
935
//-------------------------Bone.hasParent()
821
936
static PyObject *Bone_hasParent(BPy_Bone *self)
823
938
if (self->bone->parent)
824
return EXPP_incr_ret(Py_True);
826
return EXPP_incr_ret(Py_False);
828
943
//-------------------------Bone.hasChildren()
829
944
static PyObject *Bone_hasChildren(BPy_Bone *self)
831
946
if (self->bone->childbase.first)
832
return EXPP_incr_ret(Py_True);
834
return EXPP_incr_ret(Py_False);
836
951
//-------------------------Bone.getAllChildren()
837
952
static PyObject *Bone_getAllChildren(BPy_Bone *self)
839
PyObject *list = NULL;
841
if (self->bone->childbase.first){
842
list = PyList_New(0);
843
if (!PyBone_ChildrenAsList(list, &self->bone->childbase))
845
return EXPP_incr_ret(list);
847
return EXPP_incr_ret(Py_None);
954
PyObject *list = PyList_New(0);
955
if (!self->bone->childbase.first) {
957
} else if (!PyBone_ChildrenAsList(list, &self->bone->childbase)) {
959
EXPP_objError(PyExc_RuntimeError, "%s%s",
960
sBoneError, "Internal error trying to wrap blender bones!");
850
965
//------------------ATTRIBUTE IMPLEMENTATIONS-----------------------------
851
966
//------------------------Bone.name (get)
852
967
static PyObject *Bone_getName(BPy_Bone *self, void *closure)
863
978
//------------------------Bone.roll (get)
864
979
static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
866
return Py_BuildValue("{s:O, s:O}",
867
"BONESPACE", PyFloat_FromDouble((self->bone->roll * (180/Py_PI))),
868
"ARMATURESPACE", PyFloat_FromDouble((boneRoll_ToArmatureSpace(self->bone) * (180/Py_PI))));
981
return Py_BuildValue("{s:f, s:f}",
982
"BONESPACE", self->bone->roll * (180/Py_PI),
983
"ARMATURESPACE", boneRoll_ToArmatureSpace(self->bone) * (180/Py_PI));
870
985
//------------------------Bone.roll (set)
871
986
static int Bone_setRoll(BPy_Bone *self, PyObject *value, void *closure)
876
991
//------------------------Bone.head (get)
877
992
static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
879
return Py_BuildValue("{s:O, s:O}",
880
"BONESPACE", newVectorObject(self->bone->head, 3, Py_WRAP),
881
"ARMATURESPACE", newVectorObject(self->bone->arm_head, 3, Py_WRAP));
994
PyObject *val1 = newVectorObject(self->bone->head, 3, Py_WRAP);
995
PyObject *val2 = newVectorObject(self->bone->arm_head, 3, Py_WRAP);
996
PyObject *ret = Py_BuildValue(
997
"{s:O, s:O}", "BONESPACE", val1, "ARMATURESPACE", val2);
883
1003
//------------------------Bone.head (set)
884
1004
static int Bone_setHead(BPy_Bone *self, PyObject *value, void *closure)
889
1009
//------------------------Bone.tail (get)
890
1010
static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
892
return Py_BuildValue("{s:O, s:O}",
893
"BONESPACE", newVectorObject(self->bone->tail, 3, Py_WRAP),
894
"ARMATURESPACE", newVectorObject(self->bone->arm_tail, 3, Py_WRAP));
1012
PyObject *val1 = newVectorObject(self->bone->tail, 3, Py_WRAP);
1013
PyObject *val2 = newVectorObject(self->bone->arm_tail, 3, Py_WRAP);
1014
PyObject *ret = Py_BuildValue("{s:O, s:O}",
1015
"BONESPACE", val1, "ARMATURESPACE", val2);
896
1021
//------------------------Bone.tail (set)
897
1022
static int Bone_setTail(BPy_Bone *self, PyObject *value, void *closure)
1003
1129
//------------------------Bone.children (get)
1004
1130
static PyObject *Bone_getChildren(BPy_Bone *self, void *closure)
1006
PyObject *list = NULL;
1132
PyObject *list = PyList_New(0);
1007
1133
Bone *bone = NULL;
1008
1134
PyObject *py_bone = NULL;
1010
1136
if (self->bone->childbase.first){
1011
list = PyList_New(0);
1012
1137
for (bone = self->bone->childbase.first; bone; bone = bone->next){
1013
1138
py_bone = PyBone_FromBone(bone);
1014
1139
if (py_bone == NULL)
1016
if(PyList_Append(list, py_bone) == -1){
1141
if (PyList_Append(list, py_bone) == -1)
1020
return EXPP_incr_ret(list);
1022
return EXPP_incr_ret(Py_None);
1150
Py_XDECREF(py_bone);
1026
1151
return EXPP_objError(PyExc_RuntimeError, "%s%s",
1027
1152
sBoneError, "Internal error trying to wrap blender bones!");
1035
1160
//------------------------Bone.matrix (get)
1036
1161
static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
1038
return Py_BuildValue("{s:O, s:O}",
1039
"BONESPACE", newMatrixObject((float*)self->bone->bone_mat, 3,3, Py_WRAP),
1040
"ARMATURESPACE", newMatrixObject((float*)self->bone->arm_mat, 4,4, Py_WRAP));
1163
PyObject *val1 = newMatrixObject((float*)self->bone->bone_mat, 3,3, Py_WRAP);
1164
PyObject *val2 = newMatrixObject((float*)self->bone->arm_mat, 4,4, Py_WRAP);
1165
PyObject *ret = Py_BuildValue("{s:O, s:O}",
1166
"BONESPACE", val1, "ARMATURESPACE", val2);
1042
1173
//------------------------Bone.matrix (set)
1043
1174
static int Bone_setMatrix(BPy_Bone *self, PyObject *value, void *closure)
1056
1187
return EXPP_intError(PyExc_ValueError, "%s%s",
1057
1188
sBoneError, "You must first call .makeEditable() to edit the armature");
1191
//------------------------Bone.headRadius (get)
1192
static PyObject *Bone_getHeadRadius(BPy_Bone *self, void *closure)
1195
if (self->bone->parent && self->bone->flag & BONE_CONNECTED)
1196
return PyFloat_FromDouble(self->bone->parent->rad_tail);
1198
return PyFloat_FromDouble(self->bone->rad_head);
1200
//------------------------Bone.headRadius (set)
1201
static int Bone_setHeadRadius(BPy_Bone *self, PyObject *value, void *closure)
1204
if (!PyArg_Parse(value, "f", &radius))
1205
goto AttributeError;
1206
CLAMP(radius, 0.0f, 10000.0f);
1208
if (self->bone->parent && self->bone->flag & BONE_CONNECTED)
1209
self->bone->parent->rad_tail= radius;
1211
self->bone->rad_head= radius;
1215
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
1216
sEditBoneError, ".headRadius: ", "expects a float");
1219
//------------------------Bone.tailRadius (get)
1220
static PyObject *Bone_getTailRadius(BPy_Bone *self, void *closure)
1222
return PyFloat_FromDouble(self->bone->rad_tail);
1225
//------------------------Bone.headRadius (set)
1226
static int Bone_setTailRadius(BPy_Bone *self, PyObject *value, void *closure)
1229
if (!PyArg_Parse(value, "f", &radius))
1230
goto AttributeError;
1231
CLAMP(radius, 0.0f, 10000.0f);
1232
self->bone->rad_tail= radius;
1236
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
1237
sEditBoneError, ".headRadius: ", "expects a float");
1240
//------------------------Bone.layerMask (get)
1241
static PyObject *Bone_getLayerMask(BPy_Bone *self)
1243
/* do this extra stuff because the short's bits can be negative values */
1244
unsigned short laymask = 0;
1245
laymask |= self->bone->layer;
1246
return PyInt_FromLong((int)laymask);
1248
//------------------------Bone.layerMask (set)
1249
static int Bone_setLayerMask(BPy_Bone *self, PyObject *value)
1252
if (!PyInt_Check(value)) {
1253
return EXPP_ReturnIntError( PyExc_AttributeError,
1254
"expected an integer (bitmask) as argument" );
1257
laymask = PyInt_AsLong(value);
1259
if (laymask <= 0 || laymask > (1<<16) - 1)
1260
return EXPP_ReturnIntError( PyExc_AttributeError,
1261
"bitmask must have from 1 up to 16 bits set");
1263
self->bone->layer = 0;
1264
self->bone->layer |= laymask;
1059
1269
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
1060
1270
//------------------------tp_methods
1061
1271
//This contains a list of all methods the object contains
1095
1305
"The child bones of this bone", NULL},
1096
1306
{"length", (getter)Bone_getLength, (setter)Bone_setLength,
1097
1307
"The length of this bone", NULL},
1308
{"tailRadius", (getter)Bone_getTailRadius, (setter)Bone_setTailRadius,
1309
"Set the radius of this bones tip", NULL},
1310
{"headRadius", (getter)Bone_getHeadRadius, (setter)Bone_setHeadRadius,
1311
"Set the radius of this bones head", NULL},
1312
{"layerMask", (getter)Bone_getLayerMask, (setter)Bone_setLayerMask,
1313
"Layer bitmask", NULL },
1098
1314
{NULL, NULL, NULL, NULL,NULL}
1100
1316
//------------------------tp_repr
1119
1339
PyTypeObject Bone_Type = {
1120
1340
PyObject_HEAD_INIT(NULL) //tp_head
1121
1341
0, //tp_internal
1123
sizeof(BPy_Bone), //tp_basicsize
1343
sizeof(BPy_Bone), //tp_basicsize
1124
1344
0, //tp_itemsize
1125
(destructor)Bone_dealloc, //tp_dealloc
1345
(destructor)Bone_dealloc, //tp_dealloc
1127
1347
0, //tp_getattr
1128
1348
0, //tp_setattr
1130
(reprfunc) Bone_repr, //tp_repr
1349
(cmpfunc) Bone_compare, //tp_compare
1350
(reprfunc) Bone_repr, //tp_repr
1131
1351
0, //tp_as_number
1132
1352
0, //tp_as_sequence
1133
1353
0, //tp_as_mapping
1188
1408
//Converts a struct Bone to a BPy_Bone
1189
1409
PyObject *PyBone_FromBone(struct Bone *bone)
1191
BPy_Bone *py_Bone = NULL;
1193
py_Bone = (BPy_Bone*)Bone_Type.tp_alloc(&Bone_Type, 0); //*new*
1194
if (py_Bone == NULL)
1411
BPy_Bone *py_Bone = ( BPy_Bone * ) PyObject_NEW( BPy_Bone, &Bone_Type );
1197
1413
py_Bone->bone = bone;
1199
1415
return (PyObject *) py_Bone;
1202
return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
1203
sBoneError, "PyBone_FromBone: ", "Internal Error Ocurred");
1205
1417
//-----------------(internal)
1206
1418
//Converts a PyBone to a bBone