Sculpt: Improve support of face sets with dyntopo

Two aspects to this change:

- Do not clear face sets when enabling dynamic topology
- Draw face sets in viewport when dynamic topology is enabled

Newly added faces in the dynamic topology will have face
sets properly assigned. It is only edge collapse which can
potentially lead to undesired results w.r.t face set boundaries.
That will be worked on further as follow up development.

Pull Request: https://projects.blender.org/blender/blender/pulls/113348
This commit is contained in:
Sergey Sharybin 2023-10-06 15:42:22 +02:00 committed by Hans Goudey
parent c567f7ccae
commit 12e9894a75
2 changed files with 36 additions and 8 deletions

View File

@ -208,6 +208,11 @@ template<typename T> const T &bmesh_cd_loop_get(const BMLoop &loop, const int of
return *static_cast<const T *>(POINTER_OFFSET(loop.head.data, offset));
}
template<typename T> const T &bmesh_cd_face_get(const BMFace &face, const int offset)
{
return *static_cast<const T *>(POINTER_OFFSET(face.head.data, offset));
}
template<typename AttributeT, typename VBOT>
void extract_data_vert_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPUVertBuf &vbo)
{
@ -890,11 +895,38 @@ struct PBVHBatches {
break;
}
case CD_PBVH_FSET_TYPE: {
uchar3 white(UCHAR_MAX, UCHAR_MAX, UCHAR_MAX);
BLI_assert(args.domain == ATTR_DOMAIN_FACE);
foreach_bmesh([&](BMLoop * /*l*/) {
*static_cast<uchar3 *>(GPU_vertbuf_raw_step(&access)) = white;
});
const int cd_offset = CustomData_get_offset_named(
&args.bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
uchar4 *data = static_cast<uchar4 *>(GPU_vertbuf_get_data(vbo.vert_buf));
if (cd_offset != -1) {
GSET_FOREACH_BEGIN (const BMFace *, f, args.bm_faces) {
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
continue;
}
const int fset = bmesh_cd_face_get<int>(*f, cd_offset);
uchar4 fset_color;
if (fset != args.face_sets_color_default) {
BKE_paint_face_set_overlay_color_get(fset, args.face_sets_color_seed, fset_color);
}
else {
/* Skip for the default color face set to render it white. */
fset_color[0] = fset_color[1] = fset_color[2] = UCHAR_MAX;
}
*data = *(data + 1) = *(data + 2) = fset_color;
data += 3;
}
GSET_FOREACH_END();
}
else {
MutableSpan(data, GPU_vertbuf_get_vertex_len(vbo.vert_buf)).fill(uchar4(255));
}
break;
}
}
}

View File

@ -163,10 +163,6 @@ static void SCULPT_dynamic_topology_disable_ex(
else {
BKE_sculptsession_bm_to_me(ob, true);
/* Reset Face Sets as they are no longer valid. */
CustomData_free_layer_named(&me->face_data, ".sculpt_face_set", me->faces_num);
me->face_sets_color_default = 1;
/* Sync the visibility to vertices manually as the `pmap` is still not initialized. */
bool *hide_vert = (bool *)CustomData_get_layer_named_for_write(
&me->vert_data, CD_PROP_BOOL, ".hide_vert", me->totvert);