Fix #21028: operator redo creates hundreds of images when texture paint is on.

Now operator redo will look for an undo push with the same name in both the
paint/sculpt and global undo stack.
This commit is contained in:
Brecht Van Lommel 2010-07-23 14:46:31 +00:00
parent f5dd835850
commit a62e340573
6 changed files with 39 additions and 23 deletions

@ -49,7 +49,7 @@ void ED_keymap_paint(struct wmKeyConfig *keyconf);
#define UNDO_PAINT_IMAGE 0
#define UNDO_PAINT_MESH 1
void ED_undo_paint_step(struct bContext *C, int type, int step);
int ED_undo_paint_step(struct bContext *C, int type, int step, const char *name);
void ED_undo_paint_free(void);
#endif

@ -4699,7 +4699,7 @@ static int texture_paint_init(bContext *C, wmOperator *op)
}
settings->imapaint.flag |= IMAGEPAINT_DRAWING;
undo_paint_push_begin(UNDO_PAINT_IMAGE, "Image Paint",
undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
image_undo_restore, image_undo_free);
/* create painter */
@ -5440,7 +5440,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
scene->toolsettings->imapaint.flag |= IMAGEPAINT_DRAWING;
undo_paint_push_begin(UNDO_PAINT_IMAGE, "Image Paint",
undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
image_undo_restore, image_undo_free);
/* allocate and initialize spacial data structures */

@ -121,7 +121,7 @@ typedef enum wmBrushStrokeMode {
typedef void (*UndoRestoreCb)(struct bContext *C, struct ListBase *lb);
typedef void (*UndoFreeCb)(struct ListBase *lb);
void undo_paint_push_begin(int type, char *name, UndoRestoreCb restore, UndoFreeCb free);
void undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free);
struct ListBase *undo_paint_push_get_list(int type);
void undo_paint_push_count_alloc(int type, int size);
void undo_paint_push_end(int type);

@ -76,7 +76,7 @@ static void undo_elem_free(UndoStack *stack, UndoElem *uel)
}
}
static void undo_stack_push_begin(UndoStack *stack, char *name, UndoRestoreCb restore, UndoFreeCb free)
static void undo_stack_push_begin(UndoStack *stack, const char *name, UndoRestoreCb restore, UndoFreeCb free)
{
UndoElem *uel;
int nr;
@ -145,29 +145,37 @@ static void undo_stack_push_end(UndoStack *stack)
}
}
static void undo_stack_step(bContext *C, UndoStack *stack, int step)
static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char *name)
{
UndoElem *undo;
if(step==1) {
if(stack->current==NULL);
else {
if(!name || strcmp(stack->current->name, name) == 0) {
if(G.f & G_DEBUG) printf("undo %s\n", stack->current->name);
undo_restore(C, stack, stack->current);
stack->current= stack->current->prev;
return 1;
}
}
}
else if(step==-1) {
if((stack->current!=NULL && stack->current->next==NULL) || stack->elems.first==NULL);
else {
if(!name || strcmp(stack->current->name, name) == 0) {
undo= (stack->current && stack->current->next)? stack->current->next: stack->elems.first;
undo_restore(C, stack, undo);
stack->current= undo;
if(G.f & G_DEBUG) printf("redo %s\n", undo->name);
return 1;
}
}
}
return 0;
}
static void undo_stack_free(UndoStack *stack)
{
UndoElem *uel;
@ -181,7 +189,7 @@ static void undo_stack_free(UndoStack *stack)
/* Exported Functions */
void undo_paint_push_begin(int type, char *name, UndoRestoreCb restore, UndoFreeCb free)
void undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free)
{
if(type == UNDO_PAINT_IMAGE)
undo_stack_push_begin(&ImageUndoStack, name, restore, free);
@ -219,12 +227,14 @@ void undo_paint_push_end(int type)
undo_stack_push_end(&MeshUndoStack);
}
void ED_undo_paint_step(bContext *C, int type, int step)
int ED_undo_paint_step(bContext *C, int type, int step, const char *name)
{
if(type == UNDO_PAINT_IMAGE)
undo_stack_step(C, &ImageUndoStack, step);
return undo_stack_step(C, &ImageUndoStack, step, name);
else if(type == UNDO_PAINT_MESH)
undo_stack_step(C, &MeshUndoStack, step);
return undo_stack_step(C, &MeshUndoStack, step, name);
return 0;
}
void ED_undo_paint_free(void)

@ -1063,7 +1063,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
/* *********************** backdraw for selection *************** */
void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
{
RegionView3D *rv3d= ar->regiondata;
struct Base *base = scene->basact;

@ -116,7 +116,9 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
if((obact && obact->mode & OB_MODE_TEXTURE_PAINT) || sima->flag & SI_DRAWTOOL) {
ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step);
if(!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname)
if(U.uiflag & USER_GLOBALUNDO)
BKE_undo_name(C, undoname);
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
@ -139,10 +141,14 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
else {
int do_glob_undo= 0;
if(obact && obact->mode & OB_MODE_TEXTURE_PAINT)
ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step);
else if(obact && obact->mode & OB_MODE_SCULPT)
ED_undo_paint_step(C, UNDO_PAINT_MESH, step);
if(obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
if(!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname)
do_glob_undo= 1;
}
else if(obact && obact->mode & OB_MODE_SCULPT) {
if(!ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname) && undoname)
do_glob_undo= 1;
}
else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
if(step==1)
PE_undo(CTX_data_scene(C));