Cleanup: sync vertex-paint and sculpt from 2.8
authorCampbell Barton <ideasman42@gmail.com>
Mon, 19 Feb 2018 01:20:18 +0000 (12:20 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 19 Feb 2018 04:54:06 +0000 (15:54 +1100)
Sync API changes from 2.8 to master.

source/blender/editors/include/ED_object.h
source/blender/editors/sculpt_paint/paint_hide.c
source/blender/editors/sculpt_paint/paint_mask.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/sculpt_paint/sculpt_intern.h
source/blender/editors/sculpt_paint/sculpt_undo.c
source/blender/editors/util/undo.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_files.c

index 8456c15c79d908ee0bc518736f9192f3968e9084..4baec6a58eff5ebe62864c4fe9c63ae201f79510 100644 (file)
@@ -127,6 +127,25 @@ bool ED_object_editmode_load(struct Object *obedit);
 
 bool ED_object_editmode_calc_active_center(struct Object *obedit, const bool select_only, float r_center[3]);
 
+
+void ED_object_vpaintmode_enter_ex(
+        struct wmWindowManager *wm,
+        struct Scene *scene, struct Object *ob);
+void ED_object_vpaintmode_enter(struct bContext *C);
+void ED_object_wpaintmode_enter_ex(
+        struct wmWindowManager *wm,
+        struct Scene *scene, struct Object *ob);
+void ED_object_wpaintmode_enter(struct bContext *C);
+
+void ED_object_vpaintmode_exit_ex(struct Object *ob);
+void ED_object_vpaintmode_exit(struct bContext *C);
+void ED_object_wpaintmode_exit_ex(struct Object *ob);
+void ED_object_wpaintmode_exit(struct bContext *C);
+
+void ED_object_sculptmode_exit_ex(
+        struct Scene *scene, struct Object *ob);
+void ED_object_sculptmode_exit(struct bContext *C);
+
 void ED_object_location_from_view(struct bContext *C, float loc[3]);
 void ED_object_rotation_from_view(struct bContext *C, float rot[3], const char align_axis);
 void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]);
@@ -186,22 +205,25 @@ enum {
        MODIFIER_APPLY_SHAPE
 };
 
-struct ModifierData *ED_object_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene,
-                                            struct Object *ob, const char *name, int type);
+struct ModifierData *ED_object_modifier_add(
+        struct ReportList *reports, struct Main *bmain, struct Scene *scene,
+        struct Object *ob, const char *name, int type);
 bool ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain,
                                struct Object *ob, struct ModifierData *md);
 void ED_object_modifier_clear(struct Main *bmain, struct Object *ob);
 int ED_object_modifier_move_down(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
 int ED_object_modifier_move_up(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
-int ED_object_modifier_convert(struct ReportList *reports, struct Main *bmain, struct Scene *scene,
-                               struct Object *ob, struct ModifierData *md);
+int ED_object_modifier_convert(
+        struct ReportList *reports, struct Main *bmain, struct Scene *scene,
+        struct Object *ob, struct ModifierData *md);
 int ED_object_modifier_apply(struct ReportList *reports, struct Scene *scene,
                              struct Object *ob, struct ModifierData *md, int mode);
 int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
 
-bool ED_object_iter_other(struct Main *bmain, struct Object *orig_ob, const bool include_orig,
-                          bool (*callback)(struct Object *ob, void *callback_data),
-                          void *callback_data);
+bool ED_object_iter_other(
+        struct Main *bmain, struct Object *orig_ob, const bool include_orig,
+        bool (*callback)(struct Object *ob, void *callback_data),
+        void *callback_data);
 
 bool ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v);
 
@@ -215,7 +237,8 @@ const struct EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(
         bool *r_free,
         const unsigned int selection_mask);
 
-void ED_object_check_force_modifiers(struct Main *bmain, struct Scene *scene, struct Object *object);
+void ED_object_check_force_modifiers(
+        struct Main *bmain, struct Scene *scene, struct Object *object);
 
 #ifdef __cplusplus
 }
index d085c6953da441d1e0e3013ea8d2cacd4ba7cfdd..a49fe9c929a2ca8a1ba5d41421af8da0d6ccc629 100644 (file)
@@ -417,7 +417,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
                MEM_freeN(nodes);
        
        /* end undo */
-       sculpt_undo_push_end(C);
+       sculpt_undo_push_end();
 
        /* ensure that edges and faces get hidden as well (not used by
         * sculpt but it looks wrong when entering editmode otherwise) */
index 9d960980f30ce019022439971ebf16a47571133b..8e091bdf59ca03443aac68341d46ff1d9ea64f2e 100644 (file)
@@ -168,7 +168,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
        if (multires)
                multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
 
-       sculpt_undo_push_end(C);
+       sculpt_undo_push_end();
 
        if (nodes)
                MEM_freeN(nodes);
@@ -323,7 +323,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r
        if (multires)
                multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
 
-       sculpt_undo_push_end(C);
+       sculpt_undo_push_end();
 
        ED_region_tag_redraw(ar);
 
@@ -509,7 +509,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
                if (multires)
                        multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
 
-               sculpt_undo_push_end(C);
+               sculpt_undo_push_end();
 
                ED_region_tag_redraw(vc.ar);
                MEM_freeN((void *)mcords);
index 490343ab1f2cb9b8050db0bc2b580b0d09453bbb..e550ed66fc291bbe95eb25a6371a3888f5cc6a6e 100644 (file)
@@ -1026,71 +1026,187 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
 
 }
 
-/* *************** set wpaint operator ****************** */
+/* -------------------------------------------------------------------- */
+/** \name Enter Vertex/Weight Paint Mode
+ * \{ */
 
-/**
- * \note Keep in sync with #vpaint_mode_toggle_exec
- */
-static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
+static void ed_vwpaintmode_enter_generic(
+        wmWindowManager *wm,
+        Scene *scene,
+        Object *ob, const eObjectMode mode_flag)
 {
-       Object *ob = CTX_data_active_object(C);
-       const int mode_flag = OB_MODE_WEIGHT_PAINT;
-       const bool is_mode_set = (ob->mode & mode_flag) != 0;
-       Scene *scene = CTX_data_scene(C);
-       VPaint *wp = scene->toolsettings->wpaint;
-       Mesh *me;
+       ob->mode |= mode_flag;
+       Mesh *me = BKE_mesh_from_object(ob);
 
-       if (!is_mode_set) {
-               if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
-                       return OPERATOR_CANCELLED;
+       if (mode_flag == OB_MODE_VERTEX_PAINT) {
+               const ePaintMode paint_mode = ePaintVertex;
+               ED_mesh_color_ensure(me, NULL);
+
+               if (scene->toolsettings->vpaint == NULL) {
+                       scene->toolsettings->vpaint = new_vpaint();
                }
+
+               Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
+               paint_cursor_start_explicit(paint, wm, vertex_paint_poll);
+               BKE_paint_init(scene, paint_mode, PAINT_CURSOR_VERTEX_PAINT);
        }
+       else if (mode_flag == OB_MODE_WEIGHT_PAINT) {
+               const  ePaintMode paint_mode = ePaintWeight;
 
-       me = BKE_mesh_from_object(ob);
+               if (scene->toolsettings->wpaint == NULL) {
+                       scene->toolsettings->wpaint = new_vpaint();
+               }
+
+               Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
+               paint_cursor_start_explicit(paint, wm, weight_paint_poll);
+               BKE_paint_init(scene, paint_mode, PAINT_CURSOR_WEIGHT_PAINT);
+
+               /* weight paint specific */
+               ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
+               ED_vgroup_sync_from_pose(ob);
+       }
+       else {
+               BLI_assert(0);
+       }
+
+       /* Create vertex/weight paint mode session data */
+       if (ob->sculpt) {
+               if (ob->sculpt->cache) {
+                       sculpt_cache_free(ob->sculpt->cache);
+                       ob->sculpt->cache = NULL;
+               }
+               BKE_sculptsession_free(ob);
+       }
+
+       vertex_paint_init_session(scene, ob);
+}
+
+void ED_object_vpaintmode_enter_ex(
+        wmWindowManager *wm,
+        Scene *scene, Object *ob)
+{
+       ed_vwpaintmode_enter_generic(
+               wm, scene, ob, OB_MODE_VERTEX_PAINT);
+}
+void ED_object_vpaintmode_enter(struct bContext *C)
+{
+       wmWindowManager *wm = CTX_wm_manager(C);
+       Scene *scene = CTX_data_scene(C);
+       Object *ob = CTX_data_active_object(C);
+       ED_object_vpaintmode_enter_ex(wm, scene, ob);
+}
+
+void ED_object_wpaintmode_enter_ex(
+        wmWindowManager *wm,
+        Scene *scene, Object *ob)
+{
+       ed_vwpaintmode_enter_generic(
+               wm, scene, ob, OB_MODE_WEIGHT_PAINT);
+}
+void ED_object_wpaintmode_enter(struct bContext *C)
+{
+       wmWindowManager *wm = CTX_wm_manager(C);
+       Scene *scene = CTX_data_scene(C);
+       Object *ob = CTX_data_active_object(C);
+       ED_object_wpaintmode_enter_ex(wm, scene, ob);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exit Vertex/Weight Paint Mode
+ * \{ */
 
-       if (ob->mode & mode_flag) {
-               ob->mode &= ~mode_flag;
+static void ed_vwpaintmode_exit_generic(
+        Object *ob, const eObjectMode mode_flag)
+{
+       Mesh *me = BKE_mesh_from_object(ob);
+       ob->mode &= ~mode_flag;
 
+       if (mode_flag == OB_MODE_VERTEX_PAINT) {
+               if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
+                       BKE_mesh_flush_select_from_polys(me);
+               }
+               else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
+                       BKE_mesh_flush_select_from_verts(me);
+               }
+       }
+       else if (mode_flag == OB_MODE_WEIGHT_PAINT) {
                if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
                        BKE_mesh_flush_select_from_verts(me);
                }
                else if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
                        BKE_mesh_flush_select_from_polys(me);
                }
+       }
+       else {
+               BLI_assert(0);
+       }
 
-               /* weight paint specific */
-               ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
-               ED_mesh_mirror_topo_table(NULL, NULL, 'e');
+       /* If the cache is not released by a cancel or a done, free it now. */
+       if (ob->sculpt->cache) {
+               sculpt_cache_free(ob->sculpt->cache);
+               ob->sculpt->cache = NULL;
+       }
 
-               /* If the cache is not released by a cancel or a done, free it now. */
-               if (ob->sculpt->cache) {
-                       sculpt_cache_free(ob->sculpt->cache);
-                       ob->sculpt->cache = NULL;
-               }
+       BKE_sculptsession_free(ob);
 
-               BKE_sculptsession_free(ob);
+       paint_cursor_delete_textures();
 
-               paint_cursor_delete_textures();
+       if (mode_flag == OB_MODE_WEIGHT_PAINT) {
+               ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
+               ED_mesh_mirror_topo_table(NULL, NULL, 'e');
        }
-       else {
-               ob->mode |= mode_flag;
+}
 
-               if (wp == NULL)
-                       wp = scene->toolsettings->wpaint = new_vpaint();
+void ED_object_vpaintmode_exit_ex(Object *ob)
+{
+       ed_vwpaintmode_exit_generic(ob, OB_MODE_VERTEX_PAINT);
+}
+void ED_object_vpaintmode_exit(struct bContext *C)
+{
+       Object *ob = CTX_data_active_object(C);
+       ED_object_vpaintmode_exit_ex(ob);
+}
+
+void ED_object_wpaintmode_exit_ex(Object *ob)
+{
+       ed_vwpaintmode_exit_generic(ob, OB_MODE_WEIGHT_PAINT);
+}
+void ED_object_wpaintmode_exit(struct bContext *C)
+{
+       Object *ob = CTX_data_active_object(C);
+       ED_object_wpaintmode_exit_ex(ob);
+}
 
-               paint_cursor_start(C, weight_paint_poll);
+/** \} */
 
-               BKE_paint_init(scene, ePaintWeight, PAINT_CURSOR_WEIGHT_PAINT);
+/* *************** set wpaint operator ****************** */
 
-               /* weight paint specific */
-               ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
-               ED_vgroup_sync_from_pose(ob);
+/**
+ * \note Keep in sync with #vpaint_mode_toggle_exec
+ */
+static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
+{
+       Object *ob = CTX_data_active_object(C);
+       const int mode_flag = OB_MODE_WEIGHT_PAINT;
+       const bool is_mode_set = (ob->mode & mode_flag) != 0;
+       Scene *scene = CTX_data_scene(C);
 
-               /* Create vertex/weight paint mode session data */
-               if (ob->sculpt) {
-                       BKE_sculptsession_free(ob);
+       if (!is_mode_set) {
+               if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
+                       return OPERATOR_CANCELLED;
                }
-               vertex_paint_init_session(scene, ob);
+       }
+
+       Mesh *me = BKE_mesh_from_object(ob);
+
+       if (is_mode_set) {
+               ED_object_wpaintmode_exit_ex(ob);
+       }
+       else {
+               wmWindowManager *wm = CTX_wm_manager(C);
+               ED_object_wpaintmode_enter_ex(wm, scene, ob);
        }
 
        /* Weightpaint works by overriding colors in mesh,
@@ -2203,8 +2319,6 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
        const int mode_flag = OB_MODE_VERTEX_PAINT;
        const bool is_mode_set = (ob->mode & mode_flag) != 0;
        Scene *scene = CTX_data_scene(C);
-       VPaint *vp = scene->toolsettings->vpaint;
-       Mesh *me;
 
        if (!is_mode_set) {
                if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
@@ -2212,50 +2326,15 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
                }
        }
 
-       me = BKE_mesh_from_object(ob);
+       Mesh *me = BKE_mesh_from_object(ob);
 
        /* toggle: end vpaint */
        if (is_mode_set) {
-               ob->mode &= ~mode_flag;
-
-               if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
-                       BKE_mesh_flush_select_from_polys(me);
-               }
-               else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
-                       BKE_mesh_flush_select_from_verts(me);
-               }
-
-               /* If the cache is not released by a cancel or a done, free it now. */
-               if (ob->sculpt->cache) {
-                       sculpt_cache_free(ob->sculpt->cache);
-                       ob->sculpt->cache = NULL;
-               }
-
-               BKE_sculptsession_free(ob);
-
-               paint_cursor_delete_textures();
+               ED_object_vpaintmode_exit_ex(ob);
        }
        else {
-               ob->mode |= mode_flag;
-
-               ED_mesh_color_ensure(me, NULL);
-
-               if (vp == NULL)
-                       vp = scene->toolsettings->vpaint = new_vpaint();
-
-               paint_cursor_start(C, vertex_paint_poll);
-
-               BKE_paint_init(scene, ePaintVertex, PAINT_CURSOR_VERTEX_PAINT);
-
-               /* Create vertex/weight paint mode session data */
-               if (ob->sculpt) {
-                       if (ob->sculpt->cache) {
-                               sculpt_cache_free(ob->sculpt->cache);
-                               ob->sculpt->cache = NULL;
-                       }
-                       BKE_sculptsession_free(ob);
-               }
-               vertex_paint_init_session(scene, ob);
+               wmWindowManager *wm = CTX_wm_manager(C);
+               ED_object_vpaintmode_enter_ex(wm, scene, ob);
        }
 
        /* update modifier stack for mapping requirements */
@@ -3103,3 +3182,4 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot)
 
        paint_stroke_operator_properties(ot);
 }
+
index 67cd6e433c3d4e07c04008add1d4640aa37f5f81..497cbf3d84bc0f2332cb3033b6460743894e3139 100644 (file)
@@ -5034,7 +5034,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
                sculpt_cache_free(ss->cache);
                ss->cache = NULL;
 
-               sculpt_undo_push_end(C);
+               sculpt_undo_push_end();
 
                BKE_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL);
                
@@ -5242,21 +5242,19 @@ void sculpt_dyntopo_node_layers_add(SculptSession *ss)
 }
 
 
-void sculpt_update_after_dynamic_topology_toggle(bContext *C)
+void sculpt_update_after_dynamic_topology_toggle(
+        Scene *scene, Object *ob)
 {
-       Scene *scene = CTX_data_scene(C);
-       Object *ob = CTX_data_active_object(C);
        Sculpt *sd = scene->toolsettings->sculpt;
 
        /* Create the PBVH */
        BKE_sculpt_update_mesh_elements(scene, sd, ob, false, false);
-       WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+       WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
 }
 
-void sculpt_dynamic_topology_enable(bContext *C)
+void sculpt_dynamic_topology_enable_ex(
+        Scene *scene, Object *ob)
 {
-       Scene *scene = CTX_data_scene(C);
-       Object *ob = CTX_data_active_object(C);
        SculptSession *ss = ob->sculpt;
        Mesh *me = ob->data;
        const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
@@ -5292,17 +5290,16 @@ void sculpt_dynamic_topology_enable(bContext *C)
        ss->bm_log = BM_log_create(ss->bm);
 
        /* Refresh */
-       sculpt_update_after_dynamic_topology_toggle(C);
+       sculpt_update_after_dynamic_topology_toggle(scene, ob);
 }
 
 /* Free the sculpt BMesh and BMLog
  *
  * If 'unode' is given, the BMesh's data is copied out to the unode
  * before the BMesh is deleted so that it can be restored from */
-void sculpt_dynamic_topology_disable(bContext *C,
-                                     SculptUndoNode *unode)
+void sculpt_dynamic_topology_disable_ex(
+        Scene *scene, Object *ob, SculptUndoNode *unode)
 {
-       Object *ob = CTX_data_active_object(C);
        SculptSession *ss = ob->sculpt;
        Mesh *me = ob->data;
 
@@ -5351,28 +5348,54 @@ void sculpt_dynamic_topology_disable(bContext *C,
        }
 
        /* Refresh */
-       sculpt_update_after_dynamic_topology_toggle(C);
+       sculpt_update_after_dynamic_topology_toggle(scene, ob);
+}
+
+void sculpt_dynamic_topology_disable(bContext *C, SculptUndoNode *unode)
+{
+       Scene *scene = CTX_data_scene(C);
+       Object *ob = CTX_data_active_object(C);
+       sculpt_dynamic_topology_disable_ex(scene, ob, unode);
 }
 
+static void sculpt_dynamic_topology_disable_with_undo(
+        Scene *scene, Object *ob)
+{
+       SculptSession *ss = ob->sculpt;
+       if (ss->bm) {
+               sculpt_undo_push_begin("Dynamic topology disable");
+               sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END);
+               sculpt_dynamic_topology_disable_ex(scene, ob, NULL);
+               sculpt_undo_push_end();
+       }
+}
+
+static void sculpt_dynamic_topology_enable_with_undo(
+        Scene *scene, Object *ob)
+{
+       SculptSession *ss = ob->sculpt;
+       if (ss->bm == NULL) {
+               sculpt_undo_push_begin("Dynamic topology enable");
+               sculpt_dynamic_topology_enable_ex(scene, ob);
+               sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
+               sculpt_undo_push_end();
+       }
+}
 
 static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op))
 {
+       Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
        SculptSession *ss = ob->sculpt;
 
        WM_cursor_wait(1);
 
        if (ss->bm) {
-               sculpt_undo_push_begin("Dynamic topology disable");
-               sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END);
-               sculpt_dynamic_topology_disable(C, NULL);
+               sculpt_dynamic_topology_disable_with_undo(scene, ob);
        }
        else {
-               sculpt_undo_push_begin("Dynamic topology enable");
-               sculpt_dynamic_topology_enable(C);
-               sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
+               sculpt_dynamic_topology_enable_with_undo(scene, ob);
        }
-       sculpt_undo_push_end(C);
 
        WM_cursor_wait(0);
 
@@ -5560,7 +5583,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *UNUSED(op))
 
        /* Finish undo */
        BM_log_all_added(ss->bm, ss->bm_log);
-       sculpt_undo_push_end(C);
+       sculpt_undo_push_end();
 
        /* Redraw */
        sculpt_pbvh_clear(ob);
@@ -5592,6 +5615,53 @@ static void sculpt_init_session(Scene *scene, Object *ob)
        BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, false);
 }
 
+void ED_object_sculptmode_exit_ex(
+        Scene *scene, Object *ob)
+{
+       const int mode_flag = OB_MODE_SCULPT;
+       Mesh *me = BKE_mesh_from_object(ob);
+
+       MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
+       if (mmd) {
+               multires_force_update(ob);
+       }
+
+       /* Always for now, so leaving sculpt mode always ensures scene is in
+        * a consistent state.
+        */
+       if (true || /* flush_recalc || */ (ob->sculpt && ob->sculpt->bm)) {
+               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       }
+
+       if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
+               /* Dynamic topology must be disabled before exiting sculpt
+                * mode to ensure the undo stack stays in a consistent
+                * state */
+               sculpt_dynamic_topology_disable_with_undo(scene, ob);
+
+               /* store so we know to re-enable when entering sculpt mode */
+               me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
+       }
+
+       /* Leave sculptmode */
+       ob->mode &= ~mode_flag;
+
+       BKE_sculptsession_free(ob);
+
+       paint_cursor_delete_textures();
+
+       /* VBO no longer valid */
+       if (ob->derivedFinal) {
+               GPU_drawobject_free(ob->derivedFinal);
+       }
+}
+
+void ED_object_sculptmode_exit(bContext *C)
+{
+       Scene *scene = CTX_data_scene(C);
+       Object *ob = CTX_data_active_object(C);
+       ED_object_sculptmode_exit_ex(scene, ob);
+}
 
 static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
 {
@@ -5617,32 +5687,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
        flush_recalc |= sculpt_has_active_modifiers(scene, ob);
 
        if (is_mode_set) {
-               if (mmd)
-                       multires_force_update(ob);
-
-               /* Always for now, so leaving sculpt mode always ensures scene is in
-                * a consistent state.
-                */
-               if (true || flush_recalc || (ob->sculpt && ob->sculpt->bm)) {
-                       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
-               }
-
-               if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
-                       /* Dynamic topology must be disabled before exiting sculpt
-                        * mode to ensure the undo stack stays in a consistent
-                        * state */
-                       sculpt_dynamic_topology_toggle_exec(C, NULL);
-
-                       /* store so we know to re-enable when entering sculpt mode */
-                       me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
-               }
-
-               /* Leave sculptmode */
-               ob->mode &= ~mode_flag;
-
-               BKE_sculptsession_free(ob);
-
-               paint_cursor_delete_textures();
+               ED_object_sculptmode_exit_ex(scene, ob);
        }
        else {
                /* Enter sculptmode */
@@ -5652,8 +5697,9 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
                        DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 
                /* Create sculpt mode session data */
-               if (ob->sculpt)
+               if (ob->sculpt) {
                        BKE_sculptsession_free(ob);
+               }
 
                sculpt_init_session(scene, ob);
 
@@ -5712,7 +5758,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
                        if (message_unsupported == NULL) {
                                /* undo push is needed to prevent memory leak */
                                sculpt_undo_push_begin("Dynamic topology enable");
-                               sculpt_dynamic_topology_enable(C);
+                               sculpt_dynamic_topology_enable_ex(scene, ob);
                                sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
                        }
                        else {
@@ -5722,10 +5768,12 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
                                me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
                        }
                }
-       }
 
-       if (ob->derivedFinal) /* VBO no longer valid */
-               GPU_drawobject_free(ob->derivedFinal);
+               /* VBO no longer valid */
+               if (ob->derivedFinal) {
+                       GPU_drawobject_free(ob->derivedFinal);
+               }
+       }
 
        WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
 
@@ -5795,7 +5843,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
        }
 
        MEM_freeN(nodes);
-       sculpt_undo_push_end(C);
+       sculpt_undo_push_end();
 
        /* force rebuild of pbvh for better BB placement */
        sculpt_pbvh_clear(ob);
index 5fb9eee805fd95740b941e6a7e07268df496b8bd..cf1937f14d491cd39b9e80b88bd6177321f619f8 100644 (file)
@@ -60,10 +60,16 @@ bool sculpt_stroke_get_location(struct bContext *C, float out[3], const float mo
 /* Dynamic topology */
 void sculpt_pbvh_clear(Object *ob);
 void sculpt_dyntopo_node_layers_add(struct SculptSession *ss);
-void sculpt_update_after_dynamic_topology_toggle(struct bContext *C);
-void sculpt_dynamic_topology_enable(struct bContext *C);
-void sculpt_dynamic_topology_disable(struct bContext *C,
-                                     struct SculptUndoNode *unode);
+void sculpt_update_after_dynamic_topology_toggle(
+        struct Scene *scene, struct Object *ob);
+void sculpt_dynamic_topology_enable_ex(
+        struct Scene *scene, struct Object *ob);
+void sculpt_dynamic_topology_enable(bContext *C);
+
+void sculpt_dynamic_topology_disable_ex(
+        struct Scene *scene, struct Object *ob,
+        struct SculptUndoNode *unode);
+void sculpt_dynamic_topology_disable(bContext *C, struct SculptUndoNode *unode);
 
 /* Undo */
 
@@ -342,7 +348,7 @@ void sculpt_cache_free(StrokeCache *cache);
 SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type);
 SculptUndoNode *sculpt_undo_get_node(PBVHNode *node);
 void sculpt_undo_push_begin(const char *name);
-void sculpt_undo_push_end(const struct bContext *C);
+void sculpt_undo_push_end(void);
 
 void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]);
 
index d22ddd644f9a84729e936680e3fef271c9cd8f01..794ac14483a813072f3667e7839d8426a130c891 100644 (file)
@@ -958,7 +958,7 @@ void sculpt_undo_push_begin(const char *name)
                                 sculpt_undo_restore, sculpt_undo_free, sculpt_undo_cleanup);
 }
 
-void sculpt_undo_push_end(const bContext *C)
+void sculpt_undo_push_end(void)
 {
        ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
        SculptUndoNode *unode;
@@ -976,5 +976,5 @@ void sculpt_undo_push_end(const bContext *C)
 
        ED_undo_paint_push_end(UNDO_PAINT_MESH);
 
-       WM_file_tag_modified(C);
+       WM_file_tag_modified();
 }
index 95b5c2c1e48131f432e8130993b94e79bf13de62..e224dc6484c74095f6dc7689cac04531af2b1ad5 100644 (file)
@@ -110,7 +110,7 @@ void ED_undo_push(bContext *C, const char *str)
                BKE_undo_write(C, str);
        }
 
-       WM_file_tag_modified(C);
+       WM_file_tag_modified();
 }
 
 /* note: also check undo_history_exec() in bottom if you change notifiers */
index 965eb2b258a2e4b4bae259378c91b38c92529097..b7639889bcda2b31e868aa0ef46d2c41664f03ea 100644 (file)
@@ -116,7 +116,7 @@ void                WM_file_autoexec_init(const char *filepath);
 bool           WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports);
 void           WM_autosave_init(struct wmWindowManager *wm);
 void           WM_recover_last_session(struct bContext *C, struct ReportList *reports);
-void           WM_file_tag_modified(const struct bContext *C);
+void           WM_file_tag_modified(void);
 
 void        WM_lib_reload(struct Library *lib, struct bContext *C, struct ReportList *reports);
 
index 21e6abacfec3f00aecb0d95f623e1a212dc0ff9e..2d72bcf4d58bd212b4a2c398546fd9063ad7d874 100644 (file)
@@ -315,10 +315,8 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
 }
 
 /* in case UserDef was read, we re-initialize all, and do versioning */
-static void wm_init_userdef(bContext *C, const bool read_userdef_from_memory)
+static void wm_init_userdef(Main *bmain, const bool read_userdef_from_memory)
 {
-       Main *bmain = CTX_data_main(C);
-
        /* versioning is here */
        UI_init_userdef();
        
@@ -579,7 +577,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
 
                if (retval == BKE_BLENDFILE_READ_OK_USERPREFS) {
                        /* in case a userdef is read from regular .blend */
-                       wm_init_userdef(C, false);
+                       wm_init_userdef(G.main, false);
                }
                
                if (retval != BKE_BLENDFILE_READ_FAIL) {
@@ -840,7 +838,7 @@ int wm_homefile_read(
        
        if (use_userdef) {
                /* check userdef before open window, keymaps etc */
-               wm_init_userdef(C, read_userdef_from_memory);
+               wm_init_userdef(CTX_data_main(C), read_userdef_from_memory);
        }
        
        /* match the read WM with current WM */
@@ -1351,13 +1349,13 @@ void wm_open_init_use_scripts(wmOperator *op, bool use_prefs)
 
 /** \} */
 
-void WM_file_tag_modified(const bContext *C)
+void WM_file_tag_modified(void)
 {
-       wmWindowManager *wm = CTX_wm_manager(C);
+       wmWindowManager *wm = G.main->wm.first;
        if (wm->file_saved) {
                wm->file_saved = 0;
                /* notifier that data changed, for save-over warning or header */
-               WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL);
+               WM_main_add_notifier(NC_WM | ND_DATACHANGED, NULL);
        }
 }