Another step in the undo evolution.
- Made unified API for undo calls, to be found in space.c
BIF_undo_push(char *str)
BIF_undo(void)
BIF_redo(void)
These calls will do all undo levels, including editmode and vpaint.
The transition is work in progress, because mesh undo needs recode.
- New global hotkey CTR+Z for undo
Note: 'shaded draw mode' still is SHIFT+Z, the old CTRL+Z was to recalc
the lighting in shaded mode, which already became much more interactive,
like during/after any transform().
Recalc hotkey now is SHIFT+ALT+Z
CTRL+<any modifier>+Z is redo.
- For OSX users; the Apple-key ("Command") now maps to CTRL as well. This
disables the one-mouse-button hack for rightmouse btw, will be fixed in
next commit. At least we can use Apple-Z :)
- Old Ukey for undo is still there, as a training period... my preference is
to restore Ukey to "reload original data" as in past, and only use new
CTRL+Z for undo.
- Added undo_push() for all of editobject.c and editview.c. Meaning we can
start using/testing global undo in the 3d window. Please dont comment on
missing parts for now, first I want someone to volunteer to tackle all of
that.
- Since the global undo has a full 'file' in memory, it can save extremely
fast on exit to <temp dir>/quit.blend. That's default now when global undo
is enabled. It prints "Saved session recovery to ..." in console then.
- In file menu, a new option is added "Recover Last Session". Note that this
reads the undo-save, which is without UI.
- With such nice new features we then can also kill the disputed
Cancel/Confirm menu on Q-KEY.
- Added fix which initializes seam/normal theme color on saved themes.
They showed black now.... (Note: that's in usiblender.c!)
This commit is contained in:
@@ -59,6 +59,13 @@ void poplast(void *data);
|
||||
void free_pushpop(void);
|
||||
void pushpop_test(void);
|
||||
|
||||
/* global undo */
|
||||
void BKE_write_undo(char *name);
|
||||
void BKE_undo_step(int step);
|
||||
void BKE_reset_undo(void);
|
||||
void BKE_undo_menu(void);
|
||||
void BKE_undo_save_quit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -82,7 +82,8 @@
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
#include "BLO_undofile.h"
|
||||
#include "BLO_readfile.h" /* for BLO_read_file */
|
||||
#include "BLO_readfile.h"
|
||||
#include "BLO_writefile.h"
|
||||
|
||||
#include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature
|
||||
#include "BKE_utildefines.h" // O_BINARY FALSE
|
||||
@@ -436,3 +437,195 @@ int BKE_read_file_from_memfile(MemFile *memfile)
|
||||
return (bfd?1:0);
|
||||
}
|
||||
|
||||
|
||||
/* ***************** GLOBAL UNDO *************** */
|
||||
|
||||
#define UNDO_DISK 0
|
||||
|
||||
#define MAXUNDONAME 64
|
||||
typedef struct UndoElem {
|
||||
struct UndoElem *next, *prev;
|
||||
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||
char name[MAXUNDONAME];
|
||||
MemFile memfile;
|
||||
} UndoElem;
|
||||
|
||||
#define MAXUNDO 32
|
||||
static ListBase undobase={NULL, NULL};
|
||||
static UndoElem *curundo= NULL;
|
||||
|
||||
|
||||
static int read_undosave(UndoElem *uel)
|
||||
{
|
||||
char scestr[FILE_MAXDIR+FILE_MAXFILE];
|
||||
int success=0, fileflags;
|
||||
|
||||
strcpy(scestr, G.sce); /* temporal store */
|
||||
fileflags= G.fileflags;
|
||||
G.fileflags |= G_FILE_NO_UI;
|
||||
|
||||
if(UNDO_DISK)
|
||||
success= BKE_read_file(uel->str, NULL);
|
||||
else
|
||||
success= BKE_read_file_from_memfile(&uel->memfile);
|
||||
|
||||
/* restore */
|
||||
strcpy(G.sce, scestr);
|
||||
G.fileflags= fileflags;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/* name can be a dynamic string */
|
||||
void BKE_write_undo(char *name)
|
||||
{
|
||||
int nr, success;
|
||||
UndoElem *uel;
|
||||
|
||||
if( (U.uiflag & USER_GLOBALUNDO)==0) return;
|
||||
|
||||
/* remove all undos after (also when curundo==NULL) */
|
||||
while(undobase.last != curundo) {
|
||||
uel= undobase.last;
|
||||
BLI_remlink(&undobase, uel);
|
||||
BLO_free_memfile(&uel->memfile);
|
||||
MEM_freeN(uel);
|
||||
}
|
||||
|
||||
/* make new */
|
||||
curundo= uel= MEM_callocN(sizeof(UndoElem), "undo file");
|
||||
strncpy(uel->name, name, MAXUNDONAME-1);
|
||||
BLI_addtail(&undobase, uel);
|
||||
|
||||
/* and limit amount to the maximum */
|
||||
nr= 0;
|
||||
uel= undobase.last;
|
||||
while(uel) {
|
||||
nr++;
|
||||
if(nr==MAXUNDO) break;
|
||||
uel= uel->prev;
|
||||
}
|
||||
if(uel) {
|
||||
while(undobase.first!=uel) {
|
||||
UndoElem *first= undobase.first;
|
||||
BLI_remlink(&undobase, first);
|
||||
/* the merge is because of compression */
|
||||
BLO_merge_memfile(&first->memfile, &first->next->memfile);
|
||||
MEM_freeN(first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* disk save version */
|
||||
if(UNDO_DISK) {
|
||||
static int counter= 0;
|
||||
char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
|
||||
char numstr[32];
|
||||
|
||||
/* calculate current filename */
|
||||
counter++;
|
||||
counter= counter % MAXUNDO;
|
||||
|
||||
sprintf(numstr, "%d.blend", counter);
|
||||
BLI_make_file_string("/", tstr, U.tempdir, numstr);
|
||||
|
||||
success= BLO_write_file(tstr, G.fileflags, &err);
|
||||
|
||||
strcpy(curundo->str, tstr);
|
||||
}
|
||||
else {
|
||||
MemFile *prevfile=NULL;
|
||||
char *err;
|
||||
|
||||
if(curundo->prev) prevfile= &(curundo->prev->memfile);
|
||||
|
||||
success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
|
||||
void BKE_undo_step(int step)
|
||||
{
|
||||
|
||||
if(step==1) {
|
||||
/* curundo should never be NULL, after restart or load file it should call undo_save */
|
||||
if(curundo==NULL || curundo->prev==NULL) error("No undo available");
|
||||
else {
|
||||
printf("undo %s\n", curundo->name);
|
||||
curundo= curundo->prev;
|
||||
read_undosave(curundo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
/* curundo has to remain current situation! */
|
||||
|
||||
if(curundo==NULL || curundo->next==NULL) error("No redo available");
|
||||
else {
|
||||
read_undosave(curundo->next);
|
||||
curundo= curundo->next;
|
||||
printf("redo %s\n", curundo->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_reset_undo(void)
|
||||
{
|
||||
UndoElem *uel;
|
||||
|
||||
uel= undobase.first;
|
||||
while(uel) {
|
||||
BLO_free_memfile(&uel->memfile);
|
||||
uel= uel->next;
|
||||
}
|
||||
|
||||
BLI_freelistN(&undobase);
|
||||
curundo= NULL;
|
||||
}
|
||||
|
||||
|
||||
void BKE_undo_menu(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* saves quit.blend */
|
||||
void BKE_undo_save_quit(void)
|
||||
{
|
||||
UndoElem *uel;
|
||||
MemFileChunk *chunk;
|
||||
int file;
|
||||
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||
|
||||
if( (U.uiflag & USER_GLOBALUNDO)==0) return;
|
||||
|
||||
uel= curundo;
|
||||
if(uel==NULL) {
|
||||
printf("No undo buffer to save recovery file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* no undo state to save */
|
||||
if(undobase.first==undobase.last) return;
|
||||
|
||||
BLI_make_file_string("/", str, U.tempdir, "quit.blend");
|
||||
|
||||
file = open(str,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
|
||||
if(file == -1) {
|
||||
printf("Unable to save %s\n", str);
|
||||
return;
|
||||
}
|
||||
|
||||
chunk= uel->memfile.chunks.first;
|
||||
while(chunk) {
|
||||
if( write(file, chunk->buf, chunk->size) != chunk->size) break;
|
||||
chunk= chunk->next;
|
||||
}
|
||||
|
||||
close(file);
|
||||
|
||||
if(chunk) printf("Unable to save %s\n", str);
|
||||
else printf("Saved session recovery to %s\n", str);
|
||||
}
|
||||
|
||||
|
||||
@@ -2720,7 +2720,7 @@ void lib_link_screen_restore(Main *newmain, char mode, Scene *curscene)
|
||||
|
||||
}
|
||||
else if(sl->spacetype==SPACE_IMASEL) {
|
||||
check_imasel_copy((SpaceImaSel *)sl);
|
||||
;
|
||||
}
|
||||
else if(sl->spacetype==SPACE_ACTION) {
|
||||
SpaceAction *saction= (SpaceAction *)sl;
|
||||
|
||||
@@ -148,151 +148,3 @@ void add_memfilechunk(MemFile *compare, MemFile *current, char *buf, unsigned in
|
||||
}
|
||||
}
|
||||
|
||||
/* ***************** GLOBAL UNDO *************** */
|
||||
|
||||
#define UNDO_DISK 0
|
||||
|
||||
#define MAXUNDONAME 64
|
||||
typedef struct UndoElem {
|
||||
struct UndoElem *next, *prev;
|
||||
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||
char name[MAXUNDONAME];
|
||||
MemFile memfile;
|
||||
} UndoElem;
|
||||
|
||||
#define MAXUNDO 32
|
||||
static ListBase undobase={NULL, NULL};
|
||||
static UndoElem *curundo= NULL;
|
||||
|
||||
|
||||
static int read_undosave(UndoElem *uel)
|
||||
{
|
||||
char scestr[FILE_MAXDIR+FILE_MAXFILE];
|
||||
int success=0, fileflags;
|
||||
|
||||
strcpy(scestr, G.sce); /* temporal store */
|
||||
fileflags= G.fileflags;
|
||||
G.fileflags |= G_FILE_NO_UI;
|
||||
|
||||
if(UNDO_DISK)
|
||||
success= BKE_read_file(uel->str, NULL);
|
||||
else
|
||||
success= BKE_read_file_from_memfile(&uel->memfile);
|
||||
|
||||
/* restore */
|
||||
strcpy(G.sce, scestr);
|
||||
G.fileflags= fileflags;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/* name can be a dynamic string */
|
||||
void BIF_write_undo(char *name)
|
||||
{
|
||||
int nr, success;
|
||||
UndoElem *uel;
|
||||
|
||||
if( (U.uiflag & USER_GLOBALUNDO)==0) return;
|
||||
|
||||
/* remove all undos after (also when curundo==NULL) */
|
||||
while(undobase.last != curundo) {
|
||||
uel= undobase.last;
|
||||
BLI_remlink(&undobase, uel);
|
||||
BLO_free_memfile(&uel->memfile);
|
||||
MEM_freeN(uel);
|
||||
}
|
||||
|
||||
/* make new */
|
||||
curundo= uel= MEM_callocN(sizeof(UndoElem), "undo file");
|
||||
strncpy(uel->name, name, MAXUNDONAME-1);
|
||||
BLI_addtail(&undobase, uel);
|
||||
|
||||
/* and limit amount to the maximum */
|
||||
nr= 0;
|
||||
uel= undobase.last;
|
||||
while(uel) {
|
||||
nr++;
|
||||
if(nr==MAXUNDO) break;
|
||||
uel= uel->prev;
|
||||
}
|
||||
if(uel) {
|
||||
while(undobase.first!=uel) {
|
||||
UndoElem *first= undobase.first;
|
||||
BLI_remlink(&undobase, first);
|
||||
/* the merge is because of compression */
|
||||
BLO_merge_memfile(&first->memfile, &first->next->memfile);
|
||||
MEM_freeN(first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* disk save version */
|
||||
if(UNDO_DISK) {
|
||||
static int counter= 0;
|
||||
char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
|
||||
char numstr[32];
|
||||
|
||||
/* calculate current filename */
|
||||
counter++;
|
||||
counter= counter % MAXUNDO;
|
||||
|
||||
sprintf(numstr, "%d.blend", counter);
|
||||
BLI_make_file_string("/", tstr, U.tempdir, numstr);
|
||||
|
||||
success= BLO_write_file(tstr, G.fileflags, &err);
|
||||
|
||||
strcpy(curundo->str, tstr);
|
||||
}
|
||||
else {
|
||||
MemFile *prevfile=NULL;
|
||||
char *err;
|
||||
|
||||
if(curundo->prev) prevfile= &(curundo->prev->memfile);
|
||||
|
||||
success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
|
||||
void BIF_undo_step(int step)
|
||||
{
|
||||
|
||||
if(step==1) {
|
||||
/* curundo should never be NULL, after restart or load file it should call undo_save */
|
||||
if(curundo==NULL || curundo->prev==NULL) error("No undo available");
|
||||
else {
|
||||
printf("undo %s\n", curundo->name);
|
||||
curundo= curundo->prev;
|
||||
read_undosave(curundo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
/* curundo has to remain current situation! */
|
||||
|
||||
if(curundo==NULL || curundo->next==NULL) error("No redo available");
|
||||
else {
|
||||
read_undosave(curundo->next);
|
||||
curundo= curundo->next;
|
||||
printf("redo %s\n", curundo->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BIF_reset_undo(void)
|
||||
{
|
||||
UndoElem *uel;
|
||||
|
||||
uel= undobase.first;
|
||||
while(uel) {
|
||||
BLO_free_memfile(&uel->memfile);
|
||||
uel= uel->next;
|
||||
}
|
||||
|
||||
BLI_freelistN(&undobase);
|
||||
curundo= NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ void make_parent(void);
|
||||
void make_displists_by_parent(struct Object *ob);
|
||||
void exit_editmode(int freedata);
|
||||
void check_editmode(int type);
|
||||
void docentre(void);
|
||||
void docentre(int centremode);
|
||||
void docentre_new(void);
|
||||
void docentre_cursor(void);
|
||||
void movetolayer(void);
|
||||
|
||||
@@ -144,7 +144,6 @@ void beauty_fill(void);
|
||||
void join_triangles(void);
|
||||
void edge_flip(void);
|
||||
void join_mesh(void);
|
||||
void clever_numbuts_mesh(void);
|
||||
void sort_faces(void);
|
||||
void vertices_to_sphere(void);
|
||||
void fill_mesh(void);
|
||||
|
||||
@@ -120,6 +120,10 @@ extern void start_game(void);
|
||||
extern void select_group_menu(void);
|
||||
extern void select_group(short nr);
|
||||
|
||||
extern void BIF_undo_push(char *str);
|
||||
extern void BIF_undo(void);
|
||||
extern void BIF_redo(void);
|
||||
extern void BIF_undo_menu(void);
|
||||
|
||||
#ifdef _WIN32 // FULLSCREEN
|
||||
extern void mainwindow_toggle_fullscreen(int fullscreen);
|
||||
|
||||
@@ -549,7 +549,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
|
||||
}
|
||||
break;
|
||||
case B_DOCENTRE:
|
||||
docentre();
|
||||
docentre(0);
|
||||
break;
|
||||
case B_DOCENTRENEW:
|
||||
docentre_new();
|
||||
|
||||
@@ -1233,14 +1233,17 @@ void duplicate_context_selected(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void toggle_shading(void) {
|
||||
if(G.qual & LR_CTRLKEY) {
|
||||
reshadeall_displist();
|
||||
G.vd->drawtype= OB_SHADED;
|
||||
}
|
||||
else if(G.qual & LR_SHIFTKEY) {
|
||||
if(G.vd->drawtype== OB_SHADED) G.vd->drawtype= OB_WIRE;
|
||||
else G.vd->drawtype= OB_SHADED;
|
||||
void toggle_shading(void)
|
||||
{
|
||||
if(G.qual & LR_SHIFTKEY) {
|
||||
if(G.qual & LR_ALTKEY) {
|
||||
reshadeall_displist();
|
||||
G.vd->drawtype= OB_SHADED;
|
||||
}
|
||||
else {
|
||||
if(G.vd->drawtype== OB_SHADED) G.vd->drawtype= OB_WIRE;
|
||||
else G.vd->drawtype= OB_SHADED;
|
||||
}
|
||||
}
|
||||
else if(G.qual & LR_ALTKEY) {
|
||||
if(G.vd->drawtype== OB_TEXTURE) G.vd->drawtype= OB_SOLID;
|
||||
|
||||
@@ -7748,34 +7748,15 @@ void join_mesh(void)
|
||||
test_object_materials((ID *)me);
|
||||
|
||||
enter_editmode();
|
||||
exit_editmode(1);
|
||||
exit_editmode(1); // freedata, but no undo
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSSHADING, 0);
|
||||
makeDispList(G.obedit);
|
||||
makeDispList(ob);
|
||||
|
||||
BIF_undo_push("Join Mesh");
|
||||
}
|
||||
|
||||
void clever_numbuts_mesh(void)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *eve;
|
||||
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
if(eve->f & 1) break;
|
||||
eve= eve->next;
|
||||
}
|
||||
if(eve==0) return;
|
||||
|
||||
add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, eve->co, 0);
|
||||
add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, eve->co+1, 0);
|
||||
add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, eve->co+2, 0);
|
||||
|
||||
do_clever_numbuts("Active Vertex", 3, REDRAW);
|
||||
}
|
||||
|
||||
|
||||
static void permutate(void *list, int num, int size, int *index)
|
||||
{
|
||||
void *buf;
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_booleanops.h"
|
||||
@@ -110,6 +109,7 @@
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_subsurf.h"
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_graphics.h"
|
||||
@@ -194,7 +194,7 @@ void add_object_draw(int type) /* for toolbox */
|
||||
setcursor_space(SPACE_VIEW3D, CURSOR_STD);
|
||||
|
||||
if ELEM3(curarea->spacetype, SPACE_VIEW3D, SPACE_BUTS, SPACE_INFO) {
|
||||
if (G.obedit) exit_editmode(1);
|
||||
if (G.obedit) exit_editmode(2); // freedata, and undo
|
||||
ob= add_object(type);
|
||||
base_init_from_view3d(BASACT, G.vd);
|
||||
|
||||
@@ -255,6 +255,8 @@ void delete_obj(int ok)
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
allqueue(REDRAWACTION, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
|
||||
BIF_undo_push("Delete object(s)");
|
||||
}
|
||||
|
||||
int return_editmesh_indexar(int **indexar, float *cent)
|
||||
@@ -631,6 +633,7 @@ void add_hook(void)
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
BIF_undo_push("Add hook");
|
||||
}
|
||||
|
||||
void make_track(void)
|
||||
@@ -725,6 +728,7 @@ void make_track(void)
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
sort_baselist(G.scene);
|
||||
}
|
||||
BIF_undo_push("make Track");
|
||||
}
|
||||
|
||||
void apply_obmat(Object *ob)
|
||||
@@ -802,6 +806,8 @@ void clear_parent(void)
|
||||
test_scene_constraints();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
|
||||
BIF_undo_push("Clear Parent");
|
||||
}
|
||||
|
||||
void clear_track(void)
|
||||
@@ -830,6 +836,8 @@ void clear_track(void)
|
||||
test_scene_constraints();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
|
||||
BIF_undo_push("Clear Track");
|
||||
}
|
||||
|
||||
void clear_object(char mode)
|
||||
@@ -837,14 +845,18 @@ void clear_object(char mode)
|
||||
Base *base;
|
||||
Object *ob;
|
||||
float *v1, *v3, mat[3][3];
|
||||
char *str=NULL;
|
||||
|
||||
if(G.obedit) return;
|
||||
if(G.scene->id.lib) return;
|
||||
|
||||
if(mode=='r' && okee("Clear rotation")==0) return;
|
||||
else if(mode=='g' && okee("Clear location")==0) return;
|
||||
else if(mode=='s' && okee("Clear size")==0) return;
|
||||
else if(mode=='o' && okee("Clear origin")==0) return;
|
||||
if(mode=='r') str= "Clear rotation";
|
||||
else if(mode=='g') str= "Clear location";
|
||||
else if(mode=='s') str= "Clear size";
|
||||
else if(mode=='o') str= "Clear origin";
|
||||
else return;
|
||||
|
||||
if(okee(str)==0) return;
|
||||
|
||||
if (G.obpose){
|
||||
|
||||
@@ -859,6 +871,7 @@ void clear_object(char mode)
|
||||
}
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
BIF_undo_push(str);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -906,6 +919,7 @@ void clear_object(char mode)
|
||||
}
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
BIF_undo_push(str);
|
||||
}
|
||||
|
||||
void reset_slowparents(void)
|
||||
@@ -939,7 +953,7 @@ void set_slowparent(void)
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
|
||||
BIF_undo_push("Slow parent");
|
||||
}
|
||||
|
||||
void make_vertex_parent(void)
|
||||
@@ -953,7 +967,7 @@ void make_vertex_parent(void)
|
||||
Object *par, *ob;
|
||||
int a, v1=0, v2=0, v3=0, nr=1;
|
||||
|
||||
/* we need 1 ot 3 selected vertices */
|
||||
/* we need 1 to 3 selected vertices */
|
||||
|
||||
if(G.obedit->type==OB_MESH) {
|
||||
eve= em->verts.first;
|
||||
@@ -1054,6 +1068,7 @@ void make_vertex_parent(void)
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
|
||||
// BIF_undo_push(str); not, conflicts with editmode undo...
|
||||
}
|
||||
|
||||
int test_parent_loop(Object *par, Object *ob)
|
||||
@@ -1078,8 +1093,7 @@ void make_parent(void)
|
||||
{
|
||||
Base *base;
|
||||
Object *par;
|
||||
Ika *ika;
|
||||
short qual, ok, mode=0, limbnr=0, effchild=0;
|
||||
short qual, mode=0, limbnr=0, effchild=0;
|
||||
char *bonestr=NULL;
|
||||
Bone *bone=NULL;
|
||||
int bonenr;
|
||||
@@ -1095,56 +1109,7 @@ void make_parent(void)
|
||||
qual= G.qual;
|
||||
par= BASACT->object;
|
||||
|
||||
if(par->type==OB_IKA) {
|
||||
|
||||
if(qual & LR_SHIFTKEY)
|
||||
mode= pupmenu("Make Parent Without Inverse%t|Use Vertex %x1|Use Limb %x2|Use Skeleton %x3");
|
||||
else
|
||||
mode= pupmenu("Make Parent %t|Use Vertex %x1|Use Limb %x2|Use Skeleton %x3");
|
||||
|
||||
if(mode==1) {
|
||||
draw_ika_nrs(par, 0);
|
||||
if(button(&limbnr, 0, 99, "Vertex: ")==0) {
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(mode==2) {
|
||||
draw_ika_nrs(par, 1);
|
||||
if(button(&limbnr, 0, 99, "Limb: ")==0) {
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(mode==3) {
|
||||
ika= par->data;
|
||||
if(ika->def==0) {
|
||||
error("No skeleton available: use CTRL K");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else return;
|
||||
|
||||
if(mode==1) mode= PARVERT1;
|
||||
else if(mode==2) mode= PARLIMB;
|
||||
else if(mode==3) mode= PARSKEL;
|
||||
|
||||
/* test effchild */
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if TESTBASELIB(base) {
|
||||
if(base->object->type==OB_IKA && base->object!=par && mode==PARVERT1 ) {
|
||||
if(effchild==0) {
|
||||
if(okee("Effector as child")) effchild= 1;
|
||||
else effchild= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(effchild) break;
|
||||
base= base->next;
|
||||
}
|
||||
}
|
||||
else if(par->type == OB_CURVE){
|
||||
if(par->type == OB_CURVE){
|
||||
bConstraint *con;
|
||||
bFollowPathConstraint *data;
|
||||
|
||||
@@ -1188,6 +1153,7 @@ void make_parent(void)
|
||||
test_scene_constraints();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
sort_baselist(G.scene);
|
||||
BIF_undo_push("make Parent");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1294,91 +1260,67 @@ void make_parent(void)
|
||||
if TESTBASELIB(base) {
|
||||
if(base!=BASACT) {
|
||||
|
||||
ok= 1;
|
||||
if(base->object->type==OB_IKA) {
|
||||
|
||||
if(effchild==1) {
|
||||
|
||||
if( test_parent_loop(par, base->object)==0 ) {
|
||||
|
||||
Ika *ika= base->object->data;
|
||||
|
||||
ika->parent= par;
|
||||
ika->par1= limbnr;
|
||||
ika->partype= mode;
|
||||
itterate_ika(base->object);
|
||||
ok= 0;
|
||||
}
|
||||
else {
|
||||
ok= 0;
|
||||
error("Loop in parents");
|
||||
}
|
||||
}
|
||||
if( test_parent_loop(par, base->object) ) {
|
||||
error("Loop in parents");
|
||||
}
|
||||
else {
|
||||
|
||||
if(ok) {
|
||||
if( test_parent_loop(par, base->object) ) {
|
||||
error("Loop in parents");
|
||||
/* the ifs below are horrible code (ton) */
|
||||
|
||||
if(par->type==OB_IKA){
|
||||
base->object->partype= mode;
|
||||
base->object->par1= limbnr;
|
||||
}
|
||||
else if (par->type==OB_ARMATURE){
|
||||
base->object->partype= mode;
|
||||
if (bone)
|
||||
strcpy (base->object->parsubstr, bone->name);
|
||||
else
|
||||
base->object->parsubstr[0]=0;
|
||||
}
|
||||
else {
|
||||
|
||||
/* the ifs below are horrible code (ton) */
|
||||
|
||||
if(par->type==OB_IKA){
|
||||
base->object->partype= mode;
|
||||
base->object->par1= limbnr;
|
||||
if(qual & LR_ALTKEY) {
|
||||
base->object->partype= PARVERT1;
|
||||
}
|
||||
else if (par->type==OB_ARMATURE){
|
||||
else if(par->type==OB_CURVE) {
|
||||
base->object->partype= mode;
|
||||
if (bone)
|
||||
strcpy (base->object->parsubstr, bone->name);
|
||||
else
|
||||
base->object->parsubstr[0]=0;
|
||||
}
|
||||
else {
|
||||
if(qual & LR_ALTKEY) {
|
||||
base->object->partype= PARVERT1;
|
||||
}
|
||||
else if(par->type==OB_CURVE) {
|
||||
base->object->partype= mode;
|
||||
}
|
||||
else {
|
||||
base->object->partype= PAROBJECT;
|
||||
}
|
||||
base->object->partype= PAROBJECT;
|
||||
}
|
||||
base->object->parent= par;
|
||||
}
|
||||
base->object->parent= par;
|
||||
|
||||
/* calculate inverse parent matrix? */
|
||||
if( (qual & LR_SHIFTKEY) ) {
|
||||
/* not... */
|
||||
Mat4One(base->object->parentinv);
|
||||
memset(base->object->loc, 0, 3*sizeof(float));
|
||||
}
|
||||
else {
|
||||
if(mode==PARSKEL && par->type == OB_ARMATURE) {
|
||||
/* Prompt the user as to whether he wants to
|
||||
* add some vertex groups based on the bones
|
||||
* in the parent armature.
|
||||
*/
|
||||
create_vgroups_from_armature(base->object,
|
||||
par);
|
||||
/* calculate inverse parent matrix? */
|
||||
if( (qual & LR_SHIFTKEY) ) {
|
||||
/* not... */
|
||||
Mat4One(base->object->parentinv);
|
||||
memset(base->object->loc, 0, 3*sizeof(float));
|
||||
}
|
||||
else {
|
||||
if(mode==PARSKEL && par->type == OB_ARMATURE) {
|
||||
/* Prompt the user as to whether he wants to
|
||||
* add some vertex groups based on the bones
|
||||
* in the parent armature.
|
||||
*/
|
||||
create_vgroups_from_armature(base->object,
|
||||
par);
|
||||
|
||||
base->object->partype= PAROBJECT;
|
||||
what_does_parent(base->object);
|
||||
Mat4One (base->object->parentinv);
|
||||
base->object->partype= mode;
|
||||
}
|
||||
else
|
||||
what_does_parent(base->object);
|
||||
Mat4Invert(base->object->parentinv, workob.obmat);
|
||||
base->object->partype= PAROBJECT;
|
||||
what_does_parent(base->object);
|
||||
Mat4One (base->object->parentinv);
|
||||
base->object->partype= mode;
|
||||
}
|
||||
else
|
||||
what_does_parent(base->object);
|
||||
Mat4Invert(base->object->parentinv, workob.obmat);
|
||||
}
|
||||
|
||||
if(par->type==OB_LATTICE) makeDispList(base->object);
|
||||
if(par->type==OB_CURVE && mode==PARSKEL) makeDispList(base->object);
|
||||
if(par->type==OB_ARMATURE && mode == PARSKEL){
|
||||
verify_defgroups(base->object);
|
||||
makeDispList(base->object);
|
||||
}
|
||||
if(par->type==OB_LATTICE) makeDispList(base->object);
|
||||
if(par->type==OB_CURVE && mode==PARSKEL) makeDispList(base->object);
|
||||
if(par->type==OB_ARMATURE && mode == PARSKEL){
|
||||
verify_defgroups(base->object);
|
||||
makeDispList(base->object);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1390,6 +1332,8 @@ void make_parent(void)
|
||||
|
||||
test_scene_constraints();
|
||||
sort_baselist(G.scene);
|
||||
|
||||
BIF_undo_push("make Parent");
|
||||
}
|
||||
|
||||
|
||||
@@ -1499,13 +1443,13 @@ void make_displists_by_parent(Object *ob) {
|
||||
makeDispList(base->object);
|
||||
}
|
||||
|
||||
void exit_editmode(int freedata) /* freedata==0 at render */
|
||||
void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do undo buffer too */
|
||||
{
|
||||
Base *base;
|
||||
Object *ob;
|
||||
Curve *cu;
|
||||
|
||||
if(G.obedit==0) return;
|
||||
if(G.obedit==NULL) return;
|
||||
|
||||
if(G.obedit->type==OB_MESH) {
|
||||
|
||||
@@ -1588,6 +1532,8 @@ void exit_editmode(int freedata) /* freedata==0 at render */
|
||||
}
|
||||
scrarea_queue_headredraw(curarea);
|
||||
|
||||
if(G.obedit==NULL && freedata==2)
|
||||
BIF_undo_push("Editmode");
|
||||
}
|
||||
|
||||
void check_editmode(int type)
|
||||
@@ -1595,12 +1541,12 @@ void check_editmode(int type)
|
||||
|
||||
if (G.obedit==0 || G.obedit->type==type) return;
|
||||
|
||||
exit_editmode(1);
|
||||
exit_editmode(2); // freedata, and undo
|
||||
}
|
||||
|
||||
static int centremode= 0; /* 0 == do centre, 1 == centre new, 2 == centre cursor */
|
||||
/* 0 == do centre, 1 == centre new, 2 == centre cursor */
|
||||
|
||||
void docentre(void)
|
||||
void docentre(int centremode)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
Base *base;
|
||||
@@ -1830,6 +1776,7 @@ void docentre(void)
|
||||
}
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
BIF_undo_push("Do Centre");
|
||||
}
|
||||
|
||||
void docentre_new(void)
|
||||
@@ -1840,9 +1787,7 @@ void docentre_new(void)
|
||||
error("Unable to center new in Edit Mode");
|
||||
}
|
||||
else {
|
||||
centremode= 1;
|
||||
docentre();
|
||||
centremode= 0;
|
||||
docentre(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1854,9 +1799,7 @@ void docentre_cursor(void)
|
||||
error("Unable to center cursor in Edit Mode");
|
||||
}
|
||||
else {
|
||||
centremode= 2;
|
||||
docentre();
|
||||
centremode= 0;
|
||||
docentre(2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1893,6 +1836,8 @@ void movetolayer(void)
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
allqueue(REDRAWINFO, 0);
|
||||
|
||||
BIF_undo_push("Move to layer");
|
||||
}
|
||||
|
||||
|
||||
@@ -1943,7 +1888,8 @@ void special_editmenu(void)
|
||||
}
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSLOGIC, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
BIF_undo_push("Change texture face");
|
||||
}
|
||||
else if(G.f & G_VERTEXPAINT) {
|
||||
Mesh *me= get_mesh(OBACT);
|
||||
@@ -1959,6 +1905,7 @@ void special_editmenu(void)
|
||||
do_shared_vertexcol(me);
|
||||
|
||||
if(me->tface) mcol_to_tface(me, 1);
|
||||
BIF_undo_push("Shared VertexCol");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1996,6 +1943,7 @@ void special_editmenu(void)
|
||||
} else if(ret==-1) {
|
||||
error("Selected meshes must have faces to perform boolean operations");
|
||||
}
|
||||
else BIF_undo_push("Boolean");
|
||||
|
||||
waitcursor(0);
|
||||
} else {
|
||||
@@ -2215,7 +2163,7 @@ void convertmenu(void)
|
||||
/* texspace and normals */
|
||||
BASACT= base;
|
||||
enter_editmode();
|
||||
exit_editmode(1);
|
||||
exit_editmode(1); // freedata, but no undo
|
||||
BASACT= basact;
|
||||
}
|
||||
}
|
||||
@@ -2262,6 +2210,7 @@ void convertmenu(void)
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
BIF_undo_push("Convert Object");
|
||||
}
|
||||
|
||||
/* Change subdivision properties of mesh object ob, if
|
||||
@@ -2281,6 +2230,8 @@ void flip_subdivison(Object *ob, int level)
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
makeDispList(ob);
|
||||
|
||||
BIF_undo_push("Switch subsurf on/off");
|
||||
}
|
||||
|
||||
void copymenu_properties(Object *ob)
|
||||
@@ -2345,6 +2296,8 @@ void copymenu_properties(Object *ob)
|
||||
}
|
||||
MEM_freeN(str);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
|
||||
BIF_undo_push("Copy properties");
|
||||
}
|
||||
|
||||
void copymenu_logicbricks(Object *ob)
|
||||
@@ -2378,6 +2331,7 @@ void copymenu_logicbricks(Object *ob)
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
BIF_undo_push("Copy logic");
|
||||
}
|
||||
|
||||
void copy_attr_menu()
|
||||
@@ -2604,6 +2558,7 @@ void copy_attr(short event)
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
}
|
||||
|
||||
BIF_undo_push("Copy attributes");
|
||||
}
|
||||
|
||||
void link_to_scene(unsigned short nr)
|
||||
@@ -2818,6 +2773,8 @@ void make_links(short event)
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
allqueue(REDRAWBUTSHEAD, 0);
|
||||
|
||||
BIF_undo_push("Create links");
|
||||
}
|
||||
|
||||
void make_duplilist_real()
|
||||
@@ -2866,6 +2823,8 @@ void make_duplilist_real()
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
|
||||
BIF_undo_push("Make duplicates real");
|
||||
}
|
||||
|
||||
void apply_object()
|
||||
@@ -2928,7 +2887,7 @@ void apply_object()
|
||||
/* texspace and normals */
|
||||
BASACT= base;
|
||||
enter_editmode();
|
||||
exit_editmode(1);
|
||||
exit_editmode(1); // freedata, but no undo
|
||||
BASACT= basact;
|
||||
|
||||
}
|
||||
@@ -2995,7 +2954,7 @@ void apply_object()
|
||||
/* texspace and normals */
|
||||
BASACT= base;
|
||||
enter_editmode();
|
||||
exit_editmode(1);
|
||||
exit_editmode(1); // freedata, but no undo
|
||||
BASACT= basact;
|
||||
}
|
||||
}
|
||||
@@ -3003,6 +2962,7 @@ void apply_object()
|
||||
}
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
BIF_undo_push("Apply object");
|
||||
}
|
||||
|
||||
|
||||
@@ -6579,7 +6539,7 @@ void transform(int mode)
|
||||
|
||||
/* undo after transform, since it's storing current situations */
|
||||
if(canceled==0 && G.obedit==NULL)
|
||||
BIF_write_undo(transform_mode_to_string(mode));
|
||||
BIF_undo_push(transform_mode_to_string(mode));
|
||||
}
|
||||
|
||||
void std_rmouse_transform(void (*xf_func)(int))
|
||||
@@ -6613,6 +6573,8 @@ void std_rmouse_transform(void (*xf_func)(int))
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if gets here it's a select, later on remove obedit check */
|
||||
if(G.obedit==NULL) BIF_undo_push("Select");
|
||||
}
|
||||
|
||||
void rightmouse_transform(void)
|
||||
@@ -7027,6 +6989,7 @@ void single_user(void)
|
||||
|
||||
countall();
|
||||
allqueue(REDRAWALL, 0);
|
||||
BIF_undo_push("Single user");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7190,7 +7153,7 @@ void make_local(void)
|
||||
|
||||
|
||||
allqueue(REDRAWALL, 0);
|
||||
|
||||
BIF_undo_push("Make local");
|
||||
}
|
||||
|
||||
|
||||
@@ -7552,6 +7515,7 @@ void selectlinks(int nr)
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWDATASELECT, 0);
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
BIF_undo_push("Select links");
|
||||
}
|
||||
|
||||
void image_aspect(void)
|
||||
@@ -7612,6 +7576,7 @@ void image_aspect(void)
|
||||
}
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
BIF_undo_push("Image aspect");
|
||||
}
|
||||
|
||||
void set_ob_ipoflags(void)
|
||||
@@ -7693,6 +7658,8 @@ void select_select_keys(void)
|
||||
allspace(REMAKEIPO, 0);
|
||||
allqueue(REDRAWIPO, 0);
|
||||
|
||||
BIF_undo_push("Selet keys");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -7836,7 +7803,8 @@ void make_displists_by_obdata(void *obdata) {
|
||||
/* ******************************************************************** */
|
||||
/* Mirror function in Edit Mode */
|
||||
|
||||
void mirror_edit(short mode) {
|
||||
void mirror_edit(short mode)
|
||||
{
|
||||
short axis, a;
|
||||
float mat[3][3], imat[3][3], min[3], max[3];
|
||||
TransVert *tv;
|
||||
@@ -8043,6 +8011,9 @@ void mirrormenu(void){
|
||||
|
||||
if (mode==-1) return; /* return */
|
||||
mirror_edit(mode); /* separating functionality from interface | call*/
|
||||
|
||||
BIF_undo_push("Mirror");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1076,9 +1076,7 @@ void screenmain(void)
|
||||
if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT||g_activearea->spacetype==SPACE_SCRIPT);
|
||||
else {
|
||||
if(val) {
|
||||
int mode = 0;
|
||||
mode= pupmenu("Quit Blender?%t|Cancel%x1|Confirm%x2");
|
||||
if (mode == 2)
|
||||
if(okee("Quit Blender?"))
|
||||
exit_usiblender();
|
||||
}
|
||||
towin= 0;
|
||||
|
||||
@@ -392,7 +392,7 @@ void deselectall(void) /* is toggle */
|
||||
allqueue(REDRAWNLA, 0);
|
||||
|
||||
countall();
|
||||
|
||||
BIF_undo_push("(De)select all");
|
||||
}
|
||||
|
||||
/* selects all objects of a particular type, on currently visible layers */
|
||||
@@ -414,7 +414,7 @@ void selectall_type(short obtype)
|
||||
allqueue(REDRAWNLA, 0);
|
||||
|
||||
countall();
|
||||
|
||||
BIF_undo_push("Select all per type");
|
||||
}
|
||||
/* selects all objects on a particular layer */
|
||||
void selectall_layer(int layernum)
|
||||
@@ -435,8 +435,9 @@ void selectall_layer(int layernum)
|
||||
allqueue(REDRAWNLA, 0);
|
||||
|
||||
countall();
|
||||
|
||||
BIF_undo_push("Select all per layer");
|
||||
}
|
||||
|
||||
static void deselectall_except(Base *b) /* deselect all except b */
|
||||
{
|
||||
Base *base;
|
||||
@@ -658,13 +659,14 @@ void mouse_select(void)
|
||||
allqueue(REDRAWACTION, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
allqueue(REDRAWHEADERS, 0); /* To force display update for the posebutton */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
countall();
|
||||
|
||||
rightmouse_transform();
|
||||
rightmouse_transform(); // does undo push!
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -915,6 +917,9 @@ void borderselect(void)
|
||||
|
||||
allqueue(REDRAWINFO, 0);
|
||||
}
|
||||
/* remove obedit check later */
|
||||
if(G.obedit==NULL) BIF_undo_push("Border select");
|
||||
|
||||
} /* end of borderselect() */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -1322,6 +1327,7 @@ void fly(void)
|
||||
}
|
||||
else if(toets==SPACEKEY) {
|
||||
loop= 0;
|
||||
BIF_undo_push("Fly camera");
|
||||
break;
|
||||
}
|
||||
else if(toets==LEFTMOUSE) {
|
||||
|
||||
@@ -886,6 +886,26 @@ static void do_info_filemenu(void *arg, int event)
|
||||
case 14:
|
||||
G.fileflags ^= G_FILE_NO_UI;
|
||||
break;
|
||||
case 15: /* recover previous session */
|
||||
{
|
||||
extern short winqueue_break; /* editscreen.c */
|
||||
int save_over;
|
||||
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||
char scestr[FILE_MAXDIR+FILE_MAXFILE];
|
||||
|
||||
strcpy(scestr, G.sce); /* temporal store */
|
||||
save_over = G.save_over;
|
||||
BLI_make_file_string("/", str, U.tempdir, "quit.blend");
|
||||
BKE_read_file(str, NULL);
|
||||
G.save_over = save_over;
|
||||
strcpy(G.sce, scestr);
|
||||
|
||||
winqueue_break= 1; /* leave queues everywhere */
|
||||
|
||||
BKE_reset_undo();
|
||||
BKE_write_undo("original"); /* save current state */
|
||||
}
|
||||
break;
|
||||
case 31: /* save default settings */
|
||||
BIF_write_homefile();
|
||||
break;
|
||||
@@ -905,6 +925,7 @@ static uiBlock *info_filemenu(void *arg_unused)
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "New|Ctrl X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Open...|F1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reopen Last|Ctrl O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Recover Last Session", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
|
||||
@@ -3436,7 +3436,7 @@ void do_view3d_buttons(short event)
|
||||
}
|
||||
#endif /* NAN_VPT */
|
||||
if(G.obedit==0) enter_editmode();
|
||||
else exit_editmode(1);
|
||||
else exit_editmode(2); // freedata, and undo
|
||||
scrarea_queue_headredraw(curarea);
|
||||
break;
|
||||
case B_POSEMODE:
|
||||
@@ -3590,7 +3590,7 @@ void do_view3d_buttons(short event)
|
||||
G.f &= ~G_WEIGHTPAINT; /* Switch off weight paint */
|
||||
G.f &= ~G_FACESELECT; /* Switch off face select */
|
||||
if (G.obpose) exit_posemode(1); /* exit posemode */
|
||||
if(G.obedit) exit_editmode(1); /* exit editmode */
|
||||
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
|
||||
} else if (G.vd->modeselect == V3D_EDITMODE_SEL) {
|
||||
if(!G.obedit) {
|
||||
G.vd->flag &= ~V3D_MODE;
|
||||
@@ -3603,7 +3603,7 @@ void do_view3d_buttons(short event)
|
||||
}
|
||||
} else if (G.vd->modeselect == V3D_FACESELECTMODE_SEL) {
|
||||
if ((G.obedit) && (G.f & G_FACESELECT)) {
|
||||
exit_editmode(1); /* exit editmode */
|
||||
exit_editmode(2); /* exit editmode and undo */
|
||||
} else if ((G.f & G_FACESELECT) && (G.f & G_VERTEXPAINT)) {
|
||||
G.f &= ~G_VERTEXPAINT;
|
||||
} else if ((G.f & G_FACESELECT) && (G.f & G_TEXTUREPAINT)) {
|
||||
@@ -3614,7 +3614,7 @@ void do_view3d_buttons(short event)
|
||||
G.f &= ~G_TEXTUREPAINT; /* Switch off texture paint */
|
||||
G.f &= ~G_WEIGHTPAINT; /* Switch off weight paint */
|
||||
if (G.obpose) exit_posemode(1); /* exit posemode */
|
||||
if (G.obedit) exit_editmode(1); /* exit editmode */
|
||||
if (G.obedit) exit_editmode(2); /* exit editmode and undo */
|
||||
|
||||
set_faceselect();
|
||||
}
|
||||
@@ -3624,7 +3624,7 @@ void do_view3d_buttons(short event)
|
||||
G.f &= ~G_TEXTUREPAINT; /* Switch off texture paint */
|
||||
G.f &= ~G_WEIGHTPAINT; /* Switch off weight paint */
|
||||
if (G.obpose) exit_posemode(1); /* exit posemode */
|
||||
if(G.obedit) exit_editmode(1); /* exit editmode */
|
||||
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
|
||||
|
||||
set_vpaint();
|
||||
}
|
||||
@@ -3634,7 +3634,7 @@ void do_view3d_buttons(short event)
|
||||
G.f &= ~G_VERTEXPAINT; /* Switch off vertex paint */
|
||||
G.f &= ~G_WEIGHTPAINT; /* Switch off weight paint */
|
||||
if (G.obpose) exit_posemode(1); /* exit posemode */
|
||||
if(G.obedit) exit_editmode(1); /* exit editmode */
|
||||
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
|
||||
|
||||
G.f |= G_TEXTUREPAINT; /* Switch on texture paint flag */
|
||||
}
|
||||
@@ -3644,14 +3644,14 @@ void do_view3d_buttons(short event)
|
||||
G.f &= ~G_VERTEXPAINT; /* Switch off vertex paint */
|
||||
G.f &= ~G_TEXTUREPAINT; /* Switch off texture paint */
|
||||
if (G.obpose) exit_posemode(1); /* exit posemode */
|
||||
if(G.obedit) exit_editmode(1); /* exit editmode */
|
||||
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
|
||||
|
||||
set_wpaint();
|
||||
}
|
||||
} else if (G.vd->modeselect == V3D_POSEMODE_SEL) {
|
||||
if (!G.obpose) {
|
||||
G.vd->flag &= ~V3D_MODE;
|
||||
if(G.obedit) exit_editmode(1); /* exit editmode */
|
||||
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
|
||||
|
||||
enter_posemode();
|
||||
}
|
||||
|
||||
@@ -3091,7 +3091,8 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
|
||||
if(inside || uevent->event!=LEFTMOUSE) {
|
||||
butevent= ui_do_button(block, but, uevent);
|
||||
|
||||
if(but->type!=BLOCK && but->type!=MENU) BIF_write_undo(but->str);
|
||||
if( !(block->flag & UI_BLOCK_LOOP))
|
||||
if(but->type!=BLOCK && but->type!=MENU) BIF_undo_push(but->str);
|
||||
|
||||
if(butevent) addqueue(block->winq, UI_BUT_EVENT, (short)butevent);
|
||||
|
||||
|
||||
@@ -474,7 +474,10 @@ char *BIF_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
|
||||
|
||||
#define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
|
||||
|
||||
// initialize
|
||||
/* initialize
|
||||
Note: when you add new colors, created & saved themes need initialized
|
||||
in usiblender.c, search for "versionfile"
|
||||
*/
|
||||
void BIF_InitTheme(void)
|
||||
{
|
||||
bTheme *btheme= U.themes.first;
|
||||
|
||||
@@ -620,18 +620,87 @@ static unsigned short convert_for_nonumpad(unsigned short event)
|
||||
|
||||
/* *************** */
|
||||
|
||||
void BIF_undo()
|
||||
void BIF_undo_push(char *str)
|
||||
{
|
||||
|
||||
if(G.obedit) {
|
||||
if(G.obedit->type==OB_MESH)
|
||||
undo_push_mesh(str);
|
||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
|
||||
undo_push_curve(str);
|
||||
}
|
||||
else {
|
||||
if(U.uiflag & USER_GLOBALUNDO)
|
||||
BKE_write_undo(str);
|
||||
}
|
||||
}
|
||||
|
||||
void BIF_redo()
|
||||
void BIF_undo(void)
|
||||
{
|
||||
extern void undo_curve_step(int step); // editcurve.c
|
||||
|
||||
if(G.obedit) {
|
||||
if(G.obedit->type==OB_MESH)
|
||||
undo_pop_mesh(1);
|
||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
|
||||
undo_curve_step(1);
|
||||
|
||||
}
|
||||
else {
|
||||
if (G.f & G_FACESELECT)
|
||||
;
|
||||
else if(G.f & G_WEIGHTPAINT)
|
||||
wpaint_undo();
|
||||
else if(G.f & G_VERTEXPAINT)
|
||||
vpaint_undo();
|
||||
else {
|
||||
if(U.uiflag & USER_GLOBALUNDO) BKE_undo_step(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BIF_undo_menu()
|
||||
void BIF_redo(void)
|
||||
{
|
||||
extern void undo_curve_step(int step); // editcurve.c
|
||||
|
||||
if(G.obedit) {
|
||||
if(G.obedit->type==OB_MESH)
|
||||
undo_redo_mesh();
|
||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
|
||||
undo_curve_step(-1);
|
||||
|
||||
}
|
||||
else {
|
||||
if (G.f & G_FACESELECT)
|
||||
;
|
||||
else if(G.f & G_WEIGHTPAINT)
|
||||
wpaint_undo();
|
||||
else if(G.f & G_VERTEXPAINT)
|
||||
vpaint_undo();
|
||||
else {
|
||||
if(U.uiflag & USER_GLOBALUNDO) BKE_undo_step(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BIF_undo_menu(void)
|
||||
{
|
||||
if(G.obedit) {
|
||||
if(G.obedit->type==OB_MESH)
|
||||
undo_menu_mesh();
|
||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
|
||||
;//undo_menu_curve();
|
||||
}
|
||||
else {
|
||||
if (G.f & G_FACESELECT)
|
||||
;
|
||||
else if(G.f & G_WEIGHTPAINT)
|
||||
;
|
||||
else if(G.f & G_VERTEXPAINT)
|
||||
;
|
||||
else {
|
||||
if(U.uiflag & USER_GLOBALUNDO) BKE_undo_menu();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1469,12 +1538,12 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
else if(G.f & G_VERTEXPAINT)
|
||||
vpaint_undo();
|
||||
else {
|
||||
if(U.uiflag & USER_GLOBALUNDO) BIF_undo_step(1);
|
||||
if(U.uiflag & USER_GLOBALUNDO) BIF_undo();
|
||||
else single_user();
|
||||
}
|
||||
}
|
||||
else if(G.qual==LR_SHIFTKEY)
|
||||
if(U.uiflag & USER_GLOBALUNDO) BIF_undo_step(-1);
|
||||
if(U.uiflag & USER_GLOBALUNDO) BIF_redo();
|
||||
|
||||
break;
|
||||
case VKEY:
|
||||
@@ -1537,7 +1606,6 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
scrarea_queue_winredraw(curarea);
|
||||
break;
|
||||
|
||||
|
||||
case HOMEKEY:
|
||||
if(G.qual==0)
|
||||
view3d_home(0);
|
||||
|
||||
@@ -61,15 +61,16 @@
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "BKE_ika.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_screen.h"
|
||||
@@ -742,7 +743,7 @@ int blenderqread(unsigned short event, short val)
|
||||
if(G.obedit==0)
|
||||
enter_editmode();
|
||||
else
|
||||
exit_editmode(1);
|
||||
exit_editmode(2); // freedata, and undo
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -757,7 +758,7 @@ int blenderqread(unsigned short event, short val)
|
||||
}
|
||||
else if(G.qual==LR_SHIFTKEY) {
|
||||
if(G.obedit)
|
||||
exit_editmode(1);
|
||||
exit_editmode(2); // freedata, and undo
|
||||
if(G.f & G_FACESELECT)
|
||||
set_faceselect();
|
||||
if(G.f & G_VERTEXPAINT)
|
||||
@@ -795,7 +796,7 @@ int blenderqread(unsigned short event, short val)
|
||||
if(G.obedit==0)
|
||||
enter_editmode();
|
||||
else
|
||||
exit_editmode(1);
|
||||
exit_editmode(2); // freedata, and undo
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -908,8 +909,7 @@ int blenderqread(unsigned short event, short val)
|
||||
}
|
||||
}
|
||||
else if(event==4) {
|
||||
extern void BIF_write_undo(char *name);
|
||||
BIF_write_undo("10 timer");
|
||||
BKE_write_undo("10 timer");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -967,6 +967,13 @@ int blenderqread(unsigned short event, short val)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZKEY: // undo
|
||||
if(G.qual & LR_CTRLKEY) { // all combos with ctrl/cammandkey are accepted
|
||||
if(G.qual==LR_CTRLKEY) BIF_undo();
|
||||
else BIF_redo(); // all combos with ctrl is redo
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -122,11 +122,6 @@
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
// temporal, will go to include file
|
||||
void BIF_reset_undo(void);
|
||||
void BIF_write_undo(char *);
|
||||
|
||||
|
||||
/***/
|
||||
|
||||
void BIF_read_file(char *name)
|
||||
@@ -150,8 +145,8 @@ void BIF_read_file(char *name)
|
||||
|
||||
winqueue_break= 1; /* leave queues everywhere */
|
||||
|
||||
BIF_reset_undo();
|
||||
BIF_write_undo("original"); /* save current state */
|
||||
BKE_reset_undo();
|
||||
BKE_write_undo("original"); /* save current state */
|
||||
}
|
||||
|
||||
int BIF_read_homefile(void)
|
||||
@@ -213,7 +208,7 @@ int BIF_read_homefile(void)
|
||||
}
|
||||
if (U.savetime <= 0) {
|
||||
U.savetime = 1;
|
||||
error("%s is buggy, please cosider removing it.\n",
|
||||
error("%s is buggy, please consider removing it.\n",
|
||||
tstr);
|
||||
}
|
||||
if (G.main->versionfile <= 191) {
|
||||
@@ -231,11 +226,32 @@ int BIF_read_homefile(void)
|
||||
U.vrmlflag= USER_VRML_LAYERS;
|
||||
}
|
||||
|
||||
/* added seam, normal color */
|
||||
if (G.main->versionfile <= 234) {
|
||||
bTheme *btheme;
|
||||
|
||||
for(btheme= U.themes.first; btheme; btheme= btheme->next) {
|
||||
/* check for alpha==0 is safe, then color was never set */
|
||||
if(btheme->tv3d.edge_seam[3]==0) {
|
||||
btheme->tv3d.edge_seam[0]= 230;
|
||||
btheme->tv3d.edge_seam[1]= 150;
|
||||
btheme->tv3d.edge_seam[2]= 50;
|
||||
btheme->tv3d.edge_seam[3]= 255;
|
||||
}
|
||||
if(btheme->tv3d.normal[3]==0) {
|
||||
btheme->tv3d.normal[0]= 0x22;
|
||||
btheme->tv3d.normal[1]= 0xDD;
|
||||
btheme->tv3d.normal[2]= 0xDD;
|
||||
btheme->tv3d.normal[3]= 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
space_set_commmandline_options();
|
||||
|
||||
if (U.undosteps==0) U.undosteps=32;
|
||||
BIF_reset_undo();
|
||||
BIF_write_undo("original"); /* save current state */
|
||||
BKE_reset_undo();
|
||||
BKE_write_undo("original"); /* save current state */
|
||||
|
||||
reset_autosave();
|
||||
|
||||
@@ -455,6 +471,7 @@ void BIF_write_autosave(void)
|
||||
BLO_write_file(tstr, write_flags, &err);
|
||||
}
|
||||
|
||||
/* if global undo; remove tempsave, otherwise rename */
|
||||
static void delete_autosave(void)
|
||||
{
|
||||
char tstr[FILE_MAXDIR+FILE_MAXFILE];
|
||||
@@ -464,7 +481,9 @@ static void delete_autosave(void)
|
||||
if (BLI_exists(tstr)) {
|
||||
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||
BLI_make_file_string("/", str, U.tempdir, "quit.blend");
|
||||
BLI_rename(tstr, str);
|
||||
|
||||
if(U.uiflag & USER_GLOBALUNDO) BLI_delete(tstr, 0, 0);
|
||||
else BLI_rename(tstr, str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,7 +605,9 @@ void exit_usiblender(void)
|
||||
|
||||
if (G.undo_clear) G.undo_clear();
|
||||
undo_clear_curve();
|
||||
BIF_reset_undo();
|
||||
|
||||
BKE_undo_save_quit(); // saves quit.blend if global undo is on
|
||||
BKE_reset_undo();
|
||||
|
||||
BLI_freelistN(&U.themes);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user