Merge branch 'master' into blender2.8
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 7 May 2018 12:20:47 +0000 (14:20 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 7 May 2018 12:20:47 +0000 (14:20 +0200)
1  2 
source/blender/editors/sculpt_paint/sculpt.c

index 9817ca4183242b700765d7d9a8119cb70b1e1d80,cc46263164742cfd3c5c6bca4ce1a94f33727b5d..38fbb609283393a5c7274a29dd49bf66eb16a051
@@@ -56,6 -56,7 +56,6 @@@
  #include "BKE_brush.h"
  #include "BKE_ccg.h"
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_global.h"
  #include "BKE_image.h"
  #include "BKE_key.h"
@@@ -72,8 -73,6 +72,8 @@@
  #include "BKE_subsurf.h"
  #include "BKE_colortools.h"
  
 +#include "DEG_depsgraph.h"
 +
  #include "WM_api.h"
  #include "WM_types.h"
  
@@@ -87,6 -86,9 +87,6 @@@
  #include "RNA_access.h"
  #include "RNA_define.h"
  
 -#include "GPU_buffers.h"
 -#include "GPU_extensions.h"
 -
  #include "UI_interface.h"
  #include "UI_resources.h"
  
@@@ -498,7 -500,8 +498,7 @@@ bool sculpt_get_redraw_rect(ARegion *ar
        return 1;
  }
  
 -void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar,
 -                                 RegionView3D *rv3d, Object *ob)
 +void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *ar, Object *ob)
  {
        PBVH *pbvh = ob->sculpt->pbvh;
        /* copy here, original will be used below */
  
        sculpt_extend_redraw_rect_previous(ob, &rect);
  
 -      paint_calc_redraw_planes(planes, ar, rv3d, ob, &rect);
 +      paint_calc_redraw_planes(planes, ar, ob, &rect);
  
        /* we will draw this rect, so now we can set it as the previous partial rect.
         * Note that we don't update with the union of previous/current (rect), only with
@@@ -1126,6 -1129,8 +1126,8 @@@ static float brush_strength
                                case BRUSH_MASK_SMOOTH:
                                        return alpha * pressure * feather;
                        }
+                       BLI_assert(!"Not supposed to happen");
+                       break;
  
                case SCULPT_TOOL_CREASE:
                case SCULPT_TOOL_BLOB:
@@@ -2096,10 -2101,6 +2098,10 @@@ static void do_draw_brush(Sculpt *sd, O
        mul_v3_v3(offset, ss->cache->scale);
        mul_v3_fl(offset, bstrength);
  
 +      /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
 +       * initialize before threads so they can do curve mapping */
 +      curvemapping_initialize(brush->curve);
 +
        /* threaded loop over nodes */
        SculptThreadedTaskData data = {
            .sd = sd, .ob = ob, .brush = brush, .nodes = nodes,
@@@ -4598,11 -4599,10 +4600,11 @@@ static void sculpt_stroke_modifiers_che
        SculptSession *ss = ob->sculpt;
  
        if (ss->kb || ss->modifiers_active) {
 +              Depsgraph *depsgraph = CTX_data_depsgraph(C);
                Scene *scene = CTX_data_scene(C);
                Sculpt *sd = scene->toolsettings->sculpt;
                bool need_pmap = sculpt_any_smooth_mode(brush, ss->cache, 0);
 -              BKE_sculpt_update_mesh_elements(scene, sd, ob, need_pmap, false);
 +              BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, need_pmap, false);
        }
  }
  
@@@ -4687,7 -4687,7 +4689,7 @@@ static float sculpt_raycast_init
        RegionView3D *rv3d = vc->ar->regiondata;
  
        /* TODO: what if the segment is totally clipped? (return == 0) */
 -      ED_view3d_win_to_segment(vc->ar, vc->v3d, mouse, ray_start, ray_end, true);
 +      ED_view3d_win_to_segment(vc->depsgraph, vc->ar, vc->v3d, mouse, ray_start, ray_end, true);
  
        invert_m4_m4(obimat, ob->obmat);
        mul_m4_v3(obimat, ray_start);
@@@ -4805,7 -4805,6 +4807,7 @@@ static void sculpt_brush_init_tex(cons
  
  static bool sculpt_brush_stroke_init(bContext *C, wmOperator *op)
  {
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
        Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
        sculpt_brush_init_tex(scene, sd, ss);
  
        is_smooth = sculpt_any_smooth_mode(brush, NULL, mode);
 -      BKE_sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask);
 +      BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, is_smooth, need_mask);
  
        return 1;
  }
@@@ -4863,9 -4862,11 +4865,9 @@@ static void sculpt_flush_update(bContex
  
        if (mmd)
                multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
 -      if (ob->derivedFinal) /* VBO no longer valid */
 -              GPU_drawobject_free(ob->derivedFinal);
  
        if (ss->kb || ss->modifiers_active) {
 -              DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +              DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                ED_region_tag_redraw(ar);
        }
        else {
                        ED_region_tag_redraw_partial(ar, &r);
                }
        }
 +
 +      /* 2.8x - avoid full mesh update! */
 +      BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_SCULPT_COORDS);
  }
  
  /* Returns whether the mouse/stylus is over the mesh (1)
@@@ -4981,7 -4979,7 +4983,7 @@@ static void sculpt_stroke_update_step(b
         * Could be optimized later, but currently don't think it's so
         * much common scenario.
         *
 -       * Same applies to the DAG_id_tag_update() invoked from
 +       * Same applies to the DEG_id_tag_update() invoked from
         * sculpt_flush_update().
         */
        if (ss->modifiers_active) {
@@@ -5055,7 -5053,7 +5057,7 @@@ static void sculpt_stroke_done(const bC
  
                /* try to avoid calling this, only for e.g. linked duplicates now */
                if (((Mesh *)ob->data)->id.us > 1)
 -                      DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +                      DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
  
                WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
        }
@@@ -5248,18 -5246,16 +5250,18 @@@ void sculpt_dyntopo_node_layers_add(Scu
  
  
  void sculpt_update_after_dynamic_topology_toggle(
 +        Depsgraph *depsgraph,
          Scene *scene, Object *ob)
  {
        Sculpt *sd = scene->toolsettings->sculpt;
  
        /* Create the PBVH */
 -      BKE_sculpt_update_mesh_elements(scene, sd, ob, false, false);
 +      BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, false, false);
        WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
  }
  
  void sculpt_dynamic_topology_enable_ex(
 +        Depsgraph *depsgraph,
          Scene *scene, Object *ob)
  {
        SculptSession *ss = ob->sculpt;
        ss->bm_log = BM_log_create(ss->bm);
  
        /* Refresh */
 -      sculpt_update_after_dynamic_topology_toggle(scene, ob);
 +      sculpt_update_after_dynamic_topology_toggle(depsgraph, 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_ex(
 +        Depsgraph *depsgraph,
          Scene *scene, Object *ob, SculptUndoNode *unode)
  {
        SculptSession *ss = ob->sculpt;
        }
  
        /* Refresh */
 -      sculpt_update_after_dynamic_topology_toggle(scene, ob);
 +      sculpt_update_after_dynamic_topology_toggle(depsgraph, scene, ob);
  }
  
  void sculpt_dynamic_topology_disable(bContext *C, SculptUndoNode *unode)
  {
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
 -      sculpt_dynamic_topology_disable_ex(scene, ob, unode);
 +      sculpt_dynamic_topology_disable_ex(depsgraph, scene, ob, unode);
  }
  
  static void sculpt_dynamic_topology_disable_with_undo(
 -        Scene *scene, Object *ob)
 +        Depsgraph *depsgraph, 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_dynamic_topology_disable_ex(depsgraph, scene, ob, NULL);
                sculpt_undo_push_end();
        }
  }
  
  static void sculpt_dynamic_topology_enable_with_undo(
 +        Depsgraph *depsgraph,
          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_dynamic_topology_enable_ex(depsgraph, 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))
  {
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
        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_dynamic_topology_disable_with_undo(scene, ob);
 +              sculpt_dynamic_topology_disable_with_undo(depsgraph, scene, ob);
        }
        else {
 -              sculpt_dynamic_topology_enable_with_undo(scene, ob);
 +              sculpt_dynamic_topology_enable_with_undo(depsgraph, scene, ob);
        }
  
        WM_cursor_wait(0);
@@@ -5616,14 -5608,13 +5618,14 @@@ static void SCULPT_OT_symmetrize(wmOper
  
  /**** Toggle operator for turning sculpt mode on or off ****/
  
 -static void sculpt_init_session(Scene *scene, Object *ob)
 +static void sculpt_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob)
  {
        /* Create persistent sculpt mode data */
        BKE_sculpt_toolsettings_data_ensure(scene);
  
        ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
 -      BKE_sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, false);
 +      ob->sculpt->mode_type = OB_MODE_SCULPT;
 +      BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, 0, false);
  }
  
  static int ed_object_sculptmode_flush_recalc_flag(Scene *scene, Object *ob, MultiresModifierData *mmd)
  }
  
  void ED_object_sculptmode_enter_ex(
 +        Depsgraph *depsgraph,
          Scene *scene, Object *ob,
          ReportList *reports)
  {
        /* Enter sculptmode */
        ob->mode |= mode_flag;
  
 -
        MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
  
        const int flush_recalc = ed_object_sculptmode_flush_recalc_flag(scene, ob, mmd);
  
 -      if (flush_recalc) {
 -              DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 -      }
 +      if (flush_recalc)
 +              DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
  
        /* Create sculpt mode session data */
        if (ob->sculpt) {
                BKE_sculptsession_free(ob);
        }
  
 -      sculpt_init_session(scene, ob);
 +      sculpt_init_session(depsgraph, scene, ob);
  
        /* Mask layer is required */
        if (mmd) {
                if (message_unsupported == NULL) {
                        /* undo push is needed to prevent memory leak */
                        sculpt_undo_push_begin("Dynamic topology enable");
 -                      sculpt_dynamic_topology_enable_ex(scene, ob);
 +                      sculpt_dynamic_topology_enable_ex(depsgraph, scene, ob);
                        sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
                }
                else {
                }
        }
  
 -      /* VBO no longer valid */
 -      if (ob->derivedFinal) {
 -              GPU_drawobject_free(ob->derivedFinal);
 -      }
 +      // ED_workspace_object_mode_sync_from_object(G.main->wm.first, workspace, ob);
  }
  
  void ED_object_sculptmode_enter(struct bContext *C, ReportList *reports)
  {
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
 -      ED_object_sculptmode_enter_ex(scene, ob, reports);
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
 +      ED_object_sculptmode_enter_ex(depsgraph, scene, ob, reports);
  }
  
  void ED_object_sculptmode_exit_ex(
 +        Depsgraph *depsgraph,
          Scene *scene, Object *ob)
  {
        const int mode_flag = OB_MODE_SCULPT;
        if (mmd) {
                multires_force_update(ob);
        }
 -      
 +
        /* Not needed for now. */
  #if 0
        const int flush_recalc = ed_object_sculptmode_flush_recalc_flag(scene, ob, mmd);
         * a consistent state.
         */
        if (true || /* flush_recalc || */ (ob->sculpt && ob->sculpt->bm)) {
 -              DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +              DEG_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);
 +              sculpt_dynamic_topology_disable_with_undo(depsgraph, 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;
  
 +      // ED_workspace_object_mode_sync_from_object(G.main->wm.first, workspace, ob);
 +
        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)
  {
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
 -      ED_object_sculptmode_exit_ex(scene, ob);
 +      ED_object_sculptmode_exit_ex(depsgraph, scene, ob);
  }
  
  static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
  {
 +      Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
        const int mode_flag = OB_MODE_SCULPT;
        }
  
        if (is_mode_set) {
 -              ED_object_sculptmode_exit_ex(scene, ob);
 +              ED_object_sculptmode_exit_ex(depsgraph, scene, ob);
        }
        else {
 -              ED_object_sculptmode_enter_ex(scene, ob, op->reports);
 +              ED_object_sculptmode_enter_ex(depsgraph, scene, ob, op->reports);
        }
  
        WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);