diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_expand.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_expand.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index 8b8ed42a694..40874375772 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -273,7 +273,7 @@ static bool sculpt_expand_state_get(SculptSession *ss, ExpandCache *expand_cache */ static bool sculpt_expand_face_state_get(SculptSession *ss, ExpandCache *expand_cache, const int f) { - if (ss->face_sets[f] <= 0) { + if (expand_cache->original_face_sets[f] <= 0) { return false; } @@ -1398,6 +1398,13 @@ static void sculpt_expand_face_sets_restore(SculptSession *ss, ExpandCache *expa { const int totfaces = ss->totfaces; for (int i = 0; i < totfaces; i++) { + if (expand_cache->original_face_sets[i] <= 0) { + /* Do not modify hidden Face Sets, even when restoring the IDs state. */ + continue; + } + if (!sculpt_expand_is_face_in_active_component(ss, expand_cache, i)) { + continue; + } ss->face_sets[i] = expand_cache->initial_face_sets[i]; } } @@ -1892,13 +1899,22 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event * The faces that were using the `delete_id` Face Set are filled * using the content from their neighbors. */ -static void sculpt_expand_delete_face_set_id( - int *r_face_sets, Mesh *mesh, MeshElemMap *pmap, const int totface, const int delete_id) +static void sculpt_expand_delete_face_set_id(int *r_face_sets, + SculptSession *ss, + ExpandCache *expand_cache, + Mesh *mesh, + const int delete_id) { + const int totface = ss->totfaces; + MeshElemMap *pmap = ss->pmap; + /* Check that all the face sets IDs in the mesh are not equal to `delete_id` * before attempting to delete it. */ bool all_same_id = true; for (int i = 0; i < totface; i++) { + if (!sculpt_expand_is_face_in_active_component(ss, expand_cache, i)) { + continue; + } if (r_face_sets[i] != delete_id) { all_same_id = false; break; @@ -1921,6 +1937,7 @@ static void sculpt_expand_delete_face_set_id( } while (BLI_LINKSTACK_SIZE(queue)) { + bool any_updated = false; while (BLI_LINKSTACK_SIZE(queue)) { const int f_index = POINTER_AS_INT(BLI_LINKSTACK_POP(queue)); int other_id = delete_id; @@ -1931,6 +1948,10 @@ static void sculpt_expand_delete_face_set_id( for (int i = 0; i < vert_map->count; i++) { const int neighbor_face_index = vert_map->indices[i]; + if (expand_cache->original_face_sets[neighbor_face_index] <= 0) { + /* Skip picking IDs from hidden Face Sets. */ + continue; + } if (r_face_sets[neighbor_face_index] != delete_id) { other_id = r_face_sets[neighbor_face_index]; } @@ -1938,18 +1959,36 @@ static void sculpt_expand_delete_face_set_id( } if (other_id != delete_id) { + any_updated = true; r_face_sets[f_index] = other_id; } else { BLI_LINKSTACK_PUSH(queue_next, POINTER_FROM_INT(f_index)); } } + if (!any_updated) { + /* No Face Sets where updated in this iteration, which means that no more content to keep + * filling the polys of the deleted Face Set was found. Break to avoid entering an infinite + * loop trying to search for those polys again. */ + break; + } BLI_LINKSTACK_SWAP(queue, queue_next); } BLI_LINKSTACK_FREE(queue); BLI_LINKSTACK_FREE(queue_next); + + /* Ensure that the visibility state of the modified Face Sets is the same as the original ones. + */ + for (int i = 0; i < totface; i++) { + if (expand_cache->original_face_sets[i] >= 0) { + r_face_sets[i] = abs(r_face_sets[i]); + } + else { + r_face_sets[i] = -abs(r_face_sets[i]); + } + } } static void sculpt_expand_cache_initial_config_set(bContext *C, @@ -2070,9 +2109,9 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even if (ss->expand_cache->modify_active_face_set) { sculpt_expand_delete_face_set_id(ss->expand_cache->initial_face_sets, + ss, + ss->expand_cache, ob->data, - ss->pmap, - ss->totfaces, ss->expand_cache->next_face_set); } |