Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Tue, 6 Mar 2018 09:04:02 +0000 (20:04 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 6 Mar 2018 09:04:02 +0000 (20:04 +1100)
1  2 
source/blender/editors/include/ED_object.h
source/blender/editors/sculpt_paint/sculpt.c

index 2a3d5d144acab7785a784cd9d0e5bf5a7f2bddef,dcc6d064f927e05be267514eff835a4c72e58d78..bf29aba34f8a0c0f2ef62e3a571613f4b059b121
@@@ -135,22 -126,25 +135,27 @@@ bool ED_object_editmode_calc_active_cen
  
  
  void ED_object_vpaintmode_enter_ex(
 -        struct wmWindowManager *wm,
 -        struct Scene *scene, struct Object *ob);
 +        const struct EvaluationContext *eval_ctx, struct wmWindowManager *wm,
 +        struct WorkSpace *workspace, 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);
 +        const struct EvaluationContext *eval_ctx, struct wmWindowManager *wm,
 +        struct WorkSpace *workspace, 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_ex(struct WorkSpace *workspace, 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_ex(struct WorkSpace *workspace, struct Object *ob);
  void ED_object_wpaintmode_exit(struct bContext *C);
  
 -        struct Scene *scene, struct Object *ob,
+ void ED_object_sculptmode_enter_ex(
++        const struct EvaluationContext *eval_ctx,
++        struct WorkSpace *workspace, struct Scene *scene, struct Object *ob,
+         struct ReportList *reports);
+ void ED_object_sculptmode_enter(struct bContext *C, struct ReportList *reports);
  void ED_object_sculptmode_exit_ex(
 -        struct Scene *scene, struct Object *ob);
 +        const struct EvaluationContext *eval_ctx,
 +        struct WorkSpace *workspace, 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]);
index debc719a5d92f1d27c57d2eb200a44ea76aea0d8,156ab649849610ad199879891f9e171968306aca..5333436f34fa34df42f8e9eda4aae6b323d6140e
@@@ -5634,13 -5612,127 +5633,133 @@@ static void sculpt_init_session(const E
        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(eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false);
  }
  
 -        Scene *scene, Object *ob,
+ static int ed_object_sculptmode_flush_recalc_flag(Scene *scene, Object *ob, MultiresModifierData *mmd)
+ {
+       int flush_recalc = 0;
+       /* multires in sculpt mode could have different from object mode subdivision level */
+       flush_recalc |= mmd && mmd->sculptlvl != mmd->lvl;
+       /* if object has got active modifiers, it's dm could be different in sculpt mode  */
+       flush_recalc |= sculpt_has_active_modifiers(scene, ob);
+       return flush_recalc;
+ }
+ void ED_object_sculptmode_enter_ex(
 -      ob->mode |= mode_flag;
 -
++        const EvaluationContext *eval_ctx,
++        WorkSpace *workspace, Scene *scene, Object *ob,
+         ReportList *reports)
+ {
+       const int mode_flag = OB_MODE_SCULPT;
+       Mesh *me = BKE_mesh_from_object(ob);
+       /* Enter sculptmode */
 -      if (flush_recalc) {
 -              DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 -      }
++      workspace->object_mode |= mode_flag;
+       MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
+       const int flush_recalc = ed_object_sculptmode_flush_recalc_flag(scene, ob, mmd);
 -      sculpt_init_session(scene, ob);
++      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_dynamic_topology_enable_ex(scene, ob);
++      sculpt_init_session(eval_ctx, scene, ob);
+       /* Mask layer is required */
+       if (mmd) {
+               /* XXX, we could attempt to support adding mask data mid-sculpt mode (with multi-res)
+                * but this ends up being quite tricky (and slow) */
+               BKE_sculpt_mask_layers_ensure(ob, mmd);
+       }
+       if (!(fabsf(ob->size[0] - ob->size[1]) < 1e-4f && fabsf(ob->size[1] - ob->size[2]) < 1e-4f)) {
+               BKE_report(reports, RPT_WARNING,
+                          "Object has non-uniform scale, sculpting may be unpredictable");
+       }
+       else if (is_negative_m4(ob->obmat)) {
+               BKE_report(reports, RPT_WARNING,
+                          "Object has negative scale, sculpting may be unpredictable");
+       }
+       Paint *paint = BKE_paint_get_active_from_paintmode(scene, ePaintSculpt);
+       BKE_paint_init(scene, ePaintSculpt, PAINT_CURSOR_SCULPT);
+       paint_cursor_start_explicit(paint, G.main->wm.first, sculpt_poll_view3d);
+       /* Check dynamic-topology flag; re-enter dynamic-topology mode when changing modes,
+        * As long as no data was added that is not supported. */
+       if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
+               const char *message_unsupported = NULL;
+               if (me->totloop != me->totpoly * 3) {
+                       message_unsupported = TIP_("non-triangle face");
+               }
+               else if (mmd != NULL) {
+                       message_unsupported = TIP_("multi-res modifier");
+               }
+               else {
+                       enum eDynTopoWarnFlag flag = sculpt_dynamic_topology_check(scene, ob);
+                       if (flag == 0) {
+                               /* pass */
+                       }
+                       else if (flag & DYNTOPO_WARN_VDATA) {
+                               message_unsupported = TIP_("vertex data");
+                       }
+                       else if (flag & DYNTOPO_WARN_EDATA) {
+                               message_unsupported = TIP_("edge data");
+                       }
+                       else if (flag & DYNTOPO_WARN_LDATA) {
+                               message_unsupported = TIP_("face data");
+                       }
+                       else if (flag & DYNTOPO_WARN_MODIFIER) {
+                               message_unsupported = TIP_("constructive modifier");
+                       }
+                       else {
+                               BLI_assert(0);
+                       }
+               }
+               if (message_unsupported == NULL) {
+                       /* undo push is needed to prevent memory leak */
+                       sculpt_undo_push_begin("Dynamic topology enable");
 -      ED_object_sculptmode_enter_ex(scene, ob, reports);
++                      sculpt_dynamic_topology_enable_ex(eval_ctx, scene, ob);
+                       sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
+               }
+               else {
+                       BKE_reportf(reports, RPT_WARNING,
+                                   "Dynamic Topology found: %s, disabled",
+                                   message_unsupported);
+                       me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
+               }
+       }
++      ED_workspace_object_mode_sync_from_object(G.main->wm.first, workspace, ob);
++
+       /* VBO no longer valid */
+       if (ob->derivedFinal) {
+               GPU_drawobject_free(ob->derivedFinal);
+       }
+ }
+ void ED_object_sculptmode_enter(struct bContext *C, ReportList *reports)
+ {
++      WorkSpace *workspace = CTX_wm_workspace(C);
+       Scene *scene = CTX_data_scene(C);
+       Object *ob = CTX_data_active_object(C);
++      EvaluationContext eval_ctx;
++      CTX_data_eval_ctx(C, &eval_ctx);
++      ED_object_sculptmode_enter_ex(&eval_ctx, workspace, scene, ob, reports);
+ }
  void ED_object_sculptmode_exit_ex(
 -        Scene *scene, Object *ob)
 +        const EvaluationContext *eval_ctx,
 +        WorkSpace *workspace, Scene *scene, Object *ob)
  {
        const int mode_flag = OB_MODE_SCULPT;
        Mesh *me = BKE_mesh_from_object(ob);
        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);
+ #endif
        /* Always for now, so leaving sculpt mode always ensures scene is in
         * a consistent state.
         */
@@@ -5694,122 -5786,25 +5818,26 @@@ void ED_object_sculptmode_exit(bContex
  
  static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
  {
-       wmWindowManager *wm = CTX_wm_manager(C);
 +      WorkSpace *workspace = CTX_wm_workspace(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
        const int mode_flag = OB_MODE_SCULPT;
 -      const bool is_mode_set = (ob->mode & mode_flag) != 0;
 -      Mesh *me;
 +      const bool is_mode_set = (workspace->object_mode & mode_flag) != 0;
-       Mesh *me;
-       MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
-       int flush_recalc = 0;
  
        if (!is_mode_set) {
 -              if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
 +              if (!ED_object_mode_compat_set(C, workspace, mode_flag, op->reports)) {
                        return OPERATOR_CANCELLED;
                }
        }
  
--      me = BKE_mesh_from_object(ob);
-       /* multires in sculpt mode could have different from object mode subdivision level */
-       flush_recalc |= mmd && mmd->sculptlvl != mmd->lvl;
-       /* if object has got active modifiers, it's dm could be different in sculpt mode  */
-       flush_recalc |= sculpt_has_active_modifiers(scene, ob);
++      EvaluationContext eval_ctx;
++      CTX_data_eval_ctx(C, &eval_ctx);
  
        if (is_mode_set) {
-               EvaluationContext eval_ctx;
-               CTX_data_eval_ctx(C, &eval_ctx);
 -              ED_object_sculptmode_exit_ex(scene, ob);
 +              ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob);
        }
        else {
-               /* Enter sculptmode */
-               workspace->object_mode |= mode_flag;
-               if (flush_recalc)
-                       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
-               /* Create sculpt mode session data */
-               if (ob->sculpt) {
-                       BKE_sculptsession_free(ob);
-               }
-               EvaluationContext eval_ctx;
-               CTX_data_eval_ctx(C, &eval_ctx);
-               sculpt_init_session(&eval_ctx, scene, ob);
-               /* Mask layer is required */
-               if (mmd) {
-                       /* XXX, we could attempt to support adding mask data mid-sculpt mode (with multi-res)
-                        * but this ends up being quite tricky (and slow) */
-                       BKE_sculpt_mask_layers_ensure(ob, mmd);
-               }
-               if (!(fabsf(ob->size[0] - ob->size[1]) < 1e-4f && fabsf(ob->size[1] - ob->size[2]) < 1e-4f)) {
-                       BKE_report(op->reports, RPT_WARNING,
-                                  "Object has non-uniform scale, sculpting may be unpredictable");
-               }
-               else if (is_negative_m4(ob->obmat)) {
-                       BKE_report(op->reports, RPT_WARNING,
-                                  "Object has negative scale, sculpting may be unpredictable");
-               }
-               BKE_paint_init(scene, ePaintSculpt, PAINT_CURSOR_SCULPT);
-               paint_cursor_start(C, sculpt_poll_view3d);
-               /* Check dynamic-topology flag; re-enter dynamic-topology mode when changing modes,
-                * As long as no data was added that is not supported. */
-               if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
-                       const char *message_unsupported = NULL;
-                       if (me->totloop != me->totpoly * 3) {
-                               message_unsupported = TIP_("non-triangle face");
-                       }
-                       else if (mmd != NULL) {
-                               message_unsupported = TIP_("multi-res modifier");
-                       }
-                       else {
-                               enum eDynTopoWarnFlag flag = sculpt_dynamic_topology_check(C);
-                               if (flag == 0) {
-                                       /* pass */
-                               }
-                               else if (flag & DYNTOPO_WARN_VDATA) {
-                                       message_unsupported = TIP_("vertex data");
-                               }
-                               else if (flag & DYNTOPO_WARN_EDATA) {
-                                       message_unsupported = TIP_("edge data");
-                               }
-                               else if (flag & DYNTOPO_WARN_LDATA) {
-                                       message_unsupported = TIP_("face data");
-                               }
-                               else if (flag & DYNTOPO_WARN_MODIFIER) {
-                                       message_unsupported = TIP_("constructive modifier");
-                               }
-                               else {
-                                       BLI_assert(0);
-                               }
-                       }
-                       if (message_unsupported == NULL) {
-                               /* undo push is needed to prevent memory leak */
-                               sculpt_undo_push_begin("Dynamic topology enable");
-                               sculpt_dynamic_topology_enable_ex(&eval_ctx, scene, ob);
-                               sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
-                       }
-                       else {
-                               BKE_reportf(op->reports, RPT_WARNING,
-                                           "Dynamic Topology found: %s, disabled",
-                                           message_unsupported);
-                               me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
-                       }
-               }
-               ED_workspace_object_mode_sync_from_object(wm, workspace, ob);
-               /* VBO no longer valid */
-               if (ob->derivedFinal) {
-                       GPU_drawobject_free(ob->derivedFinal);
-               }
 -              ED_object_sculptmode_enter_ex(scene, ob, op->reports);
++              ED_object_sculptmode_enter_ex(&eval_ctx, workspace, scene, ob, op->reports);
        }
  
        WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);