diff options
Diffstat (limited to 'source/blender/src/editmode_undo.c')
-rw-r--r-- | source/blender/src/editmode_undo.c | 375 |
1 files changed, 0 insertions, 375 deletions
diff --git a/source/blender/src/editmode_undo.c b/source/blender/src/editmode_undo.c deleted file mode 100644 index 7893dac2408..00000000000 --- a/source/blender/src/editmode_undo.c +++ /dev/null @@ -1,375 +0,0 @@ -/** - * $Id: - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - - -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "MEM_guardedalloc.h" - -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_screen_types.h" -#include "DNA_scene_types.h" -#include "DNA_userdef_types.h" - -#include "BKE_depsgraph.h" -#include "BKE_global.h" -#include "BKE_object.h" - -#include "BLI_blenlib.h" -#include "BLI_dynstr.h" - -#include "BKE_utildefines.h" - -#include "BIF_editmesh.h" -#include "BIF_interface.h" -#include "BIF_screen.h" -#include "BIF_resources.h" -#include "BIF_toolbox.h" -#include "BIF_space.h" - -#include "BDR_editcurve.h" - -#include "BSE_edit.h" - -#include "mydevice.h" - -/* ***************** generic editmode undo system ********************* */ -/* - -Add this in your local code: - -void undo_editmode_push(char *name, - void (*freedata)(void *), // pointer to function freeing data - void (*to_editmode)(void *), // data to editmode conversion - void * (*from_editmode)(void)) // editmode to data conversion - int (*validate_undo)(void *)) // check if undo data is still valid - - -Further exported for UI is: - -void undo_editmode_step(int step); // undo and redo -void undo_editmode_clear(void) // free & clear all data -void undo_editmode_menu(void) // history menu - - -*/ -/* ********************************************************************* */ - -/* local prototypes --------------- */ - void undo_editmode_step(int step); // undo and redo - void undo_editmode_clear(void); // free & clear all data - void undo_editmode_menu(void); // history menu - void undo_editmode_push(char *name, void (*freedata)(void *), - void (*to_editmode)(void *), void *(*from_editmode)(void), - int (*validate_undo)(void *)); - struct uiBlock *editmode_undohistorymenu(void *arg_unused); - - - -#define MAXUNDONAME 64 -typedef struct UndoElem { - struct UndoElem *next, *prev; - ID id; // copy of editmode object ID - Object *ob; // pointer to edited object - int type; // type of edited object - void *undodata; - uintptr_t undosize; - char name[MAXUNDONAME]; - void (*freedata)(void *); - void (*to_editmode)(void *); - void * (*from_editmode)(void); - int (*validate_undo)(void *); -} UndoElem; - -static ListBase undobase={NULL, NULL}; -static UndoElem *curundo= NULL; - - -/* ********************* xtern api calls ************* */ - -static void undo_restore(UndoElem *undo) -{ - if(undo) { - waitcursor(1); - undo->to_editmode(undo->undodata); - waitcursor(0); - - countall(); - } -} - -/* name can be a dynamic string */ -void undo_editmode_push(char *name, void (*freedata)(void *), - void (*to_editmode)(void *), void *(*from_editmode)(void), - int (*validate_undo)(void *)) -{ - UndoElem *uel; - int nr; - uintptr_t memused, totmem, maxmem; - - /* at first here was code to prevent an "original" key to be insterted twice - this was giving conflicts for example when mesh changed due to keys or apply */ - - /* remove all undos after (also when curundo==NULL) */ - while(undobase.last != curundo) { - uel= undobase.last; - uel->freedata(uel->undodata); - BLI_freelinkN(&undobase, uel); - } - - /* make new */ - curundo= uel= MEM_callocN(sizeof(UndoElem), "undo file"); - strncpy(uel->name, name, MAXUNDONAME-1); - BLI_addtail(&undobase, uel); - - uel->freedata= freedata; - uel->to_editmode= to_editmode; - uel->from_editmode= from_editmode; - uel->validate_undo= validate_undo; - - /* limit amount to the maximum amount*/ - nr= 0; - uel= undobase.last; - while(uel) { - nr++; - if(nr==U.undosteps) break; - uel= uel->prev; - } - if(uel) { - while(undobase.first!=uel) { - UndoElem *first= undobase.first; - first->freedata(first->undodata); - BLI_freelinkN(&undobase, first); - } - } - - /* copy */ - memused= MEM_get_memory_in_use(); - curundo->undodata= curundo->from_editmode(); - curundo->undosize= MEM_get_memory_in_use() - memused; - curundo->ob= G.obedit; - curundo->id= G.obedit->id; - curundo->type= G.obedit->type; - - if(U.undomemory != 0) { - /* limit to maximum memory (afterwards, we can't know in advance) */ - totmem= 0; - maxmem= ((uintptr_t)U.undomemory)*1024*1024; - - uel= undobase.last; - while(uel && uel->prev) { - totmem+= uel->undosize; - if(totmem>maxmem) break; - uel= uel->prev; - } - - if(uel) { - if(uel->prev && uel->prev->prev) - uel= uel->prev; - - while(undobase.first!=uel) { - UndoElem *first= undobase.first; - first->freedata(first->undodata); - BLI_freelinkN(&undobase, first); - } - } - } -} - -/* helper to remove clean other objects from undo stack */ -static void undo_clean_stack(void) -{ - UndoElem *uel, *next; - int mixed= 0; - - /* global undo changes pointers, so we also allow identical names */ - /* side effect: when deleting/renaming object and start editing new one with same name */ - - uel= undobase.first; - while(uel) { - next= uel->next; - - /* for when objects are converted, renamed, or global undo changes pointers... */ - if(uel->type==G.obedit->type && strcmp(uel->id.name, G.obedit->id.name)==0 && - (!uel->validate_undo || uel->validate_undo(uel->undodata))) { - uel->ob= G.obedit; - } - else { - mixed= 1; - uel->freedata(uel->undodata); - BLI_freelinkN(&undobase, uel); - } - - uel= next; - } - - if(mixed) curundo= undobase.last; -} - -/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */ -void undo_editmode_step(int step) -{ - - /* prevent undo to happen on wrong object, stack can be a mix */ - undo_clean_stack(); - - if(step==0) { - undo_restore(curundo); - } - else if(step==1) { - - if(curundo==NULL || curundo->prev==NULL) error("No more steps to undo"); - else { - if(G.f & G_DEBUG) printf("undo %s\n", curundo->name); - curundo= curundo->prev; - undo_restore(curundo); - } - } - else { - /* curundo has to remain current situation! */ - - if(curundo==NULL || curundo->next==NULL) error("No more steps to redo"); - else { - undo_restore(curundo->next); - curundo= curundo->next; - if(G.f & G_DEBUG) printf("redo %s\n", curundo->name); - } - } - - DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); - allqueue(REDRAWVIEW3D, 1); - allqueue(REDRAWBUTSEDIT, 0); - allqueue(REDRAWIMAGE, 0); -} - -void undo_editmode_clear(void) -{ - UndoElem *uel; - - uel= undobase.first; - while(uel) { - uel->freedata(uel->undodata); - uel= uel->next; - } - BLI_freelistN(&undobase); - curundo= NULL; -} - -/* based on index nr it does a restore */ -static void undo_number(int nr) -{ - UndoElem *uel; - int a=1; - - for(uel= undobase.first; uel; uel= uel->next, a++) { - if(a==nr) break; - } - curundo= uel; - undo_editmode_step(0); -} - -/* ************** for interaction with menu/pullown */ - -void undo_editmode_menu(void) -{ - UndoElem *uel; - DynStr *ds= BLI_dynstr_new(); - short event; - char *menu; - - undo_clean_stack(); // removes other objects from it - - BLI_dynstr_append(ds, "Editmode Undo History %t"); - - for(uel= undobase.first; uel; uel= uel->next) { - BLI_dynstr_append(ds, "|"); - BLI_dynstr_append(ds, uel->name); - } - - menu= BLI_dynstr_get_cstring(ds); - BLI_dynstr_free(ds); - - event= pupmenu_col(menu, 20); - MEM_freeN(menu); - - if(event>0) undo_number(event); -} - -static void do_editmode_undohistorymenu(void *arg, int event) -{ - - if(G.obedit==NULL || event<1) return; - - if (event==1) { - if(G.obedit->type==OB_MESH) remake_editMesh(); - } - else undo_number(event-1); - - allqueue(REDRAWVIEW3D, 0); -} - -uiBlock *editmode_undohistorymenu(void *arg_unused) -{ - uiBlock *block; - UndoElem *uel; - short yco = 20, menuwidth = 120; - short item=2; - - undo_clean_stack(); // removes other objects from it - - block= uiNewBlock(&curarea->uiblocks, "view3d_edit_mesh_undohistorymenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); - uiBlockSetButmFunc(block, do_editmode_undohistorymenu, NULL); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Undo All Changes", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); - - for(uel= undobase.first; uel; uel= uel->next, item++) { - if (uel==curundo) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, uel->name, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, (float)item, ""); - if (uel==curundo) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - } - - uiBlockSetDirection(block, UI_RIGHT); - uiTextBoundsBlock(block, 60); - return block; -} - -void *undo_editmode_get_prev(Object *ob) -{ - UndoElem *ue= undobase.last; - if(ue && ue->prev && ue->prev->ob==ob) return ue->prev->undodata; - return NULL; -} |