Object Mode: exit sculpt on selection

This commit is contained in:
2018-02-16 23:37:47 +11:00
parent ce4d52c4f3
commit 18bb0bc569
10 changed files with 148 additions and 75 deletions

View File

@@ -150,6 +150,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_exit_ex(
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]);
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]);

View File

@@ -146,7 +146,6 @@ void ED_object_base_activate(bContext *C, Base *base)
* Not correct because it's possible other work-spaces use these.
* although that's a corner case. */
if (workspace->object_mode & OB_MODE_EDIT) {
Object *obact = OBACT(view_layer);
FOREACH_OBJECT(view_layer, ob) {
if (ob != base->object) {
if (BKE_object_is_in_editmode(ob)) {
@@ -157,7 +156,8 @@ void ED_object_base_activate(bContext *C, Base *base)
FOREACH_OBJECT_END;
}
else if (workspace->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_SCULPT)) {
Object *obact = OBACT(view_layer);
EvaluationContext eval_ctx;
CTX_data_eval_ctx(C, &eval_ctx);
FOREACH_OBJECT(view_layer, ob) {
if (ob != base->object) {
if (ob->sculpt) {
@@ -174,7 +174,7 @@ void ED_object_base_activate(bContext *C, Base *base)
}
case OB_MODE_SCULPT:
{
/* TODO */
ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob);
break;
}
}

View File

@@ -418,7 +418,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) */

View File

@@ -171,7 +171,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);
@@ -327,7 +327,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);
@@ -514,7 +514,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);

View File

@@ -5047,7 +5047,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);
@@ -5255,24 +5255,21 @@ void sculpt_dyntopo_node_layers_add(SculptSession *ss)
}
void sculpt_update_after_dynamic_topology_toggle(bContext *C)
void sculpt_update_after_dynamic_topology_toggle(
const EvaluationContext *eval_ctx,
Scene *scene, Object *ob)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
EvaluationContext eval_ctx;
Sculpt *sd = scene->toolsettings->sculpt;
CTX_data_eval_ctx(C, &eval_ctx);
/* Create the PBVH */
BKE_sculpt_update_mesh_elements(&eval_ctx, scene, sd, ob, false, false);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
BKE_sculpt_update_mesh_elements(eval_ctx, scene, sd, ob, false, false);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
void sculpt_dynamic_topology_enable(bContext *C)
void sculpt_dynamic_topology_enable_ex(
const EvaluationContext *eval_ctx,
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);
@@ -5308,17 +5305,17 @@ 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(eval_ctx, 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(
const EvaluationContext *eval_ctx,
Scene *scene, Object *ob, SculptUndoNode *unode)
{
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
@@ -5367,28 +5364,59 @@ void sculpt_dynamic_topology_disable(bContext *C,
}
/* Refresh */
sculpt_update_after_dynamic_topology_toggle(C);
sculpt_update_after_dynamic_topology_toggle(eval_ctx, scene, ob);
}
void sculpt_dynamic_topology_disable(bContext *C, SculptUndoNode *unode)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
EvaluationContext eval_ctx;
CTX_data_eval_ctx(C, &eval_ctx);
sculpt_dynamic_topology_disable_ex(&eval_ctx, scene, ob, unode);
}
static void sculpt_dynamic_topology_disable_with_undo(
const EvaluationContext *eval_ctx, 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(eval_ctx, scene, ob, NULL);
sculpt_undo_push_end();
}
}
static void sculpt_dynamic_topology_enable_with_undo(
const EvaluationContext *eval_ctx,
Scene *scene, Object *ob)
{
SculptSession *ss = ob->sculpt;
if (ss->bm == NULL) {
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);
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;
EvaluationContext eval_ctx;
CTX_data_eval_ctx(C, &eval_ctx);
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(&eval_ctx, 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(&eval_ctx, scene, ob);
}
sculpt_undo_push_end(C);
WM_cursor_wait(0);
@@ -5576,7 +5604,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);
@@ -5605,9 +5633,61 @@ static void sculpt_init_session(const EvaluationContext *eval_ctx, Scene *scene,
BKE_sculpt_toolsettings_data_ensure(scene);
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
ob->sculpt->mode_type = OB_MODE_SCULPT;
BKE_sculpt_update_mesh_elements(eval_ctx, scene, scene->toolsettings->sculpt, ob, 0, false);
}
void ED_object_sculptmode_exit_ex(
const EvaluationContext *eval_ctx,
WorkSpace *workspace, 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)) {
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(eval_ctx, scene, ob);
/* store so we know to re-enable when entering sculpt mode */
me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
}
/* Leave sculptmode */
workspace->object_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)
{
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_exit_ex(&eval_ctx, workspace, scene, ob);
}
static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
{
@@ -5634,32 +5714,9 @@ 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)) {
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_toggle_exec(C, NULL);
/* store so we know to re-enable when entering sculpt mode */
me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
}
/* Leave sculptmode */
workspace->object_mode &= ~mode_flag;
BKE_sculptsession_free(ob);
paint_cursor_delete_textures();
EvaluationContext eval_ctx;
CTX_data_eval_ctx(C, &eval_ctx);
ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob);
}
else {
/* Enter sculptmode */
@@ -5732,7 +5789,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(&eval_ctx, scene, ob);
sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
}
else {
@@ -5742,10 +5799,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);
@@ -5815,7 +5874,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);

View File

@@ -60,10 +60,19 @@ 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(
const struct EvaluationContext *eval_ctx,
struct Scene *scene, struct Object *ob);
void sculpt_dynamic_topology_enable_ex(
const struct EvaluationContext *eval_ctx,
struct Scene *scene, struct Object *ob);
void sculpt_dynamic_topology_enable(bContext *C);
void sculpt_dynamic_topology_disable_ex(
const struct EvaluationContext *eval_ctx,
struct Scene *scene, struct Object *ob,
struct SculptUndoNode *unode);
void sculpt_dynamic_topology_disable(bContext *C, struct SculptUndoNode *unode);
/* Undo */
@@ -342,7 +351,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]);

View File

@@ -964,7 +964,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;
@@ -982,5 +982,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();
}

View File

@@ -117,7 +117,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 */

View File

@@ -141,7 +141,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);

View File

@@ -1363,13 +1363,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);
}
}