Bugfix for #5000
Setup for Armature weak ref list was missing from some places where we execute py code. This confused the interpreter and gave random attribute/tuple parse errors. Changed name of weak ref list to "__arm_weakrefs" to avoid name collision with user variables.
This commit is contained in:
@@ -77,6 +77,32 @@
|
||||
/* for pydrivers (ipo drivers defined by one-line Python expressions) */
|
||||
PyObject *bpy_pydriver_Dict = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* set up a weakref list for Armatures
|
||||
* creates list in __main__ module dict
|
||||
*/
|
||||
|
||||
int setup_armature_weakrefs()
|
||||
{
|
||||
PyObject *maindict;
|
||||
PyObject *main_module;
|
||||
char *list_name = ARM_WEAKREF_LIST_NAME;
|
||||
|
||||
main_module = PyImport_AddModule( "__main__");
|
||||
if(main_module){
|
||||
maindict= PyModule_GetDict(main_module);
|
||||
if (PyDict_SetItemString(maindict,
|
||||
list_name,
|
||||
PyList_New(0)) == -1){
|
||||
printf("Oops - setup_armature_weakrefs()\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*Declares the modules and their initialization functions
|
||||
*These are TOP-LEVEL modules e.g. import `module` - there is no
|
||||
*support for packages here e.g. import `package.module` */
|
||||
@@ -478,7 +504,6 @@ 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];
|
||||
@@ -525,14 +550,10 @@ int BPY_txt_do_python_Text( struct Text *text )
|
||||
|
||||
py_dict = CreateGlobalDictionary( );
|
||||
|
||||
#if 0
|
||||
/* bug 5000 */
|
||||
//setup a weakref dictionary on __main__
|
||||
maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
|
||||
if (PyDict_SetItemString(maindict, "armatures", PyList_New(0)) == -1){
|
||||
if( !setup_armature_weakrefs()){
|
||||
printf("Oops - weakref dict\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
script->py_globaldict = py_dict;
|
||||
|
||||
@@ -826,6 +847,12 @@ int BPY_menu_do_python( short menutype, int event )
|
||||
|
||||
fclose( fp );
|
||||
|
||||
|
||||
if( !setup_armature_weakrefs()){
|
||||
printf("Oops - weakref dict\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* run the string buffer */
|
||||
|
||||
py_res = PyRun_String( buffer, Py_file_input, py_dict, py_dict );
|
||||
@@ -1132,6 +1159,12 @@ float BPY_pydriver_eval(IpoDriver *driver)
|
||||
}
|
||||
}
|
||||
|
||||
/* sds*/
|
||||
if( !setup_armature_weakrefs()){
|
||||
fprintf( stderr, "Oops - weakref dict setup\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
|
||||
bpy_pydriver_Dict);
|
||||
|
||||
@@ -1202,6 +1235,12 @@ int BPY_button_eval(char *expr, double *value)
|
||||
}
|
||||
}
|
||||
|
||||
/* sds*/
|
||||
if( !setup_armature_weakrefs()){
|
||||
fprintf(stderr, "Oops - weakref dict\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
|
||||
bpy_pydriver_Dict);
|
||||
|
||||
|
||||
@@ -1348,36 +1348,38 @@ PyObject *Armature_RebuildBones(PyObject *pyarmature)
|
||||
PyObject *PyArmature_FromArmature(struct bArmature *armature)
|
||||
{
|
||||
BPy_Armature *py_armature = NULL;
|
||||
PyObject *maindict = NULL, *armdict = NULL, *weakref = NULL;
|
||||
PyObject *maindict = NULL, *weakref = NULL;
|
||||
PyObject *armlist = NULL; /* list of armature weak refs */
|
||||
char *list_name = ARM_WEAKREF_LIST_NAME;
|
||||
|
||||
//create armature type
|
||||
py_armature = (BPy_Armature*)PyObject_New(BPy_Armature, &Armature_Type); //Armature_Type.tp_alloc(&Armature_Type, 0); //*new*
|
||||
py_armature->weaklist = NULL; //init the weaklist
|
||||
if (!py_armature)
|
||||
py_armature = (BPy_Armature*)Armature_Type.tp_alloc(&Armature_Type, 0); /*new*/
|
||||
if (!py_armature){
|
||||
printf("Oops - can't create py armature\n");
|
||||
goto RuntimeError;
|
||||
}
|
||||
|
||||
py_armature->weaklist = NULL; //init the weaklist
|
||||
py_armature->armature = armature;
|
||||
|
||||
//create armature.bones
|
||||
py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature);
|
||||
if (!py_armature->Bones)
|
||||
if (!py_armature->Bones){
|
||||
printf("Oops - creating armature.bones\n");
|
||||
goto RuntimeError;
|
||||
}
|
||||
|
||||
//put a weakreference in __main__
|
||||
maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
|
||||
|
||||
armdict = PyDict_GetItemString(maindict, "armatures");
|
||||
/*armature list doesn't exist for pydrivers. . .so check.
|
||||
by the way, why is the var called armatures? what if a script author has
|
||||
a similar var in his script? won't they conflict?.
|
||||
|
||||
joeedh*/
|
||||
if (!armdict) return (PyObject *) py_armature;
|
||||
|
||||
armlist = PyDict_GetItemString(maindict, list_name);
|
||||
if( armlist){
|
||||
weakref = PyWeakref_NewProxy((PyObject*)py_armature, Py_None);
|
||||
if (PyList_Append(armdict, weakref) == -1){
|
||||
if (PyList_Append(armlist, weakref) == -1){
|
||||
printf("Oops - list-append failed\n");
|
||||
goto RuntimeError;
|
||||
}
|
||||
|
||||
}
|
||||
return (PyObject *) py_armature;
|
||||
|
||||
RuntimeError:
|
||||
|
||||
@@ -884,18 +884,42 @@ static PyObject *M_Window_GetPerspMatrix( PyObject * self )
|
||||
return perspmat;
|
||||
}
|
||||
|
||||
|
||||
/* update_armature_weakrefs()
|
||||
* helper function used in M_Window_EditMode.
|
||||
* rebuilds list of Armature weakrefs in __main__
|
||||
*/
|
||||
|
||||
static int update_armature_weakrefs()
|
||||
{
|
||||
/* stuff for armature weak refs */
|
||||
char *list_name = ARM_WEAKREF_LIST_NAME;
|
||||
PyObject *maindict = NULL, *armlist = NULL;
|
||||
PyObject *pyarmature = NULL;
|
||||
int x;
|
||||
|
||||
maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
|
||||
armlist = PyDict_GetItemString(maindict, list_name);
|
||||
if( !armlist){
|
||||
printf("Oops - update_armature_weakrefs()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (x = 0; x < PySequence_Size(armlist); x++){
|
||||
pyarmature = PyWeakref_GetObject(PySequence_GetItem( armlist, x));
|
||||
if (pyarmature != Py_None)
|
||||
Armature_RebuildEditbones(pyarmature);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *M_Window_EditMode( PyObject * self, PyObject * args )
|
||||
{
|
||||
short status = -1;
|
||||
char *undo_str = "From script";
|
||||
int undo_str_len = 11;
|
||||
int do_undo = 1;
|
||||
#if 0
|
||||
/* bug 5000 */
|
||||
PyObject *maindict = NULL, *armlist = NULL;
|
||||
PyObject *pyarmature = NULL;
|
||||
int x;
|
||||
#endif
|
||||
|
||||
if( !PyArg_ParseTuple( args,
|
||||
"|hs#i", &status, &undo_str, &undo_str_len, &do_undo ) )
|
||||
@@ -905,17 +929,14 @@ static PyObject *M_Window_EditMode( PyObject * self, PyObject * args )
|
||||
if( status >= 0 ) {
|
||||
if( status ) {
|
||||
if( !G.obedit ){
|
||||
#if 0
|
||||
/* bug 5000 */
|
||||
|
||||
//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);
|
||||
if(! update_armature_weakrefs()){
|
||||
return EXPP_ReturnPyObjError(
|
||||
PyExc_RuntimeError,
|
||||
"internal error - update_armature_weakrefs");
|
||||
}
|
||||
#endif
|
||||
|
||||
//enter editmode
|
||||
enter_editmode(0);
|
||||
}
|
||||
@@ -925,17 +946,13 @@ static PyObject *M_Window_EditMode( PyObject * self, PyObject * args )
|
||||
BIF_undo_push( undo_str ); /* This checks user undo settings */
|
||||
exit_editmode( EM_FREEDATA );
|
||||
|
||||
#if 0
|
||||
/* bug 5000 */
|
||||
//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);
|
||||
if(! update_armature_weakrefs()){
|
||||
return EXPP_ReturnPyObjError(
|
||||
PyExc_RuntimeError,
|
||||
"internal error - update_armature_weakrefs");
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,9 @@
|
||||
#define Py_RETURN_TRUE return PyBool_FromLong(1)
|
||||
#endif
|
||||
|
||||
/* name of list of Armature weak refs built into __main__ */
|
||||
#define ARM_WEAKREF_LIST_NAME "__arm_weakrefs"
|
||||
|
||||
int EXPP_FloatsAreEqual(float A, float B, int floatSteps);
|
||||
int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user