diff options
author | Ton Roosendaal <ton@blender.org> | 2005-12-13 23:32:39 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2005-12-13 23:32:39 +0300 |
commit | 4f235db6e6480881677678e2a9d4bc362d690bee (patch) | |
tree | 4d560b27550bb597f3d7b6d6a646577f2707ec19 /source/blender/python | |
parent | 904a478d9d7b7b633356ad638e4291ff79bbd067 (diff) | |
parent | d1cc4b7a15efaeea5de1f70762c3507572fe186d (diff) |
Tuesday merger of Orange branch with bf-blender
Diffstat (limited to 'source/blender/python')
-rw-r--r-- | source/blender/python/api2_2x/Armature.c | 559 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Armature.h | 11 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Bone.c | 788 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Bone.h | 78 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Image.c | 45 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Library.c | 1 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Mesh.c | 21 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/API_intro.py | 2 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Armature.py | 234 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Image.py | 7 | ||||
-rw-r--r-- | source/blender/python/api2_2x/sceneTimeLine.c | 68 |
11 files changed, 1112 insertions, 702 deletions
diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c index f728f3f19d1..05a89dbda21 100644 --- a/source/blender/python/api2_2x/Armature.c +++ b/source/blender/python/api2_2x/Armature.c @@ -48,7 +48,7 @@ //These are evil 'extern' declarations for functions with no anywhere extern void free_editArmature(void); extern void make_boneList(ListBase* list, ListBase *bones, EditBone *parent); -extern void editbones_to_armature (ListBase *list, Object *ob, bArmature *armature); +extern void editbones_to_armature (ListBase *list, Object *ob); //------------------------ERROR CODES--------------------------------- //This is here just to make me happy and to have more consistant error strings :) @@ -71,9 +71,9 @@ static const char sModuleBadArgs[] = "Blender.Armature - Bad Arguments: "; PyObject* BonesDict_items(BPy_BonesDict *self) { if (self->editmode_flag){ - return PyDict_Items(self->editBoneDict); + return PyDict_Items(self->editbonesMap); }else{ - return PyDict_Items(self->dict); + return PyDict_Items(self->bonesMap); } } //------------------------Armature.bones.keys() @@ -81,9 +81,9 @@ PyObject* BonesDict_items(BPy_BonesDict *self) PyObject* BonesDict_keys(BPy_BonesDict *self) { if (self->editmode_flag){ - return PyDict_Keys(self->editBoneDict); + return PyDict_Keys(self->editbonesMap); }else{ - return PyDict_Keys(self->dict); + return PyDict_Keys(self->bonesMap); } } //------------------------Armature.bones.values() @@ -91,13 +91,13 @@ PyObject* BonesDict_keys(BPy_BonesDict *self) PyObject* BonesDict_values(BPy_BonesDict *self) { if (self->editmode_flag){ - return PyDict_Values(self->editBoneDict); + return PyDict_Values(self->editbonesMap); }else{ - return PyDict_Values(self->dict); + return PyDict_Values(self->bonesMap); } } //------------------ATTRIBUTE IMPLEMENTATION--------------------------- -//------------------TYPE_OBECT IMPLEMENTATION-------------------------- +//------------------TYPE_OBECT IMPLEMENTATION----------------------- //------------------------tp_doc //The __doc__ string for this object static char BPy_BonesDict_doc[] = "This is an internal subobject of armature\ @@ -114,32 +114,59 @@ static PyMethodDef BPy_BonesDict_methods[] = { "() - Returns the values from the dictionary"}, {NULL} }; +//-----------------(internal) +static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){ + Bone *bone = NULL; + PyObject *py_bone = NULL; -//------------------------tp_new -//This methods creates a new object (note it does not initialize it - only the building) -static PyObject *BonesDict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - BPy_BonesDict *py_BonesDict = NULL; - - py_BonesDict = (BPy_BonesDict*)type->tp_alloc(type, 0); - if (!py_BonesDict) - goto RuntimeError; - - py_BonesDict->dict = PyDict_New(); - if(!py_BonesDict->dict) - goto RuntimeError; - - py_BonesDict->editBoneDict = PyDict_New(); - if (py_BonesDict->editBoneDict == NULL) - goto RuntimeError; + for (bone = bones->first; bone; bone = bone->next){ + py_bone = PyBone_FromBone(bone); + if (!py_bone) + return -1; - py_BonesDict->editmode_flag = 0; + if(PyDict_SetItem(dictionary, + PyString_FromString(bone->name), py_bone) == -1){ + return -1; + } + Py_DECREF(py_bone); + if (bone->childbase.first) + BoneMapping_Init(dictionary, &bone->childbase); + } + return 0; +} +//-----------------(internal) +static int EditBoneMapping_Init(PyObject *dictionary, ListBase *editbones){ + EditBone *editbone = NULL; + PyObject *py_editbone = NULL; - return (PyObject*)py_BonesDict; + for (editbone = editbones->first; editbone; editbone = editbone->next){ + py_editbone = PyEditBone_FromEditBone(editbone); + if (!py_editbone) + return -1; -RuntimeError: - return EXPP_objError(PyExc_RuntimeError, "%s%s", - sBoneDictError, "Failed to create dictionary!"); + if(PyDict_SetItem(dictionary, + PyString_FromString(editbone->name), py_editbone) == -1){ + return -1; + } + Py_DECREF(py_editbone); + } + return 0; +} +//----------------- BonesDict_InitBones +static int BonesDict_InitBones(BPy_BonesDict *self) +{ + PyDict_Clear(self->bonesMap); + if (BoneMapping_Init(self->bonesMap, self->bones) == -1) + return 0; + return 1; +} +//----------------- BonesDict_InitEditBones +static int BonesDict_InitEditBones(BPy_BonesDict *self) +{ + PyDict_Clear(self->editbonesMap); + if (EditBoneMapping_Init(self->editbonesMap, &self->editbones) == -1) + return 0; + return 1; } //------------------------tp_repr //This is the string representation of the object @@ -153,13 +180,13 @@ static PyObject *BonesDict_repr(BPy_BonesDict *self) sprintf(buffer, "[Bone Dict: {"); strcat(str,buffer); if (self->editmode_flag){ - while (PyDict_Next(self->editBoneDict, &pos, &key, &value)) { + while (PyDict_Next(self->editbonesMap, &pos, &key, &value)) { sprintf(buffer, "%s : %s, ", PyString_AsString(key), PyString_AsString(value->ob_type->tp_repr(value))); strcat(str,buffer); } }else{ - while (PyDict_Next(self->dict, &pos, &key, &value)) { + while (PyDict_Next(self->bonesMap, &pos, &key, &value)) { sprintf(buffer, "%s : %s, ", PyString_AsString(key), PyString_AsString(value->ob_type->tp_repr(value))); strcat(str,buffer); @@ -174,9 +201,10 @@ static PyObject *BonesDict_repr(BPy_BonesDict *self) //This tells how to 'tear-down' our object when ref count hits 0 static void BonesDict_dealloc(BPy_BonesDict * self) { - Py_DECREF(self->dict); - Py_DECREF(self->editBoneDict); - ((PyObject*)self)->ob_type->tp_free((PyObject*)self); + Py_DECREF(self->bonesMap); + Py_DECREF(self->editbonesMap); + BLI_freelistN(&self->editbones); + BonesDict_Type.tp_free(self); return; } //------------------------mp_length @@ -184,9 +212,9 @@ static void BonesDict_dealloc(BPy_BonesDict * self) int BonesDict_len(BPy_BonesDict *self) { if (self->editmode_flag){ - return PyDict_Size(self->editBoneDict); + return BLI_countlist(&self->editbones); }else{ - return PyDict_Size(self->dict); + return BLI_countlist(self->bones); } } //-----------------------mp_subscript @@ -196,9 +224,9 @@ PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key) PyObject *value = NULL; if (self->editmode_flag){ - value = PyDict_GetItem(self->editBoneDict, key); + value = PyDict_GetItem(self->editbonesMap, key); }else{ - value = PyDict_GetItem(self->dict, key); + value = PyDict_GetItem(self->bonesMap, key); } if(value == NULL){ return EXPP_incr_ret(Py_None); @@ -209,29 +237,106 @@ PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key) //This does dict assignment - Bones['key'] = value int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value) { - char *key_str = "", *name = "", *misc = ""; - static char *kwlist[] = {"name", "misc", NULL}; + BPy_EditBone *editbone_for_deletion; + struct EditBone *editbone = NULL; + char *key_str = ""; - //Get the key name - if(key && PyString_Check(key)){ - key_str = PyString_AsString(key); - }else{ - goto AttributeError; - } - - //Parse the value for assignment - if(value && PyDict_Check(value)){ - if(!PyArg_ParseTupleAndKeywords(Py_BuildValue("()"), value, "|ss", kwlist, &name, &misc)){ + if (self->editmode_flag){ + //Get the key name + if(key && PyString_Check(key)){ + key_str = PyString_AsString(key); + }else{ goto AttributeError; } + //parse value for assignment + if (value && EditBoneObject_Check(value)){ + //create a new editbone + editbone = MEM_callocN(sizeof(EditBone), "eBone"); + BLI_strncpy(editbone->name, key_str, 32); + unique_editbone_name(editbone->name); + editbone->dist = ((BPy_EditBone*)value)->dist; + editbone->ease1 = ((BPy_EditBone*)value)->ease1; + editbone->ease2 = ((BPy_EditBone*)value)->ease2; + editbone->flag = ((BPy_EditBone*)value)->flag; + editbone->parent = ((BPy_EditBone*)value)->parent; + editbone->rad_head = ((BPy_EditBone*)value)->rad_head; + editbone->rad_tail = ((BPy_EditBone*)value)->rad_tail; + editbone->roll = ((BPy_EditBone*)value)->roll; + editbone->segments = ((BPy_EditBone*)value)->segments; + editbone->weight = ((BPy_EditBone*)value)->weight; + editbone->xwidth = ((BPy_EditBone*)value)->xwidth; + editbone->zwidth = ((BPy_EditBone*)value)->zwidth; + VECCOPY(editbone->head, ((BPy_EditBone*)value)->head); + VECCOPY(editbone->tail, ((BPy_EditBone*)value)->tail); + + //set object pointer + ((BPy_EditBone*)value)->editbone = editbone; + + //fix the bone's head position if flags indicate that it is 'connected' + if (editbone->flag & BONE_CONNECTED){ + if(!editbone->parent){ + ((BPy_EditBone*)value)->editbone = NULL; + MEM_freeN(editbone); + goto AttributeError3; + }else{ + VECCOPY(editbone->head, editbone->parent->tail); + } + } + + //set in editbonelist + BLI_addtail(&self->editbones, editbone); + + //set the new editbone in the mapping + if(PyDict_SetItemString(self->editbonesMap, key_str, value) == -1){ + ((BPy_EditBone*)value)->editbone = NULL; + BLI_freelinkN(&self->editbones, editbone); + goto RuntimeError; + } + }else if(!value){ + //they are trying to delete the bone using 'del' + if(PyDict_GetItem(self->editbonesMap, key) != NULL){ + /*first kill the datastruct then remove the item from the dict + and wait for GC to pick it up. + We have to delete the datastruct here because the tp_dealloc + doesn't handle it*/ + editbone_for_deletion = (BPy_EditBone*)PyDict_GetItem(self->editbonesMap, key); + /*this is ugly but you have to set the parent to NULL for else + editbones_to_armature will crash looking for this bone*/ + for (editbone = self->editbones.first; editbone; editbone = editbone->next){ + if (editbone->parent == editbone_for_deletion->editbone) + editbone->parent = NULL; + /*any parent's were connected to this we must remove the flag + or else the 'root' ball doesn't get draw*/ + if (editbone->flag & BONE_CONNECTED) + editbone->flag &= ~BONE_CONNECTED; + } + BLI_freelinkN(&self->editbones, editbone_for_deletion->editbone); + if(PyDict_DelItem(self->editbonesMap, key) == -1) + goto RuntimeError; + }else{ + goto KeyError; + } + } + return 0; }else{ - goto AttributeError; + goto AttributeError2; } - return 0; +KeyError: +return EXPP_intError(PyExc_KeyError, "%s%s%s%s", + sBoneDictError, "The key: ", key_str, " is not present in this dictionary!"); +RuntimeError: + return EXPP_intError(PyExc_RuntimeError, "%s%s", + sBoneDictError, "Unable to access dictionary!"); AttributeError: return EXPP_intError(PyExc_AttributeError, "%s%s", - sBoneDictBadArgs, "Expects (optional) name='string', misc='string'"); + sBoneDictBadArgs, "Expects EditboneType Object"); +AttributeError2: + return EXPP_intError(PyExc_AttributeError, "%s%s", + sBoneDictBadArgs, "You must call makeEditable() first"); +AttributeError3: + return EXPP_intError(PyExc_AttributeError, "%s%s", + sBoneDictBadArgs, "The 'connected' flag is set but the bone has no parent!"); } //------------------TYPE_OBECT DEFINITION-------------------------- //Mapping Protocol @@ -242,35 +347,35 @@ static PyMappingMethods BonesDict_MapMethods = { }; //BonesDict TypeObject PyTypeObject BonesDict_Type = { - PyObject_HEAD_INIT(NULL) //tp_head + PyObject_HEAD_INIT(NULL) //tp_head 0, //tp_internal "BonesDict", //tp_name - sizeof(BPy_BonesDict), //tp_basicsize + sizeof(BPy_BonesDict), //tp_basicsize 0, //tp_itemsize - (destructor)BonesDict_dealloc, //tp_dealloc + (destructor)BonesDict_dealloc, //tp_dealloc 0, //tp_print 0, //tp_getattr 0, //tp_setattr 0, //tp_compare - (reprfunc) BonesDict_repr, //tp_repr + (reprfunc) BonesDict_repr, //tp_repr 0, //tp_as_number 0, //tp_as_sequence - &BonesDict_MapMethods, //tp_as_mapping + &BonesDict_MapMethods, //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_BonesDict_doc, //tp_doc + Py_TPFLAGS_DEFAULT, //tp_flags + BPy_BonesDict_doc, //tp_doc 0, //tp_traverse 0, //tp_clear 0, //tp_richcompare 0, //tp_weaklistoffset 0, //tp_iter 0, //tp_iternext - BPy_BonesDict_methods, //tp_methods + BPy_BonesDict_methods, //tp_methods 0, //tp_members 0, //tp_getset 0, //tp_base @@ -278,9 +383,9 @@ PyTypeObject BonesDict_Type = { 0, //tp_descr_get 0, //tp_descr_set 0, //tp_dictoffset - 0, //tp_init + 0, //tp_init 0, //tp_alloc - (newfunc)BonesDict_new, //tp_new + 0, //tp_new 0, //tp_free 0, //tp_is_gc 0, //tp_bases @@ -290,232 +395,88 @@ PyTypeObject BonesDict_Type = { 0, //tp_weaklist 0 //tp_del }; -//-----------------(internal) -static int BonesDict_Init(PyObject *dictionary, ListBase *bones){ - Bone *bone = NULL; - PyObject *py_bone = NULL; +//-----------------------PyBonesDict_FromPyArmature +static PyObject *PyBonesDict_FromPyArmature(BPy_Armature *py_armature) +{ + BPy_BonesDict *py_BonesDict = NULL; - for (bone = bones->first; bone; bone = bone->next){ - py_bone = PyBone_FromBone(bone); - if (py_bone == NULL) - return -1; + //create py object + py_BonesDict = (BPy_BonesDict *)BonesDict_Type.tp_alloc(&BonesDict_Type, 0); + if (!py_BonesDict) + goto RuntimeError; - if(PyDict_SetItem(dictionary, PyString_FromString(bone->name), py_bone) == -1){ - goto RuntimeError; - } - if (bone->childbase.first) - BonesDict_Init(dictionary, &bone->childbase); - } - return 0; + //create internal dictionaries + py_BonesDict->bonesMap = PyDict_New(); + py_BonesDict->editbonesMap = PyDict_New(); + if (!py_BonesDict->bonesMap || !py_BonesDict->editbonesMap) + goto RuntimeError; + + //set listbase pointer + py_BonesDict->bones = &py_armature->armature->bonebase; + + //now that everything is setup - init the mappings + if (!BonesDict_InitBones(py_BonesDict)) + goto RuntimeError; + if (!BonesDict_InitEditBones(py_BonesDict)) + goto RuntimeError; + + //set editmode flag + py_BonesDict->editmode_flag = 0; + + return (PyObject*)py_BonesDict; RuntimeError: - return EXPP_intError(PyExc_RuntimeError, "%s%s", - sBoneDictError, "Internal error trying to wrap blender bones!"); + return EXPP_objError(PyExc_RuntimeError, "%s%s", + sBoneDictError, "Failed to create class"); } //######################### Armature_Type ############################# /*This type represents a thin wrapper around bArmature data types * internal to blender. It contains the psuedo-dictionary BonesDict * as an assistant in manipulating it's own bone collection*/ -//##################################################################### +//################################################################# //------------------METHOD IMPLEMENTATION------------------------------ -//This is a help function for Armature_makeEditable -static int PyArmature_InitEditBoneDict(PyObject *dictionary, ListBase *branch) -{ - struct Bone *bone = NULL; - PyObject *args, *py_editBone = NULL, *py_bone = NULL; - - for (bone = branch->first; bone; bone = bone->next){ - - //create a new editbone based on the bone data - py_bone = PyBone_FromBone(bone); //new - if (py_bone == NULL) - goto RuntimeError; - - args = Py_BuildValue("(O)",py_bone); //new - - py_editBone = EditBone_Type.tp_new(&EditBone_Type, args, NULL); //new - if (py_editBone == NULL) - goto RuntimeError; - - //add the new editbone to the dictionary - if (PyDict_SetItemString(dictionary, bone->name, py_editBone) == -1) - goto RuntimeError; - - if(bone->childbase.first){ - PyArmature_InitEditBoneDict(dictionary, &bone->childbase); - } - } - return 0; - -RuntimeError: - return EXPP_intError(PyExc_RuntimeError, "%s%s", - sArmatureError, "Internal error trying to construct an edit armature!"); - -} //------------------------Armature.makeEditable() static PyObject *Armature_makeEditable(BPy_Armature *self) { - if (PyArmature_InitEditBoneDict(((BPy_BonesDict*)self->Bones)->editBoneDict, - &self->armature->bonebase) == -1){ - return NULL; //error already set - } - ((BPy_BonesDict*)self->Bones)->editmode_flag = 1; - return EXPP_incr_ret(Py_None); -} - -static void PyArmature_FixRolls(ListBase *branch, PyObject *dictionary) -{ - float premat[3][3],postmat[3][3]; - float difmat[3][3],imat[3][3], delta[3]; - BPy_EditBone *py_editBone = NULL; - struct Bone *bone = NULL; - int keyCheck = -1; - - for (bone = branch->first; bone; bone = bone->next){ - - where_is_armature_bone(bone, bone->parent); //set bone_mat, arm_mat, length, etc. - - keyCheck = PySequence_Contains(dictionary, PyString_FromString(bone->name)); - if (keyCheck == 1){ - - py_editBone = (BPy_EditBone*)PyDict_GetItem(dictionary, - PyString_FromString(bone->name)); //borrowed - VecSubf (delta, py_editBone->tail, py_editBone->head); - vec_roll_to_mat3(delta, py_editBone->roll, premat); //pre-matrix - Mat3CpyMat4(postmat, bone->arm_mat); //post-matrix - Mat3Inv(imat, premat); - Mat3MulMat3(difmat, imat, postmat); - - bone->roll = (float)-atan(difmat[2][0]/difmat[2][2]); //YEA!! - if (difmat[0][0]<0.0){ - bone->roll += (float)M_PI; - } + if (self->armature->flag & ARM_EDITMODE) + goto AttributeError; - where_is_armature_bone(bone, bone->parent); //gotta do it again... - }else if (keyCheck == 0){ - //oops we couldn't find it - }else{ - //error - } - PyArmature_FixRolls (&bone->childbase, dictionary); - } -} -//------------------------(internal)EditBoneDict_CheckForKey -static BPy_EditBone *EditBoneDict_CheckForKey(BPy_BonesDict *dictionary, char *name) -{ - BPy_EditBone *editbone; - PyObject *value, *key; - int pos = 0; + make_boneList(&self->Bones->editbones, self->Bones->bones, NULL); + if (!BonesDict_InitEditBones(self->Bones)) + return NULL; + self->Bones->editmode_flag = 1; + return EXPP_incr_ret(Py_None); - while (PyDict_Next(dictionary->editBoneDict, &pos, &key, &value)) { - editbone = (BPy_EditBone *)value; - if (STREQ(editbone->name, name)){ - Py_INCREF(editbone); - return editbone; - } - } - return NULL; +AttributeError: + return EXPP_objError(PyExc_AttributeError, "%s%s", + sArmatureBadArgs, "The armature cannot be placed manually in editmode before you call makeEditable()!"); } -//------------------------Armature.saveChanges() -static PyObject *Armature_saveChanges(BPy_Armature *self) +//------------------------Armature.update() +//This is a bit ugly because you need an object link to do this +static PyObject *Armature_update(BPy_Armature *self) { - float M_boneRest[3][3], M_parentRest[3][3]; - float iM_parentRest[3][3], delta[3]; - BPy_EditBone *parent = NULL, *editbone = NULL; - struct Bone *bone = NULL; - struct Object *obj = NULL; - PyObject *key, *value; - int pos = 0; + Object *obj = NULL; - //empty armature of old bones - free_bones(self->armature); - - //create a new set based on the editbones - while (PyDict_Next(((BPy_BonesDict*)self->Bones)->editBoneDict, &pos, &key, &value)) { - - editbone = (BPy_EditBone*)value; - bone = MEM_callocN (sizeof(Bone), "bone"); - editbone->temp = bone; //save temp pointer - - strcpy (bone->name, editbone->name); - memcpy (bone->head, editbone->head, sizeof(float)*3); - memcpy (bone->tail, editbone->tail, sizeof(float)*3); - bone->flag= editbone->flag; - bone->roll = 0.0f; //is fixed later - bone->weight = editbone->weight; - bone->dist = editbone->dist; - bone->xwidth = editbone->xwidth; - bone->zwidth = editbone->zwidth; - bone->ease1= editbone->ease1; - bone->ease2= editbone->ease2; - bone->rad_head= editbone->rad_head; - bone->rad_tail= editbone->rad_tail; - bone->segments= editbone->segments; + for (obj = G.main->object.first; obj; obj = obj->id.next){ + if (obj->data == self->armature) + break; } + if (obj){ + editbones_to_armature (&self->Bones->editbones, obj); + if (!BonesDict_InitBones(self->Bones)) + return NULL; + self->Bones->editmode_flag = 0; + }else{ + goto AttributeError; - pos = 0; - //place bones in their correct heirarchy - while (PyDict_Next(((BPy_BonesDict*)self->Bones)->editBoneDict, - &pos, &key, &value)) { - - editbone = (BPy_EditBone*)value; - bone = editbone->temp; //get bone pointer - - if (!STREQ(editbone->parent, "")){ - parent = EditBoneDict_CheckForKey((BPy_BonesDict*)self->Bones, editbone->parent); - if(parent != NULL){ - - //parent found in dictionary - bone->parent = parent->temp; - BLI_addtail (&parent->temp->childbase, bone); - //Parenting calculations - VecSubf (delta, parent->tail, parent->head); - vec_roll_to_mat3(delta, parent->roll, M_parentRest); //M_parentRest = parent matrix - VecSubf (delta, editbone->tail, editbone->head); - vec_roll_to_mat3(delta, editbone->roll, M_boneRest); //M_boneRest = bone matrix - Mat3Inv(iM_parentRest, M_parentRest); //iM_parentRest = 1/parent matrix - //get head/tail - VecSubf (bone->head, editbone->head, parent->tail); - VecSubf (bone->tail, editbone->tail, parent->tail); - //put them in parentspace - Mat3MulVecfl(iM_parentRest, bone->head); - Mat3MulVecfl(iM_parentRest, bone->tail); - - Py_DECREF(parent); - }else{ - //was not found - most likely parent was deleted - parent = NULL; - BLI_addtail (&self->armature->bonebase, bone); - } - }else{ - BLI_addtail (&self->armature->bonebase, bone); - } - } - //fix rolls and generate matrices - PyArmature_FixRolls(&self->armature->bonebase, - ((BPy_BonesDict*)self->Bones)->editBoneDict); - - //update linked objects - for(obj = G.main->object.first; obj; obj = obj->id.next) { - if(obj->data == self->armature){ - armature_rebuild_pose(obj, self->armature); - } } - DAG_object_flush_update(G.scene, obj, OB_RECALC_DATA); - - //clear the editbone dictionary and set edit flag - PyDict_Clear(((BPy_BonesDict*)self->Bones)->editBoneDict); - ((BPy_BonesDict*)self->Bones)->editmode_flag = 0; - - //rebuild py_bones - PyDict_Clear(((BPy_BonesDict*)self->Bones)->dict); - if (BonesDict_Init(((BPy_BonesDict*)self->Bones)->dict, - &self->armature->bonebase) == -1) - return NULL; //error string already set - return EXPP_incr_ret(Py_None); + +AttributeError: + return EXPP_objError(PyExc_AttributeError, "%s%s", + sArmatureBadArgs, "The armature must be linked to an object before you can save changes!"); } //------------------ATTRIBUTE IMPLEMENTATION--------------------------- //------------------------Armature.autoIK (getter) @@ -945,7 +906,7 @@ AttributeError: //Gets the name of the armature static PyObject *Armature_getBoneDict(BPy_Armature *self, void *closure) { - return EXPP_incr_ret(self->Bones); + return EXPP_incr_ret((PyObject*)self->Bones); } //------------------------Armature.bones (setter) //Sets the name of the armature @@ -963,17 +924,15 @@ AttributeError: //------------------------tp_doc //The __doc__ string for this object static char BPy_Armature_doc[] = "This object wraps a Blender Armature object."; - //------------------------tp_methods //This contains a list of all methods the object contains static PyMethodDef BPy_Armature_methods[] = { {"makeEditable", (PyCFunction) Armature_makeEditable, METH_NOARGS, "() - Unlocks the ability to modify armature bones"}, - {"saveChanges", (PyCFunction) Armature_saveChanges, METH_NOARGS, + {"update", (PyCFunction) Armature_update, METH_NOARGS, "() - Rebuilds the armature based on changes to bones since the last call to makeEditable"}, {NULL} }; - //------------------------tp_getset //This contains methods for attributes that require checking static PyGetSetDef BPy_Armature_getset[] = { @@ -1014,7 +973,6 @@ static PyObject *Armature_new(PyTypeObject *type, PyObject *args, PyObject *kwds { BPy_Armature *py_armature = NULL; bArmature *bl_armature; - int success; bl_armature = add_armature(); if(bl_armature) { @@ -1026,13 +984,11 @@ static PyObject *Armature_new(PyTypeObject *type, PyObject *args, PyObject *kwds py_armature->armature = bl_armature; - py_armature->Bones = BonesDict_new(&BonesDict_Type, NULL, NULL); - if (py_armature->Bones == NULL) + //create armature.bones + py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature); + if (!py_armature->Bones) goto RuntimeError; - success = BonesDict_Init(((BPy_BonesDict*)py_armature->Bones)->dict, &bl_armature->bonebase); - if (success == -1) - return NULL; //error string already set } else { goto RuntimeError; } @@ -1061,7 +1017,6 @@ static int Armature_init(BPy_Armature *self, PyObject *args, PyObject *kwds) PyOS_snprintf(buf, sizeof(buf), "%s", name); rename_id(&self->armature->id, buf); } - return 0; AttributeError: @@ -1075,21 +1030,19 @@ static PyObject *Armature_richcmpr(BPy_Armature *self, PyObject *v, int op) { return EXPP_incr_ret(Py_None); } - //------------------------tp_repr //This is the string representation of the object static PyObject *Armature_repr(BPy_Armature *self) { return PyString_FromFormat( "[Armature: \"%s\"]", self->armature->id.name + 2 ); //*new* } - //------------------------tp_dealloc //This tells how to 'tear-down' our object when ref count hits 0 ///tp_dealloc static void Armature_dealloc(BPy_Armature * self) { Py_DECREF(self->Bones); - ((PyObject*)self)->ob_type->tp_free((PyObject*)self); + Armature_Type.tp_free(self); return; } //------------------TYPE_OBECT DEFINITION-------------------------- @@ -1159,7 +1112,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args) size = PySequence_Length(args); if (size == 1) { seq = PySequence_GetItem(args, 0); //*new* - if (seq == NULL) + if (!seq) goto RuntimeError; if(!PyString_Check(seq)){ if (PySequence_Check(seq)) { @@ -1176,7 +1129,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args) if(!PyString_Check(seq)){ for(i = 0; i < size; i++){ item = PySequence_GetItem(seq, i); //*new* - if (item == NULL) { + if (!item) { Py_DECREF(seq); goto RuntimeError; } @@ -1191,7 +1144,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args) //GET ARMATURES if(size != 1){ dict = PyDict_New(); //*new* - if(dict == NULL){ + if(!dict){ Py_DECREF(seq); goto RuntimeError; } @@ -1204,6 +1157,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args) EXPP_decr3(seq, dict, py_armature); goto RuntimeError; } + Py_DECREF(py_armature); data = ((ID*)data)->next; } Py_DECREF(seq); @@ -1219,16 +1173,18 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args) EXPP_decr3(seq, dict, py_armature); goto RuntimeError; } + Py_DECREF(py_armature); }else{ if(PyDict_SetItemString(dict, name, Py_None) == -1){ //add to dictionary EXPP_decr2(seq, dict); goto RuntimeError; } + Py_DECREF(Py_None); } } Py_DECREF(seq); } - return dict; //transfering ownership to caller + return dict; }else{ //GET SINGLE ARMATURE if(!PyString_Check(seq)){ //This handles the bizarre case where (['s']) is passed item = PySequence_GetItem(seq, 0); //*new* @@ -1272,22 +1228,18 @@ struct PyMethodDef M_Armature_methods[] = { PyObject *PyArmature_FromArmature(struct bArmature *armature) { BPy_Armature *py_armature = NULL; - int success; + //create armature type py_armature = (BPy_Armature*)Armature_Type.tp_alloc(&Armature_Type, 0); //*new* - if (py_armature == NULL) + if (!py_armature) goto RuntimeError; - py_armature->armature = armature; - py_armature->Bones = BonesDict_new(&BonesDict_Type, NULL, NULL); //*new* - if (py_armature->Bones == NULL) + //create armature.bones + py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature); + if (!py_armature->Bones) goto RuntimeError; - success = BonesDict_Init(((BPy_BonesDict*)py_armature->Bones)->dict, &armature->bonebase); - if (success == -1) - return NULL; //error string already set - return (PyObject *) py_armature; RuntimeError: @@ -1307,7 +1259,7 @@ PyObject *Armature_Init(void) //Initializes TypeObject.ob_type if (PyType_Ready(&Armature_Type) < 0 || PyType_Ready(&BonesDict_Type) < 0 || - PyType_Ready(&EditBone_Type) < 0 || PyType_Ready(&Bone_Type) < 0){ + PyType_Ready(&EditBone_Type) < 0 || PyType_Ready(&Bone_Type) < 0) { return EXPP_incr_ret(Py_None); } @@ -1316,10 +1268,12 @@ PyObject *Armature_Init(void) "The Blender Armature module"); //Add TYPEOBJECTS to the module - PyModule_AddObject(module, "ArmatureType", + PyModule_AddObject(module, "Armature", EXPP_incr_ret((PyObject *)&Armature_Type)); //*steals* - PyModule_AddObject(module, "BoneType", + PyModule_AddObject(module, "Bone", EXPP_incr_ret((PyObject *)&Bone_Type)); //*steals* + PyModule_AddObject(module, "Editbone", + EXPP_incr_ret((PyObject *)&EditBone_Type)); //*steals* //Add CONSTANTS to the module PyModule_AddObject(module, "CONNECTED", @@ -1332,13 +1286,12 @@ PyObject *Armature_Init(void) EXPP_incr_ret(PyConstant_NewInt("MULTIPLY", BONE_MULT_VG_ENV))); PyModule_AddObject(module, "HIDDEN_EDIT", EXPP_incr_ret(PyConstant_NewInt("HIDDEN_EDIT", BONE_HIDDEN_A))); - - PyModule_AddObject(module, "BONESPACE", - EXPP_incr_ret(PyConstant_NewString("BONESPACE", "bone_space"))); - PyModule_AddObject(module, "ARMATURESPACE", - EXPP_incr_ret(PyConstant_NewString("ARMATURESPACE", "armature_space"))); - PyModule_AddObject(module, "WORLDSPACE", - EXPP_incr_ret(PyConstant_NewString("WORLDSPACE", "world_space"))); + PyModule_AddObject(module, "ROOT_SELECTED", + EXPP_incr_ret(PyConstant_NewInt("ROOT_SELECTED", BONE_ROOTSEL))); + PyModule_AddObject(module, "BONE_SELECTED", + EXPP_incr_ret(PyConstant_NewInt("BONE_SELECTED", BONE_SELECTED))); + PyModule_AddObject(module, "TIP_SELECTED", + EXPP_incr_ret(PyConstant_NewInt("TIP_SELECTED", BONE_TIPSEL))); PyModule_AddObject(module, "OCTAHEDRON", EXPP_incr_ret(PyConstant_NewInt("OCTAHEDRON", ARM_OCTA))); diff --git a/source/blender/python/api2_2x/Armature.h b/source/blender/python/api2_2x/Armature.h index 473a2392931..4d14b41fdc8 100644 --- a/source/blender/python/api2_2x/Armature.h +++ b/source/blender/python/api2_2x/Armature.h @@ -43,18 +43,19 @@ PyObject *Armature_Init( void ); PyTypeObject Armature_Type; PyTypeObject BonesDict_Type; //-------------------STRUCT DEFINITION--------------------------- - typedef struct { PyObject_HEAD - PyObject *dict; - PyObject *editBoneDict; - short editmode_flag; //1 = in , 0 = not in + PyObject *bonesMap; //wrapper for bones + PyObject *editbonesMap; //wrapper for editbones + ListBase *bones; //pointer to armature->bonebase + ListBase editbones; //allocated list of EditBones + short editmode_flag; //1 = in , 0 = not in } BPy_BonesDict; typedef struct { PyObject_HEAD struct bArmature * armature; - PyObject *Bones; + BPy_BonesDict *Bones; //BPy_BonesDict } BPy_Armature; //-------------------VISIBLE PROTOTYPES------------------------- 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) { diff --git a/source/blender/python/api2_2x/Bone.h b/source/blender/python/api2_2x/Bone.h index 2bdcfb2b120..aa095733d05 100644 --- a/source/blender/python/api2_2x/Bone.h +++ b/source/blender/python/api2_2x/Bone.h @@ -41,6 +41,7 @@ PyTypeObject EditBone_Type; PyTypeObject Bone_Type; //-------------------STRUCT DEFINITION---------------------------- + typedef struct { PyObject_HEAD Bone * bone; @@ -48,14 +49,13 @@ typedef struct { typedef struct { PyObject_HEAD - struct Bone *temp; //temp tracking - char parent[32]; + struct EditBone *editbone; + struct EditBone *parent; char name[32]; float roll; float head[3]; float tail[3]; int flag; - float length; float dist; float weight; float xwidth; @@ -69,75 +69,7 @@ typedef struct { //-------------------VISIBLE PROTOTYPES------------------------- PyObject *PyBone_FromBone(struct Bone *bone); struct Bone *PyBone_AsBone(BPy_Bone *py_Bone); +PyObject *PyEditBone_FromBone(Bone *bone); +PyObject *PyEditBone_FromEditBone(struct EditBone *editbone); #endif - - - - - - - - - - - - - - - - - - - - - - - - - -/* -#ifndef EXPP_BONE_H -#define EXPP_BONE_H - -#include <Python.h> -#include "DNA_armature_types.h" -#include "Mathutils.h" - -//--------------------------Python BPy_Bone structure definition.------- -typedef struct { - PyObject_HEAD - //reference to data if bone is linked to an armature - Bone * bone; - //list of vars that define the bone - char *name; - char *parent; - float roll; - int flag; - float dist; - float weight; - VectorObject *head; - VectorObject *tail; - VectorObject *loc; - VectorObject *dloc; - VectorObject *size; - VectorObject *dsize; - QuaternionObject *quat; - QuaternionObject *dquat; - MatrixObject *obmat; - MatrixObject *parmat; - MatrixObject *defmat; - MatrixObject *irestmat; - MatrixObject *posemat; -} BPy_Bone; - -//------------------------------visible prototypes---------------------- -PyObject *Bone_CreatePyObject( struct Bone *obj ); -int Bone_CheckPyObject( PyObject * py_obj ); -Bone *Bone_FromPyObject( PyObject * py_obj ); -PyObject *Bone_Init( void ); -int updateBoneData( BPy_Bone * self, Bone * parent ); - -#endif - -*/ diff --git a/source/blender/python/api2_2x/Image.c b/source/blender/python/api2_2x/Image.c index b81fb1aa5d2..70f69ac840b 100644 --- a/source/blender/python/api2_2x/Image.c +++ b/source/blender/python/api2_2x/Image.c @@ -69,6 +69,7 @@ short IMB_saveiff( struct ImBuf *ibuf, char *naam, int flags ); /*static PyObject *M_Image_New( PyObject * self, PyObject * args, PyObject * keywords );*/ static PyObject *M_Image_Get( PyObject * self, PyObject * args ); +static PyObject *M_Image_GetCurrent( PyObject * self ); static PyObject *M_Image_Load( PyObject * self, PyObject * args ); /*****************************************************************************/ @@ -86,6 +87,10 @@ static char M_Image_Get_doc[] = returns None if not found.\n If 'name' is not specified, \ it returns a list of all images in the\ncurrent scene."; +static char M_Image_GetCurrent_doc[] = + "() - return the current image, from last active the uv/image view, \ +returns None no image is in the view.\n"; + static char M_Image_Load_doc[] = "(filename) - return image from file filename as Image Object, \ returns None if not found.\n"; @@ -96,9 +101,10 @@ returns None if not found.\n"; struct PyMethodDef M_Image_methods[] = { /*{"New", ( PyCFunction ) M_Image_New, METH_VARARGS | METH_KEYWORDS, M_Image_New_doc}, */ - {"Get", M_Image_Get, METH_VARARGS, M_Image_Get_doc}, - {"get", M_Image_Get, METH_VARARGS, M_Image_Get_doc}, - {"Load", M_Image_Load, METH_VARARGS, M_Image_Load_doc}, + {"Get", (PyCFunction) M_Image_Get, METH_VARARGS, M_Image_Get_doc}, + {"GetCurrent", (PyCFunction) M_Image_GetCurrent, METH_NOARGS, M_Image_GetCurrent_doc}, + {"get", (PyCFunction) M_Image_Get, METH_VARARGS, M_Image_Get_doc}, + {"Load", (PyCFunction) M_Image_Load, METH_VARARGS, M_Image_Load_doc}, {NULL, NULL, 0, NULL} }; @@ -170,11 +176,6 @@ static PyObject *M_Image_Get( PyObject * self, PyObject * args ) while( img_iter ) { pyobj = Image_CreatePyObject( img_iter ); - if( !pyobj ) - return ( EXPP_ReturnPyObjError - ( PyExc_MemoryError, - "couldn't create PyObject" ) ); - PyList_SET_ITEM( img_list, index, pyobj ); img_iter = img_iter->id.next; @@ -185,6 +186,28 @@ static PyObject *M_Image_Get( PyObject * self, PyObject * args ) } } + + +/*****************************************************************************/ +/* Function: M_Image_GetCurrent */ +/* Python equivalent: Blender.Image.GetCurrent */ +/* Description: Returns the active current (G.sima) */ +/* This will be the image last under the mouse cursor */ +/* None if there is no Image. */ +/*****************************************************************************/ +static PyObject *M_Image_GetCurrent( PyObject * self ) +{ + PyObject *current_img; + if (!G.sima || !G.sima->image) { + Py_RETURN_NONE; + } + current_img = Image_CreatePyObject( G.sima->image ); + return current_img; +} + + + + /*****************************************************************************/ /* Function: M_Image_Load */ /* Python equivalent: Blender.Image.Load */ @@ -674,15 +697,13 @@ static void Image_dealloc( BPy_Image * self ) PyObject *Image_CreatePyObject( Image * image ) { BPy_Image *py_img; - py_img = ( BPy_Image * ) PyObject_NEW( BPy_Image, &Image_Type ); - + if( !py_img ) return EXPP_ReturnPyObjError( PyExc_MemoryError, "couldn't create BPy_Image object" ); - + py_img->image = image; - return ( PyObject * ) py_img; } diff --git a/source/blender/python/api2_2x/Library.c b/source/blender/python/api2_2x/Library.c index a4b97bfeef6..32c2c9792d4 100644 --- a/source/blender/python/api2_2x/Library.c +++ b/source/blender/python/api2_2x/Library.c @@ -42,6 +42,7 @@ #include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BLI_blenlib.h" #include "BLO_readfile.h" #include "BLI_linklist.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c index d4ef5b79c0e..ec5d75f16df 100644 --- a/source/blender/python/api2_2x/Mesh.c +++ b/source/blender/python/api2_2x/Mesh.c @@ -1696,6 +1696,18 @@ static PyObject *MVertSeq_extend( BPy_MVertSeq * self, PyObject *args ) } } + /* + * if there are vertex groups, also have to fix them + */ + + if( mesh->dvert ) { + MDeformVert *newdvert; + newdvert = MEM_callocN( sizeof(MDeformVert)*newlen , "mesh defVert" ); + memcpy( newdvert, mesh->dvert, sizeof(MDeformVert)*mesh->totvert ); + MEM_freeN( mesh->dvert ); + mesh->dvert = newdvert; + } + /* set final vertex list size */ mesh->totvert = newlen; @@ -4842,13 +4854,18 @@ static PyObject *Mesh_getFromObject( BPy_Mesh * self, PyObject * args ) /* save a copy of our ID, dup the temporary mesh, restore the ID */ tmpid = self->mesh->id; memcpy( self->mesh, tmpmesh, sizeof( Mesh ) ); - self->mesh->id= tmpid; + self->mesh->id = tmpid; + + /* if mesh has keys, make sure they point back to this mesh */ + if( self->mesh->key ) + self->mesh->key->from = (ID *)self->mesh; + /* remove the temporary mesh */ BLI_remlink( &G.main->mesh, tmpmesh ); MEM_freeN( tmpmesh ); /* make sure materials get updated in objects */ - test_object_materials( ( ID * ) self->mesh ); + test_object_materials( ( ID * ) self->mesh ); mesh_update( self->mesh ); return EXPP_incr_ret( Py_None ); diff --git a/source/blender/python/api2_2x/doc/API_intro.py b/source/blender/python/api2_2x/doc/API_intro.py index 31ab333f231..9a7c16d5168 100644 --- a/source/blender/python/api2_2x/doc/API_intro.py +++ b/source/blender/python/api2_2x/doc/API_intro.py @@ -13,7 +13,7 @@ The Blender Python API Reference Submodules: ----------- - - L{Armature} (work in progress) + - L{Armature} - L{NLA} - L{BGL} - L{Camera} diff --git a/source/blender/python/api2_2x/doc/Armature.py b/source/blender/python/api2_2x/doc/Armature.py index 93fec9e96fb..79f9481192d 100644 --- a/source/blender/python/api2_2x/doc/Armature.py +++ b/source/blender/python/api2_2x/doc/Armature.py @@ -12,14 +12,60 @@ example. Example:: import Blender - from Blender import Armature + from Blender import Armature as A + from Blender.Mathutils import * # - armatures = Armature.Get() - for a in armatures: - print "Armature ", a - for bone_name, bone in a.bones.items(): - print bone_name, bone.weight + arms = A.Get() + for arm in arms.values(): + arm.drawType = A.STICK #set the draw type + arm.makeEditable() #enter editmode + #generating new editbone + eb = A.Editbone() + eb.roll = 10 + eb.parent = arm.bones['Bone.003'] + eb.head = Vector(1,1,1) + eb.tail = Vector(0,0,1) + eb.options = [A.HINGE, A.CONNECTED] + + #add the bone + arm.bones['myNewBone'] = eb + + #delete an old bone + del arm.bones['Bone.002'] + + arm.update() #save changes + + for bone in arm.bones.values(): + #print bone.matrix['ARMATURESPACE'] + print bone.parent, bone.name + print bone.children, bone.name + print bone.options, bone.name + +@var CONNECTED: Connect this bone to parent +@type CONNECTED: Constant +@var HINGE: Don't inherit rotation or scale from parent +@type HINGE: Constant +@var NO_DEFORM: If bone will not deform geometry +@type NO_DEFORM: Constant +@var MULTIPLY: Multiply bone with vertex group +@type MULTIPLY: Constant +@var HIDDEN_EDIT: Bone is hidden in editmode +@type HIDDEN_EDIT: Constant +@var ROOT_SELECTED: Root of the Bone is selected +@type ROOT_SELECTED: Constant +@var BONE_SELECTED: Bone is selected +@type BONE_SELECTED: Constant +@var TIP_SELECTED: Tip of the Bone is selected +@type TIP_SELECTED: Constant +@var OCTAHEDRON: Bones drawn as octahedrons +@type OCTAHEDRON: Constant +@var STICK: Bones drawn as a line +@type STICK: Constant +@var BBONE: Bones draw as a segmented B-spline +@type BBONE: Constant +@var ENVELOPE: Bones draw as a stick with envelope influence +@type ENVELOPE: Constant """ def Get (name = None): @@ -34,58 +80,85 @@ def Get (name = None): - (): A list with all Armature objects in the current scene. """ -class ArmatureType: +class Armature: """ - The ArmatureType object - ======================= + The Armature object + =================== This object gives access to Armature-specific data in Blender. @ivar name: The Armature name. - @ivar bones: A Dictionary of Bones that make up this armature. - @ivar vertexGroups: (bool) Whether vertex groups define deformation - @ivar envelopes: (bool) Whether bone envelopes define deformation - @ivar restPosition: (bool) Show rest position (no posing possible) - @ivar delayDeform: (bool) Dont deform children when manipulating bones - @ivar drawAxes: (bool) Draw bone axes - @ivar drawNames: (bool) Draw bone names + @type name: String + @ivar bones: A Dictionary of Bones (BonesDict) that make up this armature. + @type bones: BonesDict Object + @ivar vertexGroups: Whether vertex groups define deformation + @type vertexGroups: Bool + @ivar envelopes: Whether bone envelopes define deformation + @type envelopes: Bool + @ivar restPosition: Show rest position (no posing possible) + @type restPosition: Bool + @ivar delayDeform: Dont deform children when manipulating bones + @type delayDeform: Bool + @ivar drawAxes: Draw bone axes + @type drawAxes: Bool + @ivar drawNames: Draw bone names + @type drawNames: Bool @ivar ghost: Draw ghosts around frame for current Action + @type ghost: Bool @ivar ghostStep: Number of frames between ghosts + @type ghostStep: Int @ivar drawType: The drawing type that is used to display the armature Acceptable values are: - Armature.OCTAHEDRON: bones drawn as octahedrons - Armature.STICK: bones drawn as sticks - Armature.BBONE: bones drawn as b-bones - Armature.ENVELOPE: bones drawn as sticks with envelopes - @ivar mirrorEdit: (bool) X-axis mirrored editing - @ivar autoIK: (bool) Adds temporary IK chains while grabbing bones + @type drawType: Constant Object + @ivar mirrorEdit: X-axis mirrored editing + @type mirrorEdit: Bool + @ivar autoIK: Adds temporary IK chains while grabbing bones + @type autoIK: Bool """ def __init__(name = 'myArmature'): """ - Initializer for the ArmatureType TypeObject. + Initializer for the Armature TypeObject. Example:: - myNewArmature = Blender.Armature.ArmatureType('AR_1') + myNewArmature = Blender.Armature.Armature('AR_1') @param name: The name for the new armature @type name: string + @return: New Armature Object + @rtype: Armature Object """ def makeEditable(): """ Put the armature into EditMode for editing purposes. @warning: The armature should not be in manual editmode - prior to calling this method. + prior to calling this method. The armature must be parented + to an object prior to editing. + @rtype: None """ - def saveChanges(): + def update(): """ Save all changes and update the armature. @note: Must have called makeEditable() first. + @rtype: None """ class BonesDict: """ The BonesDict object ==================== - This object gives gives dictionary like access to the bones in an armature. + This object gives gives dictionary like access to the bones in an armature. + It is internal to blender but is called as 'Armature.bones' + + Removing a bone: + Example:: + del myArmature.bones['bone_name'] + Adding a bone: + Example:: + myEditBone = Armature.Editbone() + myArmature.bones['bone_name'] = myEditBone """ def items(): @@ -109,25 +182,116 @@ class BonesDict: @return: All BPy_bones in this dictionary """ -class BoneType: +class Bone: """ - The BoneType object - =================== - This object gives access to Bone-specific data in Blender. + The Bone object + =============== + This object gives access to Bone-specific data in Blender. This object + cannot be instantiated but is returned by BonesDict when the armature is not in editmode. @ivar name: The name of this Bone. + @type name: String @ivar roll: This Bone's roll value. + Keys are: + - 'ARMATURESPACE' - this roll in relation to the armature + - 'BONESPACE' - the roll in relation to itself + @type roll: Dictionary @ivar head: This Bone's "head" ending position when in rest state. + Keys are: + - 'ARMATURESPACE' - this head position in relation to the armature + - 'BONESPACE' - the head position in relation to itself + @type head: Dictionary @ivar tail: This Bone's "tail" ending position when in rest state. - @ivar matrix: This Bone's matrix. + Keys are: + - 'ARMATURESPACE' - this tail position in relation to the armature + - 'BONESPACE' - the tail position in relation to itself + @type tail: Dictionary + @ivar matrix: This Bone's matrix. This cannot be set. + Keys are: + - 'ARMATURESPACE' - this matrix of the bone in relation to the armature + - 'BONESPACE' - the matrix of the bone in relation to itself + @type matrix: Matrix Object @ivar parent: The parent Bone. + @type parent: Bone Object @ivar children: The children bones. + @type children: List of Bone Objects + @ivar weight: The bone's weight. + @type weight: Float + @ivar options: Various bone options which can be: + - Armature.CONNECTED: IK to parent + - Armature.HINGE: No parent rotation or scaling + - Armature.NO_DEFORM: The bone does not deform geometetry + - Armature.MULTIPLY: Multiply vgroups by envelope + - Armature.HIDDEN_EDIT: Hide bones in editmode + - Armature.ROOT_SELECTED: Selection of root ball of bone + - Armature.BONE_SELECTED: Selection of bone + - Armature.TIP_SELECTED: Selection of tip ball of bone + @type options: List of Constants + @ivar subdivision: The number of bone subdivisions. + @type subdivision: Int + @ivar deformDist: The deform distance of the bone + @type deformDist: Float + @ivar length: The length of the bone. This cannot be set. + @type length: Float + """ + + def hasParent(): + """ + Whether or not this bone has a parent + @rtype: Bool + """ + + def hasChildren(): + """ + Whether or not this bone has children + @rtype: Bool + """ + +class Editbone: + """ + The Editbone Object + =================== + This object is a wrapper for editbone data and is used only in the manipulation + of the armature in editmode. + @ivar name: The name of this Bone. + @type name: String + @ivar roll: This Bone's roll value (armaturespace). + @type roll: Float + @ivar head: This Bone's "head" ending position when in rest state (armaturespace). + @type head: Vector Object + @ivar tail: This Bone's "tail" ending position when in rest state (armaturespace). + @type tail: Vector Object + @ivar matrix: This Bone's matrix. (armaturespace) This cannot be set. + @type matrix: Matrix Object + @ivar parent: The parent Bone. + @type parent: Editbone Object @ivar weight: The bone's weight. + @type weight: Float @ivar options: Various bone options which can be: - -CONNECTED: IK to parent - -HINGE: No parent rotation or scaling - -NO_DEFORM: The bone does not deform geometetry - -MULTIPLY: Multiply vgroups by envelope - -HIDDEN_EDIT: Hide bones in editmode + - Armature.CONNECTED: IK to parent + - Armature.HINGE: No parent rotation or scaling + - Armature.NO_DEFORM: The bone does not deform geometetry + - Armature.MULTIPLY: Multiply vgroups by envelope + - Armature.HIDDEN_EDIT: Hide bones in editmode + - Armature.ROOT_SELECTED: Selection of root ball of bone + - Armature.BONE_SELECTED: Selection of bone + - Armature.TIP_SELECTED: Selection of tip ball of bone + @type options: List of Constants @ivar subdivision: The number of bone subdivisions. - @ivar deform_dist: The deform distance of the bone - """
\ No newline at end of file + @type subdivision: Int + @ivar deformDist: The deform distance of the bone + @type deformDist: Float + @ivar length: The length of the bone. This cannot be set. + @type length: Float + """ + + def hasParent(): + """ + Whether or not this bone has a parent + @rtype: Bool + """ + + def clearParent(): + """ + Set the parent to None + @rtype: None + """ diff --git a/source/blender/python/api2_2x/doc/Image.py b/source/blender/python/api2_2x/doc/Image.py index aad3d84781b..1d25c550b3d 100644 --- a/source/blender/python/api2_2x/doc/Image.py +++ b/source/blender/python/api2_2x/doc/Image.py @@ -52,6 +52,13 @@ def Get (name = None): - (): A list with all Image objects in the current scene. """ +def GetCurrent (): + """ + Get the currently displayed Image from Blenders UV/Image window. + When multiple images are displayed, the last active UV/Image windows image is used. + @rtype: Blender Image + @return: The Current Blender Image, If there is no current image it returns None. + """ class Image: """ diff --git a/source/blender/python/api2_2x/sceneTimeLine.c b/source/blender/python/api2_2x/sceneTimeLine.c index 58830d28ab4..89c55acc352 100644 --- a/source/blender/python/api2_2x/sceneTimeLine.c +++ b/source/blender/python/api2_2x/sceneTimeLine.c @@ -166,56 +166,72 @@ PyObject *M_TimeLine_Get (PyObject *self, PyObject *args) { static PyObject *TimeLine_getFramesMarked (BPy_TimeLine *self, PyObject *args) { - PyObject *marker_dict= PyDict_New (); + PyObject *marker_dict= NULL; TimeMarker *marker_it= NULL; PyObject *tmarker= NULL, *pyo= NULL; if (!PyArg_ParseTuple (args, "|O", &tmarker)) - return EXPP_ReturnPyObjError (PyExc_TypeError, - "expected nothing, string or int."); + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected nothing, string or int as arguments."); if (tmarker) { - int f= (int)PyInt_AS_LONG (tmarker); char s[64]; + int frm= 0; - if (PyString_Check (tmarker) && (BLI_strncpy (s, PyString_AsString(tmarker), 64)) ) + if (PyString_Check (tmarker) && (BLI_strncpy(s, PyString_AsString (tmarker), 64)) ) { for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next) if (!strcmp (marker_it->name, s)) { - f= (int)marker_it->frame; - tmarker= PyInt_FromLong ((long int)marker_it->frame); + frm= (int)marker_it->frame; break; } - if (PyInt_Check (tmarker) && f!=0) - for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next) - if (marker_it->frame==f) { - if ((pyo= PyDict_GetItem ((PyObject*)marker_dict, PyInt_FromLong ((long int)marker_it->frame))) ) + } + else if (PyInt_Check (tmarker)) + frm= (int)PyInt_AS_LONG (tmarker); + else + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected nothing, string or int as arguments."); + if (frm>0) { + marker_dict= PyDict_New (); + for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next){ + if (marker_it->frame==frm) { + pyo= PyDict_GetItem ((PyObject*)marker_dict, PyInt_FromLong ((long int)marker_it->frame)); + if (pyo) { PyList_Append (pyo, PyString_FromString (marker_it->name)); - else { - if (!pyo) pyo= PyList_New (0); + Py_INCREF (pyo); + }else{ + pyo = PyList_New (0); PyList_Append (pyo, PyString_FromString (marker_it->name)); } - - PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo); + PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo); + if (pyo) { + Py_DECREF (pyo); + pyo= NULL; + } } - } - else + } + } + + }else { + marker_dict= PyDict_New (); for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next) { - if ((pyo= PyDict_GetItem ((PyObject *)marker_dict, PyInt_FromLong ((long int)marker_it->frame))) ) + pyo=PyDict_GetItem ((PyObject*)marker_dict, PyInt_FromLong ((long int)marker_it->frame)); + if (pyo) { PyList_Append (pyo, PyString_FromString (marker_it->name)); - else { + Py_INCREF (pyo); + }else{ pyo= PyList_New (0); PyList_Append (pyo, PyString_FromString (marker_it->name)); } - PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo); - } - - if (pyo) { /** because warnings messages **/ - Py_DECREF (pyo); + PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo); + if (pyo) { + Py_DECREF (pyo); + pyo= NULL; + } } + } - return marker_dict; + return marker_dict; } - static PyObject *TimeLine_addMarker (BPy_TimeLine *self, PyObject *args) { int frame= 0; TimeMarker *marker= NULL, *marker_it= NULL; |