Bugfix #6053
When in sculptmode, enter editmode, add faces or vertices, exit editmode, then undos/redos screw up mesh. Now the stack for sculpt is freed. Later on one could precisely test why this undo isn't resistant to such changes.
This commit is contained in:
@@ -89,13 +89,13 @@ typedef struct SculptSession {
|
|||||||
vec3f pivot;
|
vec3f pivot;
|
||||||
} SculptSession;
|
} SculptSession;
|
||||||
|
|
||||||
SculptSession *sculpt_session();
|
SculptSession *sculpt_session(void);
|
||||||
struct SculptData *sculpt_data();
|
struct SculptData *sculpt_data(void);
|
||||||
|
|
||||||
/* Memory */
|
/* Memory */
|
||||||
void sculptmode_init(struct Scene *);
|
void sculptmode_init(struct Scene *);
|
||||||
void sculptmode_free_all(struct Scene *);
|
void sculptmode_free_all(struct Scene *);
|
||||||
void sculptmode_correct_state();
|
void sculptmode_correct_state(void);
|
||||||
|
|
||||||
/* Undo */
|
/* Undo */
|
||||||
typedef enum SculptUndoType {
|
typedef enum SculptUndoType {
|
||||||
@@ -105,9 +105,10 @@ typedef enum SculptUndoType {
|
|||||||
SUNDO_MRES= 8 /* Mesh.mr changed */
|
SUNDO_MRES= 8 /* Mesh.mr changed */
|
||||||
} SculptUndoType;
|
} SculptUndoType;
|
||||||
void sculptmode_undo_push(char *str, SculptUndoType type);
|
void sculptmode_undo_push(char *str, SculptUndoType type);
|
||||||
void sculptmode_undo();
|
void sculptmode_undo(void);
|
||||||
void sculptmode_redo();
|
void sculptmode_redo(void);
|
||||||
void sculptmode_undo_menu();
|
void sculptmode_undo_menu(void);
|
||||||
|
void sculptmode_undo_free(struct Scene *sce);
|
||||||
|
|
||||||
/* Interface */
|
/* Interface */
|
||||||
void sculptmode_draw_interface_tools(struct uiBlock *block,unsigned short cx, unsigned short cy);
|
void sculptmode_draw_interface_tools(struct uiBlock *block,unsigned short cx, unsigned short cy);
|
||||||
@@ -115,17 +116,17 @@ void sculptmode_draw_interface_textures(struct uiBlock *block,unsigned short cx,
|
|||||||
void sculptmode_rem_tex(void*,void*);
|
void sculptmode_rem_tex(void*,void*);
|
||||||
void sculptmode_propset_init(PropsetMode mode);
|
void sculptmode_propset_init(PropsetMode mode);
|
||||||
void sculptmode_propset(const unsigned short event);
|
void sculptmode_propset(const unsigned short event);
|
||||||
void sculptmode_selectbrush_menu();
|
void sculptmode_selectbrush_menu(void);
|
||||||
void sculptmode_draw_mesh(int);
|
void sculptmode_draw_mesh(int);
|
||||||
void sculpt_paint_brush(char clear);
|
void sculpt_paint_brush(char clear);
|
||||||
|
|
||||||
struct BrushData *sculptmode_brush();
|
struct BrushData *sculptmode_brush(void);
|
||||||
float *get_tex_angle();
|
float *get_tex_angle(void);
|
||||||
|
|
||||||
void sculptmode_update_tex();
|
void sculptmode_update_tex(void);
|
||||||
char sculpt_modifiers_active(struct Object *ob);
|
char sculpt_modifiers_active(struct Object *ob);
|
||||||
void sculpt();
|
void sculpt(void);
|
||||||
void set_sculptmode();
|
void set_sculptmode(void);
|
||||||
|
|
||||||
/* Partial Mesh Visibility */
|
/* Partial Mesh Visibility */
|
||||||
struct PartialVisibility *sculptmode_copy_pmv(struct PartialVisibility *);
|
struct PartialVisibility *sculptmode_copy_pmv(struct PartialVisibility *);
|
||||||
|
|||||||
@@ -1696,6 +1696,9 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b
|
|||||||
allqueue(REDRAWIMAGE, 0);
|
allqueue(REDRAWIMAGE, 0);
|
||||||
if(G.f & G_WEIGHTPAINT)
|
if(G.f & G_WEIGHTPAINT)
|
||||||
mesh_octree_table(G.obedit, NULL, 'e');
|
mesh_octree_table(G.obedit, NULL, 'e');
|
||||||
|
/* to be sure, adding/removing data crashes undo for sculpt (ton) */
|
||||||
|
if(G.f & G_SCULPTMODE)
|
||||||
|
sculptmode_undo_free(G.scene);
|
||||||
}
|
}
|
||||||
else if (G.obedit->type==OB_ARMATURE){
|
else if (G.obedit->type==OB_ARMATURE){
|
||||||
load_editArmature();
|
load_editArmature();
|
||||||
|
|||||||
@@ -161,13 +161,14 @@ typedef struct ProjVert {
|
|||||||
static ProjVert *projverts= NULL;
|
static ProjVert *projverts= NULL;
|
||||||
static Object *active_ob= NULL;
|
static Object *active_ob= NULL;
|
||||||
|
|
||||||
SculptData *sculpt_data()
|
SculptData *sculpt_data(void)
|
||||||
{
|
{
|
||||||
return &G.scene->sculptdata;
|
return &G.scene->sculptdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sculpt_init_session();
|
void sculpt_init_session(void);
|
||||||
SculptSession *sculpt_session()
|
|
||||||
|
SculptSession *sculpt_session(void)
|
||||||
{
|
{
|
||||||
if(!sculpt_data()->session)
|
if(!sculpt_data()->session)
|
||||||
sculpt_init_session();
|
sculpt_init_session();
|
||||||
@@ -212,7 +213,7 @@ void sculptmode_init(Scene *sce)
|
|||||||
|
|
||||||
void sculptmode_undo_init();
|
void sculptmode_undo_init();
|
||||||
void sculptmode_free_session(Scene *);
|
void sculptmode_free_session(Scene *);
|
||||||
void sculpt_init_session()
|
void sculpt_init_session(void)
|
||||||
{
|
{
|
||||||
if(sculpt_data()->session)
|
if(sculpt_data()->session)
|
||||||
sculptmode_free_session(G.scene);
|
sculptmode_free_session(G.scene);
|
||||||
@@ -336,6 +337,7 @@ void sculptmode_undo_pull_chopped(SculptUndoStep *sus)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* also called now after leave mesh editmode. prevent crashing when data amount changes */
|
||||||
void sculptmode_undo_free(Scene *sce)
|
void sculptmode_undo_free(Scene *sce)
|
||||||
{
|
{
|
||||||
SculptSession *ss= sce->sculptdata.session;
|
SculptSession *ss= sce->sculptdata.session;
|
||||||
@@ -508,7 +510,7 @@ void sculptmode_undo_update(SculptUndoStep *newcur)
|
|||||||
allqueue(REDRAWBUTSEDIT, 0);
|
allqueue(REDRAWBUTSEDIT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sculptmode_undo()
|
void sculptmode_undo(void)
|
||||||
{
|
{
|
||||||
SculptUndo *su= sculpt_session()->undo;
|
SculptUndo *su= sculpt_session()->undo;
|
||||||
|
|
||||||
@@ -516,7 +518,7 @@ void sculptmode_undo()
|
|||||||
sculptmode_undo_update(su->cur->prev);
|
sculptmode_undo_update(su->cur->prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sculptmode_redo()
|
void sculptmode_redo(void)
|
||||||
{
|
{
|
||||||
SculptUndo *su= sculpt_session()->undo;
|
SculptUndo *su= sculpt_session()->undo;
|
||||||
|
|
||||||
@@ -524,7 +526,7 @@ void sculptmode_redo()
|
|||||||
sculptmode_undo_update(su->cur->next);
|
sculptmode_undo_update(su->cur->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sculptmode_undo_menu()
|
void sculptmode_undo_menu(void)
|
||||||
{
|
{
|
||||||
SculptUndo *su= sculpt_session()->undo;
|
SculptUndo *su= sculpt_session()->undo;
|
||||||
SculptUndoStep *sus;
|
SculptUndoStep *sus;
|
||||||
@@ -1004,7 +1006,7 @@ unsigned *get_ri_pixel(const RenderInfo *ri, int px, int py)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Use the warpfac field in MTex to store a rotation value for sculpt textures. */
|
/* Use the warpfac field in MTex to store a rotation value for sculpt textures. */
|
||||||
float *get_tex_angle()
|
float *get_tex_angle(void)
|
||||||
{
|
{
|
||||||
SculptData *sd= sculpt_data();
|
SculptData *sd= sculpt_data();
|
||||||
if(sd->texact!=-1 && sd->mtex[sd->texact])
|
if(sd->texact!=-1 && sd->mtex[sd->texact])
|
||||||
@@ -1326,7 +1328,7 @@ void calc_damaged_verts(ListBase *damaged_verts, GrabData *grabdata)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BrushData *sculptmode_brush()
|
BrushData *sculptmode_brush(void)
|
||||||
{
|
{
|
||||||
SculptData *sd= &G.scene->sculptdata;
|
SculptData *sd= &G.scene->sculptdata;
|
||||||
return (sd->brush_type==DRAW_BRUSH ? &sd->drawbrush :
|
return (sd->brush_type==DRAW_BRUSH ? &sd->drawbrush :
|
||||||
@@ -1694,7 +1696,7 @@ void sculptmode_propset(unsigned short event)
|
|||||||
sculptmode_propset_header();
|
sculptmode_propset_header();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sculptmode_selectbrush_menu()
|
void sculptmode_selectbrush_menu(void)
|
||||||
{
|
{
|
||||||
SculptData *sd= sculpt_data();
|
SculptData *sd= sculpt_data();
|
||||||
int val;
|
int val;
|
||||||
@@ -1745,7 +1747,8 @@ void sculptmode_draw_wires(int only_damaged, Mesh *me)
|
|||||||
bglPolygonOffset(0.0);
|
bglPolygonOffset(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sculptmode_draw_mesh(int only_damaged) {
|
void sculptmode_draw_mesh(int only_damaged)
|
||||||
|
{
|
||||||
Mesh *me= get_mesh(OBACT);
|
Mesh *me= get_mesh(OBACT);
|
||||||
int i, j, dt, drawCurrentMat = 1, matnr= -1;
|
int i, j, dt, drawCurrentMat = 1, matnr= -1;
|
||||||
|
|
||||||
@@ -1799,7 +1802,7 @@ void sculptmode_draw_mesh(int only_damaged) {
|
|||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sculptmode_correct_state()
|
void sculptmode_correct_state(void)
|
||||||
{
|
{
|
||||||
if(!sculpt_session())
|
if(!sculpt_session())
|
||||||
sculpt_init_session();
|
sculpt_init_session();
|
||||||
@@ -1824,7 +1827,7 @@ char sculpt_modifiers_active(Object *ob)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sculpt()
|
void sculpt(void)
|
||||||
{
|
{
|
||||||
SculptData *sd= sculpt_data();
|
SculptData *sd= sculpt_data();
|
||||||
SculptSession *ss= sculpt_session();
|
SculptSession *ss= sculpt_session();
|
||||||
@@ -2042,7 +2045,7 @@ void sculpt()
|
|||||||
allqueue(REDRAWVIEW3D, 0);
|
allqueue(REDRAWVIEW3D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_sculptmode()
|
void set_sculptmode(void)
|
||||||
{
|
{
|
||||||
if(G.f & G_SCULPTMODE) {
|
if(G.f & G_SCULPTMODE) {
|
||||||
Mesh *me= get_mesh(OBACT);
|
Mesh *me= get_mesh(OBACT);
|
||||||
|
|||||||
Reference in New Issue
Block a user