diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-03-06 12:04:02 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-03-06 12:04:02 +0300 |
commit | 85b68aaf7fae6b3bad1b42bcbba7bef41fd0145f (patch) | |
tree | 015ca83a25f715dbfc21bf9428a19e34eba4f84f /source | |
parent | a5a0dcec902d6bbff0fe0fc1bb7fb21045823166 (diff) | |
parent | 4d86a432da19826ca28f26af30b24edf18e53553 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/include/ED_object.h | 5 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 234 |
2 files changed, 136 insertions, 103 deletions
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 2a3d5d144ac..bf29aba34f8 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -148,6 +148,11 @@ void ED_object_vpaintmode_exit(struct bContext *C); void ED_object_wpaintmode_exit_ex(struct WorkSpace *workspace, struct Object *ob); void ED_object_wpaintmode_exit(struct bContext *C); +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( const struct EvaluationContext *eval_ctx, struct WorkSpace *workspace, struct Scene *scene, struct Object *ob); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index debc719a5d9..5333436f34f 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -5460,13 +5460,11 @@ static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoW return OPERATOR_INTERFACE; } -static enum eDynTopoWarnFlag sculpt_dynamic_topology_check(bContext *C) +static enum eDynTopoWarnFlag sculpt_dynamic_topology_check(Scene *scene, Object *ob) { - Object *ob = CTX_data_active_object(C); Mesh *me = ob->data; SculptSession *ss = ob->sculpt; - Scene *scene = CTX_data_scene(C); enum eDynTopoWarnFlag flag = 0; BLI_assert(ss->bm == NULL); @@ -5511,7 +5509,8 @@ static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op, co SculptSession *ss = ob->sculpt; if (!ss->bm) { - enum eDynTopoWarnFlag flag = sculpt_dynamic_topology_check(C); + Scene *scene = CTX_data_scene(C); + enum eDynTopoWarnFlag flag = sculpt_dynamic_topology_check(scene, ob); if (flag) { /* The mesh has customdata that will be lost, let the user confirm this is OK */ @@ -5638,6 +5637,126 @@ static void sculpt_init_session(const EvaluationContext *eval_ctx, Scene *scene, BKE_sculpt_update_mesh_elements(eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false); } +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( + 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 */ + 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); + + 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(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"); + 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( const EvaluationContext *eval_ctx, WorkSpace *workspace, Scene *scene, Object *ob) @@ -5650,6 +5769,11 @@ void ED_object_sculptmode_exit_ex( 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,15 +5818,11 @@ void ED_object_sculptmode_exit(bContext *C) 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 = (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, workspace, mode_flag, op->reports)) { @@ -5710,106 +5830,14 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) } } - 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(&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(&eval_ctx, workspace, scene, ob, op->reports); } WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); |