Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/sculpt_undo.c
| Show First 20 Lines • Show All 1,328 Lines • ▼ Show 20 Lines | else { | ||||
| unode->shapeName[0] = '\0'; | unode->shapeName[0] = '\0'; | ||||
| } | } | ||||
| BLI_thread_unlock(LOCK_CUSTOM1); | BLI_thread_unlock(LOCK_CUSTOM1); | ||||
| return unode; | return unode; | ||||
| } | } | ||||
| void SCULPT_undo_push_begin(const char *name) | void SCULPT_undo_push_begin(const struct bContext *C, const char *name) | ||||
| { | { | ||||
| UndoStack *ustack = ED_undo_stack_get(); | UndoStack *ustack = ED_undo_stack_get(); | ||||
| /* Special case, we never read from this. */ | /* Special case, we never read from this. */ | ||||
| bContext *C = NULL; | C = NULL; | ||||
| BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT); | BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT); | ||||
| } | } | ||||
| void SCULPT_undo_push_end(void) | void SCULPT_undo_push_end(const bContext *C) | ||||
| { | { | ||||
| SCULPT_undo_push_end_ex(false); | SCULPT_undo_push_end_ex(C, false); | ||||
| } | } | ||||
| void SCULPT_undo_push_end_ex(const bool use_nested_undo) | void SCULPT_undo_push_end_ex(const bContext *C, const bool use_nested_undo) | ||||
| { | { | ||||
| UndoSculpt *usculpt = sculpt_undo_get_nodes(); | UndoSculpt *usculpt = sculpt_undo_get_nodes(); | ||||
| SculptUndoNode *unode; | SculptUndoNode *unode; | ||||
| /* We don't need normals in the undo stack. */ | /* We don't need normals in the undo stack. */ | ||||
| for (unode = usculpt->nodes.first; unode; unode = unode->next) { | for (unode = usculpt->nodes.first; unode; unode = unode->next) { | ||||
| if (unode->no) { | if (unode->no) { | ||||
| MEM_freeN(unode->no); | MEM_freeN(unode->no); | ||||
| unode->no = NULL; | unode->no = NULL; | ||||
| } | } | ||||
| } | } | ||||
| /* We could remove this and enforce all callers run in an operator using 'OPTYPE_UNDO'. */ | /* We could remove this and enforce all callers run in an operator using 'OPTYPE_UNDO'. */ | ||||
| wmWindowManager *wm = G_MAIN->wm.first; | wmWindowManager *wm = C != NULL ? CTX_wm_manager(C) : G_MAIN->wm.first; | ||||
| if (wm->op_undo_depth == 0 || use_nested_undo) { | if (wm->op_undo_depth == 0 || use_nested_undo) { | ||||
| UndoStack *ustack = ED_undo_stack_get(); | UndoStack *ustack = ED_undo_stack_get(); | ||||
| BKE_undosys_step_push(ustack, NULL, NULL); | BKE_undosys_step_push(ustack, NULL, NULL); | ||||
| if (wm->op_undo_depth == 0) { | if (wm->op_undo_depth == 0) { | ||||
| BKE_undosys_stack_limit_steps_and_memory_defaults(ustack); | BKE_undosys_stack_limit_steps_and_memory_defaults(ustack); | ||||
| } | } | ||||
| WM_file_tag_modified(); | WM_file_tag_modified(); | ||||
| } | } | ||||
| } | } | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Implements ED Undo System | /** \name Implements ED Undo System | ||||
| * \{ */ | * \{ */ | ||||
| typedef struct SculptUndoStep { | typedef struct SculptUndoStep { | ||||
| UndoStep step; | UndoStep step; | ||||
| /* Note: will split out into list for multi-object-sculpt-mode. */ | /* Note: will split out into list for multi-object-sculpt-mode. */ | ||||
| UndoSculpt data; | UndoSculpt data; | ||||
| } SculptUndoStep; | } SculptUndoStep; | ||||
| static void sculpt_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p) | static void sculpt_undosys_step_encode_init(const struct bContext *UNUSED(C), UndoStep *us_p) | ||||
| { | { | ||||
| SculptUndoStep *us = (SculptUndoStep *)us_p; | SculptUndoStep *us = (SculptUndoStep *)us_p; | ||||
| /* Dummy, memory is cleared anyway. */ | /* Dummy, memory is cleared anyway. */ | ||||
| BLI_listbase_clear(&us->data.nodes); | BLI_listbase_clear(&us->data.nodes); | ||||
| } | } | ||||
| static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C), | static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C), | ||||
| struct Main *bmain, | struct Main *bmain, | ||||
| ▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | while (us_iter && (us_iter->step.is_applied == false)) { | ||||
| if (us_iter == us) { | if (us_iter == us) { | ||||
| break; | break; | ||||
| } | } | ||||
| us_iter = (SculptUndoStep *)us_iter->step.next; | us_iter = (SculptUndoStep *)us_iter->step.next; | ||||
| } | } | ||||
| } | } | ||||
| static void sculpt_undosys_step_decode( | static void sculpt_undosys_step_decode( | ||||
| struct bContext *C, struct Main *bmain, UndoStep *us_p, int dir, bool UNUSED(is_final)) | bContext *C, Main *bmain, UndoStep *us_p, int dir, bool UNUSED(is_final)) | ||||
| { | { | ||||
| Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | ||||
| /* Ensure sculpt mode. */ | /* Ensure sculpt mode. */ | ||||
| { | { | ||||
| 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); | ||||
| if (ob && (ob->type == OB_MESH)) { | if (ob && (ob->type == OB_MESH)) { | ||||
| if (ob->mode & OB_MODE_SCULPT) { | if (ob->mode & OB_MODE_SCULPT) { | ||||
| /* Pass. */ | /* Pass. */ | ||||
| } | } | ||||
| else { | else { | ||||
| ED_object_mode_generic_exit(bmain, depsgraph, scene, ob); | ED_object_mode_generic_exit(bmain, depsgraph, scene, ob); | ||||
| /* Sculpt needs evaluated state. | /* Sculpt needs evaluated state. | ||||
| * Note: needs to be done here, as #ED_object_mode_generic_exit will usually invalidate | * Note: needs to be done here, as #ED_object_mode_generic_exit will usually invalidate | ||||
| * (some) evaluated data. */ | * (some) evaluated data. */ | ||||
| BKE_scene_graph_evaluated_ensure(depsgraph, bmain); | BKE_scene_graph_evaluated_ensure(depsgraph, bmain); | ||||
| Mesh *me = ob->data; | Mesh *me = ob->data; | ||||
| /* Don't add sculpt topology undo steps when reading back undo state. | /* Don't add sculpt topology undo steps when reading back undo state. | ||||
| * The undo steps must enter/exit for us. */ | * The undo steps must enter/exit for us. */ | ||||
| me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY; | me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY; | ||||
| ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, true, NULL); | ED_object_sculptmode_enter_ex(C, bmain, depsgraph, scene, ob, true, NULL); | ||||
| } | } | ||||
| if (ob->sculpt) { | if (ob->sculpt) { | ||||
| ob->sculpt->needs_flush_to_id = 1; | ob->sculpt->needs_flush_to_id = 1; | ||||
| } | } | ||||
| bmain->is_memfile_undo_flush_needed = true; | bmain->is_memfile_undo_flush_needed = true; | ||||
| } | } | ||||
| else { | else { | ||||
| Show All 12 Lines | |||||
| } | } | ||||
| static void sculpt_undosys_step_free(UndoStep *us_p) | static void sculpt_undosys_step_free(UndoStep *us_p) | ||||
| { | { | ||||
| SculptUndoStep *us = (SculptUndoStep *)us_p; | SculptUndoStep *us = (SculptUndoStep *)us_p; | ||||
| sculpt_undo_free_list(&us->data.nodes); | sculpt_undo_free_list(&us->data.nodes); | ||||
| } | } | ||||
| void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name) | void ED_sculpt_undo_geometry_begin(bContext *C, struct Object *ob, const char *name) | ||||
| { | { | ||||
| SCULPT_undo_push_begin(name); | SCULPT_undo_push_begin(C, name); | ||||
| SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY); | SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY); | ||||
| } | } | ||||
| void ED_sculpt_undo_geometry_end(struct Object *ob) | void ED_sculpt_undo_geometry_end(struct bContext *C, struct Object *ob) | ||||
| { | { | ||||
| SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY); | SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY); | ||||
| SCULPT_undo_push_end(); | SCULPT_undo_push_end(C); | ||||
| } | } | ||||
| /* Export for ED_undo_sys. */ | /* Export for ED_undo_sys. */ | ||||
| void ED_sculpt_undosys_type(UndoType *ut) | void ED_sculpt_undosys_type(UndoType *ut) | ||||
| { | { | ||||
| ut->name = "Sculpt"; | ut->name = "Sculpt"; | ||||
| ut->step_encode_init = sculpt_undosys_step_encode_init; | ut->step_encode_init = sculpt_undosys_step_encode_init; | ||||
| ut->step_encode = sculpt_undosys_step_encode; | ut->step_encode = sculpt_undosys_step_encode; | ||||
| ▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | |||||
| void ED_sculpt_undo_push_multires_mesh_begin(bContext *C, const char *str) | void ED_sculpt_undo_push_multires_mesh_begin(bContext *C, const char *str) | ||||
| { | { | ||||
| if (!sculpt_undo_use_multires_mesh(C)) { | if (!sculpt_undo_use_multires_mesh(C)) { | ||||
| return; | return; | ||||
| } | } | ||||
| Object *object = CTX_data_active_object(C); | Object *object = CTX_data_active_object(C); | ||||
| SCULPT_undo_push_begin(str); | SCULPT_undo_push_begin(C, str); | ||||
| SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY); | SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY); | ||||
| geometry_unode->geometry_clear_pbvh = false; | geometry_unode->geometry_clear_pbvh = false; | ||||
| sculpt_undo_push_all_grids(object); | sculpt_undo_push_all_grids(object); | ||||
| } | } | ||||
| void ED_sculpt_undo_push_multires_mesh_end(bContext *C, const char *str) | void ED_sculpt_undo_push_multires_mesh_end(bContext *C, const char *str) | ||||
| { | { | ||||
| if (!sculpt_undo_use_multires_mesh(C)) { | if (!sculpt_undo_use_multires_mesh(C)) { | ||||
| ED_undo_push(C, str); | ED_undo_push(C, str); | ||||
| return; | return; | ||||
| } | } | ||||
| Object *object = CTX_data_active_object(C); | Object *object = CTX_data_active_object(C); | ||||
| SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY); | SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY); | ||||
| geometry_unode->geometry_clear_pbvh = false; | geometry_unode->geometry_clear_pbvh = false; | ||||
| SCULPT_undo_push_end(); | SCULPT_undo_push_end(C); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||