diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_undo.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_undo.c | 81 |
1 files changed, 75 insertions, 6 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 044d5b3c0b0..d1896f47c52 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -79,8 +79,7 @@ static void update_cb(PBVHNode *node, void *rebuild) BKE_pbvh_node_mark_update(node); BKE_pbvh_node_mark_update_mask(node); if (*((bool *)rebuild)) { - BKE_pbvh_node_mark_rebuild_draw(node); - BKE_pbvh_node_mark_visibility_update(node); + BKE_pbvh_node_mark_update_visibility(node); } BKE_pbvh_node_fully_hidden_set(node, 0); } @@ -332,6 +331,15 @@ static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode) return true; } +static bool sculpt_undo_restore_face_sets(bContext *C, SculptUndoNode *unode) +{ + ViewLayer *view_layer = CTX_data_view_layer(C); + Object *ob = OBACT(view_layer); + SculptSession *ss = ob->sculpt; + memcpy(ss->face_sets, unode->face_sets, ss->totpoly * sizeof(int)); + return false; +} + static void sculpt_undo_bmesh_restore_generic_task_cb( void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { @@ -533,6 +541,30 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask); return; } + else if (unode->type == SCULPT_UNDO_FACE_SETS) { + + sculpt_undo_restore_face_sets(C, unode); + + rebuild = true; + BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild); + + BKE_sculpt_update_object_for_edit(depsgraph, ob, true, need_mask); + + sculpt_visibility_sync_all_face_sets_to_vertices(ss); + BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility); + + if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { + BKE_mesh_flush_hidden_from_verts(ob->data); + } + + if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) { + DEG_id_tag_update(&ob->id, ID_RECALC_SHADING); + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + } + + unode->applied = true; + return; + } } BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask); @@ -584,6 +616,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase update_mask = true; } break; + case SCULPT_UNDO_FACE_SETS: + break; case SCULPT_UNDO_DYNTOPO_BEGIN: case SCULPT_UNDO_DYNTOPO_END: @@ -619,10 +653,16 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase }; BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb_partial, &data); BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw); + if (update_mask) { BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask); } + if (update_visibility) { + sculpt_visibility_sync_all_vertex_to_face_sets(ss); + BKE_pbvh_update_visibility(ss->pbvh); + } + if (BKE_sculpt_multires_active(scene, ob)) { if (rebuild) { multires_mark_as_modified(depsgraph, ob, MULTIRES_HIDDEN_MODIFIED); @@ -642,10 +682,6 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase BKE_sculptsession_free_deformMats(ss); } - if (update_visibility) { - BKE_pbvh_update_visibility(ss->pbvh); - } - if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && update_visibility) { Mesh *mesh = ob->data; BKE_mesh_flush_hidden_from_verts(mesh); @@ -714,6 +750,10 @@ static void sculpt_undo_free_list(ListBase *lb) CustomData_free(&unode->geom_pdata, unode->geom_totpoly); } + if (unode->face_sets) { + MEM_freeN(unode->face_sets); + } + MEM_freeN(unode); unode = unode_next; @@ -828,6 +868,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt case SCULPT_UNDO_DYNTOPO_SYMMETRIZE: BLI_assert(!"Dynamic topology should've already been handled"); case SCULPT_UNDO_GEOMETRY: + case SCULPT_UNDO_FACE_SETS: break; } @@ -939,6 +980,27 @@ static SculptUndoNode *sculpt_undo_geometry_push(Object *ob, SculptUndoType type return unode; } +static SculptUndoNode *sculpt_undo_face_sets_push(Object *ob, SculptUndoType type) +{ + UndoSculpt *usculpt = sculpt_undo_get_nodes(); + SculptSession *ss = ob->sculpt; + + SculptUndoNode *unode = usculpt->nodes.first; + + unode = MEM_callocN(sizeof(*unode), __func__); + + BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname)); + unode->type = type; + unode->applied = true; + + unode->face_sets = MEM_callocN(ss->totpoly * sizeof(int), "sculpt face sets"); + memcpy(unode->face_sets, ss->face_sets, ss->totpoly * sizeof(int)); + + BLI_addtail(&usculpt->nodes, unode); + + return unode; +} + static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, SculptUndoType type) { UndoSculpt *usculpt = sculpt_undo_get_nodes(); @@ -1022,6 +1084,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt case SCULPT_UNDO_DYNTOPO_END: case SCULPT_UNDO_DYNTOPO_SYMMETRIZE: case SCULPT_UNDO_GEOMETRY: + case SCULPT_UNDO_FACE_SETS: break; } } @@ -1051,6 +1114,11 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType BLI_thread_unlock(LOCK_CUSTOM1); return unode; } + else if (type == SCULPT_UNDO_FACE_SETS) { + unode = sculpt_undo_face_sets_push(ob, type); + BLI_thread_unlock(LOCK_CUSTOM1); + return unode; + } else if ((unode = sculpt_undo_get_node(node))) { BLI_thread_unlock(LOCK_CUSTOM1); return unode; @@ -1091,6 +1159,7 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType case SCULPT_UNDO_DYNTOPO_SYMMETRIZE: BLI_assert(!"Dynamic topology should've already been handled"); case SCULPT_UNDO_GEOMETRY: + case SCULPT_UNDO_FACE_SETS: break; } |