armature weakref fix from stable, Curve.c removed unneeded cruft

This commit is contained in:
2007-08-01 12:57:59 +00:00
parent c79e2666a2
commit b38e987932
2 changed files with 144 additions and 129 deletions

View File

@@ -60,6 +60,10 @@ static const char sArmatureBadArgs[] = "ArmatureType - Bad Arguments: ";
static const char sModuleError[] = "Blender.Armature - Error: ";
static const char sModuleBadArgs[] = "Blender.Armature - Bad Arguments: ";
PyObject * arm_weakref_callback_weakref_dealloc(PyObject *self, PyObject *weakref);
/* python callable */
PyObject * arm_weakref_callback_weakref_dealloc__pyfunc;
//################## BonesDict_Type (internal) ########################
/*This is an internal psuedo-dictionary type that allows for manipulation
* of bones inside of an armature. It is a subobject of armature.
@@ -118,18 +122,19 @@ static PyMethodDef BPy_BonesDict_methods[] = {
//-----------------(internal)
static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){
Bone *bone = NULL;
PyObject *py_bone = NULL, *str;
PyObject *py_bone = NULL;
for (bone = bones->first; bone; bone = bone->next){
py_bone = PyBone_FromBone(bone);
if (!py_bone)
return -1;
str = PyString_FromString(bone->name);
if(PyDict_SetItem(dictionary, str, py_bone) == -1)
if(PyDict_SetItemString(dictionary, bone->name, py_bone) == -1) {
/* unlikely but possible */
Py_DECREF(py_bone);
return -1;
}
Py_DECREF(str);
Py_DECREF(py_bone);
if (bone->childbase.first)
BoneMapping_Init(dictionary, &bone->childbase);
@@ -139,18 +144,17 @@ static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){
//-----------------(internal)
static int EditBoneMapping_Init(PyObject *dictionary, ListBase *editbones){
EditBone *editbone = NULL;
PyObject *py_editbone = NULL, *str;
PyObject *py_editbone = NULL;
for (editbone = editbones->first; editbone; editbone = editbone->next){
py_editbone = PyEditBone_FromEditBone(editbone);
if (!py_editbone)
return -1;
str = PyString_FromString(editbone->name);
if(PyDict_SetItem(dictionary, str, py_editbone) == -1)
if(PyDict_SetItemString(dictionary, editbone->name, py_editbone) == -1) {
Py_DECREF(py_editbone);
return -1;
Py_DECREF(str);
}
Py_DECREF(py_editbone);
}
return 0;
@@ -242,17 +246,14 @@ static PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
value = PyDict_GetItem(self->bonesMap, key);
}
if(value == NULL){ /* item not found in dict. throw exception */
char buffer[128];
char* key_str;
key_str = PyString_AsString( key );
if( !key_str ){ /* key not a py string */
key_str = ""; /* use empty string for printing */
char* key_str = PyString_AsString( key );
if (key_str) {
return EXPP_ReturnPyObjError(PyExc_KeyError, "bone key must be a string" );
} else {
char buffer[128];
PyOS_snprintf( buffer, sizeof(buffer), "bone %s not found", key_str);
return EXPP_ReturnPyObjError(PyExc_KeyError, buffer );
}
PyOS_snprintf( buffer, sizeof(buffer),
"bone %s not found", key_str);
return EXPP_ReturnPyObjError(PyExc_KeyError, buffer );
}
return EXPP_incr_ret(value);
}
@@ -262,107 +263,98 @@ static int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value
{
BPy_EditBone *editbone_for_deletion;
struct EditBone *editbone = NULL;
char *key_str = "";
char *key_str = PyString_AsString(key);
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(NULL, 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);
// FIXME, should be exposed via python. this avoids creating bones with no layers.
editbone->layer= 1;
//set object pointer
((BPy_EditBone*)value)->editbone = editbone;
if (!self->editmode_flag)
return EXPP_intError(PyExc_AttributeError, "%s%s",
sBoneDictBadArgs, "You must call makeEditable() first");
if (!key_str)
return EXPP_intError(PyExc_AttributeError, "%s%s",
sBoneDictBadArgs, "The key must be the name of an editbone");
if (value && !EditBoneObject_Check(value))
return EXPP_intError(PyExc_AttributeError, "%s%s",
sBoneDictBadArgs, "Can only assign editbones as values");
//parse value for assignment
if (value){ /* we know this must be an editbone from the above check */
//create a new editbone
editbone = MEM_callocN(sizeof(EditBone), "eBone");
BLI_strncpy(editbone->name, key_str, 32);
unique_editbone_name(NULL, 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);
// FIXME, should be exposed via python. this avoids creating bones with no layers.
editbone->layer= 1;
//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){
//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;
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;
/* remove the connected flag or else the 'root' ball
* doesn't get drawn */
editbone->flag &= ~BONE_CONNECTED;
}
}
BLI_freelinkN(&self->editbones, editbone_for_deletion->editbone);
if(PyDict_DelItem(self->editbonesMap, key) == -1)
goto RuntimeError;
MEM_freeN(editbone);
return EXPP_intError(PyExc_AttributeError, "%s%s",
sBoneDictBadArgs, "The 'connected' flag is set but the bone has no parent!");
}else{
goto KeyError;
VECCOPY(editbone->head, editbone->parent->tail);
}
}
return 0;
}else{
goto AttributeError2;
}
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 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!");
//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);
return EXPP_intError(PyExc_RuntimeError, "%s%s",
sBoneDictError, "Unable to access dictionary!");
}
}else {
//they are trying to delete the bone using 'del'
editbone_for_deletion = (BPy_EditBone*)PyDict_GetItem(self->editbonesMap, key);
if (!editbone_for_deletion)
return EXPP_intError(PyExc_KeyError, "%s%s%s%s",
sBoneDictError, "The key: ", key_str, " is not present in this dictionary!");
/*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*/
/*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;
/* remove the connected flag or else the 'root' ball
* doesn't get drawn */
editbone->flag &= ~BONE_CONNECTED;
}
}
BLI_freelinkN(&self->editbones, editbone_for_deletion->editbone);
if(PyDict_DelItem(self->editbonesMap, key) == -1)
return EXPP_intError(PyExc_RuntimeError, "%s%s",
sBoneDictError, "Unable to access dictionary!");
}
return 0;
}
//------------------TYPE_OBJECT DEFINITION--------------------------
//Mapping Protocol
@@ -1068,7 +1060,7 @@ static PyObject *Armature_repr(BPy_Armature *self)
static void Armature_dealloc(BPy_Armature * self)
{
if (self->weaklist != NULL)
PyObject_ClearWeakRefs((PyObject *) self);
PyObject_ClearWeakRefs((PyObject *) self); /* this causes the weakref dealloc func to be called */
Py_DECREF(self->Bones);
PyObject_DEL( self );
@@ -1293,11 +1285,32 @@ PyObject *Armature_RebuildBones(PyObject *pyarmature)
{
return Armature_update((BPy_Armature*)pyarmature);
}
/* internal func to remove weakref from weakref list */
PyObject * arm_weakref_callback_weakref_dealloc(PyObject *self, PyObject *weakref)
{
char *list_name = ARM_WEAKREF_LIST_NAME;
PyObject *maindict = NULL, *armlist = NULL;
int i;
maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
armlist = PyDict_GetItemString(maindict, list_name);
if( !armlist){
printf("Oops - update_armature_weakrefs()\n");
Py_RETURN_NONE;
}
i = PySequence_Index(armlist, weakref);
if (i==-1) {
printf("callback weakref internal error, weakref not in list\n\tthis should never happen.\n");
Py_RETURN_NONE;
}
PySequence_DelItem(armlist, i);
Py_RETURN_NONE;
}
/*-----------------(internal)
* Converts a bArmature to a PyArmature
*
* WARNING!!! - MEMORY LEAK HERE, Run in a loop and loose your ram.
* cannot find out why but doesn't seem to be the weakref */
* Converts a bArmature to a PyArmature */
PyObject *Armature_CreatePyObject(struct bArmature *armature)
{
@@ -1329,12 +1342,14 @@ PyObject *Armature_CreatePyObject(struct bArmature *armature)
armlist = PyDict_GetItemString(maindict, list_name);
if( armlist){
weakref = PyWeakref_NewProxy((PyObject*)py_armature, Py_None);
weakref = PyWeakref_NewProxy((PyObject*)py_armature, arm_weakref_callback_weakref_dealloc__pyfunc);
if (PyList_Append(armlist, weakref) == -1){
printf("Oops - list-append failed\n");
goto RuntimeError;
}
Py_DECREF(weakref);
}
return (PyObject *) py_armature;
RuntimeError:
@@ -1353,7 +1368,10 @@ struct bArmature *Armature_FromPyObject( PyObject * py_obj )
return PyArmature_AsArmature((BPy_Armature*)py_obj);
}
/* internal use only */
static PyMethodDef bpy_arm_weakref_callback_weakref_dealloc[] = {
{"arm_weakref_callback_weakref_dealloc", arm_weakref_callback_weakref_dealloc, METH_O, ""}
};
//-------------------MODULE INITIALIZATION--------------------------------
PyObject *Armature_Init(void)
@@ -1366,6 +1384,11 @@ PyObject *Armature_Init(void)
return EXPP_incr_ret(Py_None);
}
/* Weakref management - used for callbacks so we can
* tell when a callback has been removed that a UI button referenced */
arm_weakref_callback_weakref_dealloc__pyfunc = PyCFunction_New(bpy_arm_weakref_callback_weakref_dealloc, NULL);
//Register the module
module = Py_InitModule3("Blender.Armature", M_Armature_methods,
"The Blender Armature module");

View File

@@ -769,7 +769,6 @@ static PyObject *Curve_appendPoint( BPy_Curve * self, PyObject * args )
int i;
int nurb_num; /* index of curve we append to */
PyObject *coord_args; /* coords for new point */
PyObject *retval = NULL;
Nurb *nurb = self->curve->nurb.first; /* first nurb in Curve */
/* fixme - need to malloc new Nurb */
@@ -791,14 +790,7 @@ static PyObject *Curve_appendPoint( BPy_Curve * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"curve index out of range" );
}
/* rebuild our arg tuple for appendPointToNurb() */
//valtuple = Py_BuildValue( "(O)", coord_args );
retval = CurNurb_appendPointToNurb( nurb, coord_args );
// Py_DECREF( valtuple );
return retval;
return CurNurb_appendPointToNurb( nurb, coord_args );
}