Bug fix for:
[ #5000 ] Changin EditMode in Script wrecks memory Armatures create weakreferences in __main__.__dict__. When Window.Editmode is called, the weaklist it iterated over and armatures are updated.
This commit is contained in:
@@ -478,6 +478,7 @@ void BPY_Err_Handle( char *script_name )
|
||||
*****************************************************************************/
|
||||
int BPY_txt_do_python_Text( struct Text *text )
|
||||
{
|
||||
PyObject *maindict = NULL;
|
||||
PyObject *py_dict, *py_result;
|
||||
BPy_constant *info;
|
||||
char textname[24];
|
||||
@@ -524,6 +525,12 @@ int BPY_txt_do_python_Text( struct Text *text )
|
||||
|
||||
py_dict = CreateGlobalDictionary( );
|
||||
|
||||
//setup a weakref dictionary on __main__
|
||||
maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
|
||||
if (PyDict_SetItemString(maindict, "armatures", PyList_New(0)) == -1){
|
||||
return 0;
|
||||
}
|
||||
|
||||
script->py_globaldict = py_dict;
|
||||
|
||||
info = ( BPy_constant * ) PyConstant_New( );
|
||||
|
||||
@@ -1111,6 +1111,8 @@ static PyObject *Armature_repr(BPy_Armature *self)
|
||||
///tp_dealloc
|
||||
static void Armature_dealloc(BPy_Armature * self)
|
||||
{
|
||||
if (self->weaklist != NULL)
|
||||
PyObject_ClearWeakRefs((PyObject *) self);
|
||||
Py_DECREF(self->Bones);
|
||||
Armature_Type.tp_free(self);
|
||||
return;
|
||||
@@ -1137,12 +1139,12 @@ PyTypeObject Armature_Type = {
|
||||
0, //tp_getattro
|
||||
0, //tp_setattro
|
||||
0, //tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, //tp_flags
|
||||
Py_TPFLAGS_DEFAULT| Py_TPFLAGS_HAVE_WEAKREFS, //tp_flags
|
||||
BPy_Armature_doc, //tp_doc
|
||||
0, //tp_traverse
|
||||
0, //tp_clear
|
||||
0, //tp_richcompare
|
||||
0, //tp_weaklistoffset
|
||||
offsetof(BPy_Armature, weaklist), //tp_weaklistoffset
|
||||
0, //tp_iter
|
||||
0, //tp_iternext
|
||||
BPy_Armature_methods, //tp_methods
|
||||
@@ -1328,14 +1330,27 @@ struct PyMethodDef M_Armature_methods[] = {
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
//------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
|
||||
//------------------------Armature_RebuildEditbones (internal)
|
||||
PyObject * Armature_RebuildEditbones(PyObject *pyarmature)
|
||||
{
|
||||
return Armature_makeEditable((BPy_Armature*)pyarmature);
|
||||
}
|
||||
|
||||
//------------------------Armature_RebuildBones (internal)
|
||||
PyObject *Armature_RebuildBones(PyObject *pyarmature)
|
||||
{
|
||||
return Armature_update((BPy_Armature*)pyarmature);
|
||||
}
|
||||
//-----------------(internal)
|
||||
//Converts a bArmature to a PyArmature
|
||||
PyObject *PyArmature_FromArmature(struct bArmature *armature)
|
||||
{
|
||||
BPy_Armature *py_armature = NULL;
|
||||
PyObject *maindict = NULL, *armdict = NULL, *weakref = NULL;
|
||||
|
||||
//create armature type
|
||||
py_armature = (BPy_Armature*)Armature_Type.tp_alloc(&Armature_Type, 0); //*new*
|
||||
py_armature->weaklist = NULL; //init the weaklist
|
||||
if (!py_armature)
|
||||
goto RuntimeError;
|
||||
py_armature->armature = armature;
|
||||
@@ -1345,6 +1360,14 @@ PyObject *PyArmature_FromArmature(struct bArmature *armature)
|
||||
if (!py_armature->Bones)
|
||||
goto RuntimeError;
|
||||
|
||||
//put a weakreference in __main__
|
||||
maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
|
||||
armdict = PyDict_GetItemString(maindict, "armatures");
|
||||
weakref = PyWeakref_NewProxy((PyObject*)py_armature, Py_None);
|
||||
if (PyList_Append(armdict, weakref) == -1){
|
||||
goto RuntimeError;
|
||||
}
|
||||
|
||||
return (PyObject *) py_armature;
|
||||
|
||||
RuntimeError:
|
||||
|
||||
@@ -56,11 +56,14 @@ typedef struct {
|
||||
PyObject_HEAD
|
||||
struct bArmature * armature;
|
||||
BPy_BonesDict *Bones; //BPy_BonesDict
|
||||
PyObject *weaklist;
|
||||
} BPy_Armature;
|
||||
|
||||
//-------------------VISIBLE PROTOTYPES-------------------------
|
||||
PyObject *PyArmature_FromArmature(struct bArmature *armature);
|
||||
struct bArmature *PyArmature_AsArmature(BPy_Armature *py_armature);
|
||||
PyObject * Armature_RebuildEditbones(PyObject *pyarmature);
|
||||
PyObject *Armature_RebuildBones(PyObject *pyarmature);
|
||||
|
||||
int Armature_CheckPyObject( PyObject * pyobj );
|
||||
struct bArmature *Armature_FromPyObject( PyObject * py_obj );
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
#include "Mathutils.h"
|
||||
#include "constant.h"
|
||||
#include "gen_utils.h"
|
||||
|
||||
#include "Armature.h"
|
||||
|
||||
/* See Draw.c */
|
||||
extern int EXPP_disable_force_draw;
|
||||
@@ -890,6 +890,9 @@ static PyObject *M_Window_EditMode( PyObject * self, PyObject * args )
|
||||
char *undo_str = "From script";
|
||||
int undo_str_len = 11;
|
||||
int do_undo = 1;
|
||||
PyObject *maindict = NULL, *armlist = NULL;
|
||||
PyObject *pyarmature = NULL;
|
||||
int x;
|
||||
|
||||
if( !PyArg_ParseTuple( args,
|
||||
"|hs#i", &status, &undo_str, &undo_str_len, &do_undo ) )
|
||||
@@ -899,14 +902,31 @@ static PyObject *M_Window_EditMode( PyObject * self, PyObject * args )
|
||||
if( status >= 0 ) {
|
||||
if( status ) {
|
||||
if( !G.obedit )
|
||||
//update armatures
|
||||
maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
|
||||
armlist = PyDict_GetItemString(maindict, "armatures");
|
||||
for (x = 0; x < PySequence_Size(armlist); x++){
|
||||
pyarmature = PyWeakref_GetObject(PySequence_GetItem( armlist, x));
|
||||
if (pyarmature != Py_None)
|
||||
Armature_RebuildEditbones(pyarmature);
|
||||
}
|
||||
//enter editmode
|
||||
enter_editmode(0);
|
||||
} else if( G.obedit ) {
|
||||
|
||||
if( undo_str_len > 63 )
|
||||
undo_str[63] = '\0'; /* 64 is max */
|
||||
|
||||
BIF_undo_push( undo_str ); /* This checks user undo settings */
|
||||
exit_editmode( EM_FREEDATA );
|
||||
|
||||
//update armatures
|
||||
maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
|
||||
armlist = PyDict_GetItemString(maindict, "armatures");
|
||||
for (x = 0; x < PySequence_Size(armlist); x++){
|
||||
pyarmature = PyWeakref_GetObject(PySequence_GetItem( armlist, x));
|
||||
if (pyarmature != Py_None)
|
||||
Armature_RebuildBones(pyarmature);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user