forked from bartvdbraak/blender
old bug in python api, Blender.Scene.Unlink() did not check if screens were using this scene or if it was used as a set elsewhere.
In both cases this resulted in invalid pointers and crashes. Also was not freeing nodes or sequence data.
This commit is contained in:
parent
2b49858b02
commit
df46987ba3
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* $Id: Scene.c 12513 2007-11-07 18:52:23Z joeedh $
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
||||
*
|
||||
@ -51,12 +51,15 @@ struct View3D;
|
||||
#include "BLI_blenlib.h" /* only for SceneObSeq_new */
|
||||
#include "BSE_drawview.h" /* for play_anim */
|
||||
#include "BSE_headerbuttons.h" /* for copy_scene */
|
||||
#include "BSE_sequence.h" /* to clear_scene_in_allseqs */
|
||||
#include "BSE_node.h" /* to clear_scene_in_nodes */
|
||||
#include "BIF_drawscene.h" /* for set_scene */
|
||||
#include "BIF_space.h" /* for copy_view3d_lock() */
|
||||
#include "BIF_screen.h" /* curarea */
|
||||
#include "BDR_editobject.h" /* free_and_unlink_base() */
|
||||
#include "mydevice.h" /* for #define REDRAW */
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
/* python types */
|
||||
#include "Object.h"
|
||||
#include "Camera.h"
|
||||
@ -718,7 +721,8 @@ static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *pyobj;
|
||||
BPy_Scene *pyscn;
|
||||
Scene *scene;
|
||||
Scene *scene, *sce;
|
||||
bScreen *sc;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!", &Scene_Type, &pyobj ) )
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
@ -733,6 +737,23 @@ static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args )
|
||||
return EXPP_ReturnPyObjError( PyExc_SystemError,
|
||||
"current Scene cannot be removed!" );
|
||||
|
||||
/* Copied from header_info.c */
|
||||
|
||||
/* check all sets */
|
||||
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
|
||||
if(sce->set == scene) sce->set= 0;
|
||||
}
|
||||
|
||||
/* check all sequences */
|
||||
clear_scene_in_allseqs(scene);
|
||||
|
||||
/* check render layer nodes in other scenes */
|
||||
clear_scene_in_nodes(scene);
|
||||
|
||||
for (sc= G.main->screen.first; sc; sc= sc->id.next ) {
|
||||
if(sc->scene == scene) sc->scene= G.scene;
|
||||
}
|
||||
|
||||
free_libblock( &G.main->scene, scene );
|
||||
|
||||
pyscn->scene= NULL;
|
||||
|
@ -484,16 +484,17 @@ void do_info_buttons(unsigned short event)
|
||||
else if(G.scene->id.next) sce= G.scene->id.next;
|
||||
else return;
|
||||
if(okee("Delete current scene")) {
|
||||
/* Note, anything besides free_libblock needs to be added in
|
||||
* Python Scene.c for Blender.Scene.Unlink() */
|
||||
|
||||
|
||||
/* exit modes... could become single call once */
|
||||
exit_editmode(EM_FREEDATA|EM_WAITCURSOR);
|
||||
exit_paint_modes();
|
||||
|
||||
/* check all sets */
|
||||
sce1= G.main->scene.first;
|
||||
while(sce1) {
|
||||
for (sce1= G.main->scene.first; sce1; sce1= sce1->id.next) {
|
||||
if(sce1->set == G.scene) sce1->set= 0;
|
||||
sce1= sce1->id.next;
|
||||
}
|
||||
|
||||
/* check all sequences */
|
||||
@ -503,10 +504,9 @@ void do_info_buttons(unsigned short event)
|
||||
clear_scene_in_nodes(G.scene);
|
||||
|
||||
/* al screens */
|
||||
sc= G.main->screen.first;
|
||||
while(sc) {
|
||||
|
||||
for (sc= G.main->screen.first; sc; sc= sc->id.next ) {
|
||||
if(sc->scene == G.scene) sc->scene= sce;
|
||||
sc= sc->id.next;
|
||||
}
|
||||
free_libblock(&G.main->scene, G.scene);
|
||||
set_scene(sce);
|
||||
|
Loading…
Reference in New Issue
Block a user