Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/sculpt.c
| Show First 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_multires.h" | #include "BKE_multires.h" | ||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_paint.h" | #include "BKE_paint.h" | ||||
| #include "BKE_particle.h" | #include "BKE_particle.h" | ||||
| #include "BKE_pbvh.h" | #include "BKE_pbvh.h" | ||||
| #include "BKE_pointcache.h" | #include "BKE_pointcache.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_scene.h" | |||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "BKE_subsurf.h" | #include "BKE_subsurf.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| ▲ Show 20 Lines • Show All 5,596 Lines • ▼ Show 20 Lines | void sculpt_dynamic_topology_enable_ex(Depsgraph *depsgraph, Scene *scene, Object *ob) | ||||
| /* Refresh */ | /* Refresh */ | ||||
| sculpt_update_after_dynamic_topology_toggle(depsgraph, scene, ob); | sculpt_update_after_dynamic_topology_toggle(depsgraph, scene, ob); | ||||
| } | } | ||||
| /* Free the sculpt BMesh and BMLog | /* Free the sculpt BMesh and BMLog | ||||
| * | * | ||||
| * If 'unode' is given, the BMesh's data is copied out to the unode | * 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 */ | * before the BMesh is deleted so that it can be restored from */ | ||||
| void sculpt_dynamic_topology_disable_ex(Depsgraph *depsgraph, | void sculpt_dynamic_topology_disable_ex( | ||||
| Scene *scene, | Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, SculptUndoNode *unode) | ||||
| Object *ob, | |||||
| SculptUndoNode *unode) | |||||
| { | { | ||||
| SculptSession *ss = ob->sculpt; | SculptSession *ss = ob->sculpt; | ||||
| Mesh *me = ob->data; | Mesh *me = ob->data; | ||||
| sculpt_pbvh_clear(ob); | sculpt_pbvh_clear(ob); | ||||
| if (unode) { | if (unode) { | ||||
| /* Free all existing custom data */ | /* Free all existing custom data */ | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | void sculpt_dynamic_topology_disable_ex( | ||||
| if (ss->bm_log) { | if (ss->bm_log) { | ||||
| BM_log_free(ss->bm_log); | BM_log_free(ss->bm_log); | ||||
| ss->bm_log = NULL; | ss->bm_log = NULL; | ||||
| } | } | ||||
| BKE_particlesystem_reset_all(ob); | BKE_particlesystem_reset_all(ob); | ||||
| BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED); | BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED); | ||||
| DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); | |||||
| BKE_scene_graph_update_tagged(depsgraph, bmain); | |||||
| /* Refresh */ | /* Refresh */ | ||||
| sculpt_update_after_dynamic_topology_toggle(depsgraph, scene, ob); | sculpt_update_after_dynamic_topology_toggle(depsgraph, scene, ob); | ||||
| } | } | ||||
| void sculpt_dynamic_topology_disable(bContext *C, SculptUndoNode *unode) | void sculpt_dynamic_topology_disable(bContext *C, SculptUndoNode *unode) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | |||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | Depsgraph *depsgraph = CTX_data_depsgraph(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Object *ob = CTX_data_active_object(C); | Object *ob = CTX_data_active_object(C); | ||||
| sculpt_dynamic_topology_disable_ex(depsgraph, scene, ob, unode); | sculpt_dynamic_topology_disable_ex(bmain, depsgraph, scene, ob, unode); | ||||
| } | } | ||||
| static void sculpt_dynamic_topology_disable_with_undo(Depsgraph *depsgraph, | static void sculpt_dynamic_topology_disable_with_undo(Main *bmain, | ||||
| Depsgraph *depsgraph, | |||||
| Scene *scene, | Scene *scene, | ||||
| Object *ob) | Object *ob) | ||||
| { | { | ||||
| SculptSession *ss = ob->sculpt; | SculptSession *ss = ob->sculpt; | ||||
| if (ss->bm) { | if (ss->bm) { | ||||
| sculpt_undo_push_begin("Dynamic topology disable"); | sculpt_undo_push_begin("Dynamic topology disable"); | ||||
| sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END); | sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END); | ||||
| sculpt_dynamic_topology_disable_ex(depsgraph, scene, ob, NULL); | sculpt_dynamic_topology_disable_ex(bmain, depsgraph, scene, ob, NULL); | ||||
| sculpt_undo_push_end(); | sculpt_undo_push_end(); | ||||
| } | } | ||||
| } | } | ||||
| static void sculpt_dynamic_topology_enable_with_undo(Depsgraph *depsgraph, | static void sculpt_dynamic_topology_enable_with_undo(Depsgraph *depsgraph, | ||||
| Scene *scene, | Scene *scene, | ||||
| Object *ob) | Object *ob) | ||||
| { | { | ||||
| SculptSession *ss = ob->sculpt; | SculptSession *ss = ob->sculpt; | ||||
| if (ss->bm == NULL) { | if (ss->bm == NULL) { | ||||
| sculpt_undo_push_begin("Dynamic topology enable"); | sculpt_undo_push_begin("Dynamic topology enable"); | ||||
| sculpt_dynamic_topology_enable_ex(depsgraph, scene, ob); | sculpt_dynamic_topology_enable_ex(depsgraph, scene, ob); | ||||
| sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN); | sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN); | ||||
| sculpt_undo_push_end(); | sculpt_undo_push_end(); | ||||
| } | } | ||||
| } | } | ||||
| static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op)) | static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | |||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | Depsgraph *depsgraph = CTX_data_depsgraph(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Object *ob = CTX_data_active_object(C); | Object *ob = CTX_data_active_object(C); | ||||
| SculptSession *ss = ob->sculpt; | SculptSession *ss = ob->sculpt; | ||||
| WM_cursor_wait(1); | WM_cursor_wait(1); | ||||
| if (ss->bm) { | if (ss->bm) { | ||||
| sculpt_dynamic_topology_disable_with_undo(depsgraph, scene, ob); | sculpt_dynamic_topology_disable_with_undo(bmain, depsgraph, scene, ob); | ||||
| } | } | ||||
| else { | else { | ||||
| sculpt_dynamic_topology_enable_with_undo(depsgraph, scene, ob); | sculpt_dynamic_topology_enable_with_undo(depsgraph, scene, ob); | ||||
| } | } | ||||
| WM_cursor_wait(0); | WM_cursor_wait(0); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| ▲ Show 20 Lines • Show All 347 Lines • ▼ Show 20 Lines | void ED_object_sculptmode_enter(struct bContext *C, ReportList *reports) | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| Object *ob = OBACT(view_layer); | Object *ob = OBACT(view_layer); | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | Depsgraph *depsgraph = CTX_data_depsgraph(C); | ||||
| ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, false, reports); | ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, false, reports); | ||||
| } | } | ||||
| void ED_object_sculptmode_exit_ex(Depsgraph *depsgraph, Scene *scene, Object *ob) | void ED_object_sculptmode_exit_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob) | ||||
| { | { | ||||
| const int mode_flag = OB_MODE_SCULPT; | const int mode_flag = OB_MODE_SCULPT; | ||||
| Mesh *me = BKE_mesh_from_object(ob); | Mesh *me = BKE_mesh_from_object(ob); | ||||
| MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); | MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); | ||||
| if (mmd) { | if (mmd) { | ||||
| multires_force_update(ob); | multires_force_update(ob); | ||||
| } | } | ||||
| Show All 9 Lines | #endif | ||||
| if (true || /* flush_recalc || */ (ob->sculpt && ob->sculpt->bm)) { | if (true || /* flush_recalc || */ (ob->sculpt && ob->sculpt->bm)) { | ||||
| DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); | DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); | ||||
| } | } | ||||
| if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) { | if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) { | ||||
| /* Dynamic topology must be disabled before exiting sculpt | /* Dynamic topology must be disabled before exiting sculpt | ||||
| * mode to ensure the undo stack stays in a consistent | * mode to ensure the undo stack stays in a consistent | ||||
| * state */ | * state */ | ||||
| sculpt_dynamic_topology_disable_with_undo(depsgraph, scene, ob); | sculpt_dynamic_topology_disable_with_undo(bmain, depsgraph, scene, ob); | ||||
| /* store so we know to re-enable when entering sculpt mode */ | /* store so we know to re-enable when entering sculpt mode */ | ||||
| me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY; | me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY; | ||||
| } | } | ||||
| /* Leave sculptmode */ | /* Leave sculptmode */ | ||||
| ob->mode &= ~mode_flag; | ob->mode &= ~mode_flag; | ||||
| BKE_sculptsession_free(ob); | BKE_sculptsession_free(ob); | ||||
| paint_cursor_delete_textures(); | paint_cursor_delete_textures(); | ||||
| /* Never leave derived meshes behind. */ | /* Never leave derived meshes behind. */ | ||||
| BKE_object_free_derived_caches(ob); | BKE_object_free_derived_caches(ob); | ||||
| /* Flush object mode. */ | /* Flush object mode. */ | ||||
| DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE); | DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE); | ||||
| } | } | ||||
| void ED_object_sculptmode_exit(bContext *C) | void ED_object_sculptmode_exit(bContext *C) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | |||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | Depsgraph *depsgraph = CTX_data_depsgraph(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| Object *ob = OBACT(view_layer); | Object *ob = OBACT(view_layer); | ||||
| ED_object_sculptmode_exit_ex(depsgraph, scene, ob); | ED_object_sculptmode_exit_ex(bmain, depsgraph, scene, ob); | ||||
| } | } | ||||
| static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) | static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| struct wmMsgBus *mbus = CTX_wm_message_bus(C); | struct wmMsgBus *mbus = CTX_wm_message_bus(C); | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C); | Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| ToolSettings *ts = scene->toolsettings; | ToolSettings *ts = scene->toolsettings; | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| Object *ob = OBACT(view_layer); | Object *ob = OBACT(view_layer); | ||||
| const int mode_flag = OB_MODE_SCULPT; | const int mode_flag = OB_MODE_SCULPT; | ||||
| const bool is_mode_set = (ob->mode & mode_flag) != 0; | const bool is_mode_set = (ob->mode & mode_flag) != 0; | ||||
| if (!is_mode_set) { | if (!is_mode_set) { | ||||
| if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { | if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| } | } | ||||
| if (is_mode_set) { | if (is_mode_set) { | ||||
| ED_object_sculptmode_exit_ex(depsgraph, scene, ob); | ED_object_sculptmode_exit_ex(bmain, depsgraph, scene, ob); | ||||
| } | } | ||||
| else { | else { | ||||
| ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, false, op->reports); | ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, false, op->reports); | ||||
| BKE_paint_toolslots_brush_validate(bmain, &ts->sculpt->paint); | BKE_paint_toolslots_brush_validate(bmain, &ts->sculpt->paint); | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); | WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); | ||||
| ▲ Show 20 Lines • Show All 284 Lines • Show Last 20 Lines | |||||