diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_mesh_remesh_voxel.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pbvh.h | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_remesh_voxel.c | 49 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 106 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_intern.h | 4 |
10 files changed, 208 insertions, 22 deletions
diff --git a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h index 794b8dca4bc..b63f9a9814b 100644 --- a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h +++ b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h @@ -60,6 +60,7 @@ struct Mesh *BKE_mesh_remesh_quadriflow_to_mesh_nomain(struct Mesh *mesh, /* Data reprojection functions */ void BKE_mesh_remesh_reproject_paint_mask(struct Mesh *target, struct Mesh *source); +void BKE_remesh_reproject_sculpt_face_sets(struct Mesh *target, struct Mesh *source); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 016012d7288..ceb48783e20 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -218,6 +218,8 @@ void BKE_paint_toolslots_brush_update(struct Paint *paint); void BKE_paint_toolslots_brush_validate(struct Main *bmain, struct Paint *paint); struct Brush *BKE_paint_toolslots_brush_get(struct Paint *paint, int slot_index); +#define SCULPT_FACE_SET_NONE 0 + /* Used for both vertex color and weight paint */ struct SculptVertexPaintGeomMap { int *vert_map_mem; @@ -290,6 +292,9 @@ typedef struct SculptSession { struct MeshElemMap *pmap; int *pmap_mem; + /* Mesh Face Sets */ + int *face_sets; + /* BMesh for dynamic topology sculpting */ struct BMesh *bm; int cd_vert_node_offset; @@ -304,6 +309,7 @@ typedef struct SculptSession { /* PBVH acceleration structure */ struct PBVH *pbvh; bool show_mask; + bool show_face_sets; /* Painting on deformed mesh */ bool deform_modifiers_active; /* object is deformed with some modifiers */ diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 3971b248a2e..6097fab814f 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -102,6 +102,7 @@ void BKE_pbvh_build_mesh(PBVH *bvh, int totvert, struct CustomData *vdata, struct CustomData *ldata, + struct CustomData *pdata, const struct MLoopTri *looptri, int looptri_num); void BKE_pbvh_build_grids(PBVH *bvh, @@ -244,10 +245,10 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *bvh, void BKE_pbvh_node_mark_update(PBVHNode *node); void BKE_pbvh_node_mark_update_mask(PBVHNode *node); +void BKE_pbvh_node_mark_update_visibility(PBVHNode *node); void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node); void BKE_pbvh_node_mark_redraw(PBVHNode *node); void BKE_pbvh_node_mark_normals_update(PBVHNode *node); -void BKE_pbvh_node_mark_visibility_update(PBVHNode *node); void BKE_pbvh_node_mark_topology_update(PBVHNode *node); void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden); void BKE_pbvh_node_fully_masked_set(PBVHNode *node, int fully_masked); @@ -298,6 +299,8 @@ void BKE_pbvh_grids_update(PBVH *bvh, struct DMFlagMat *flagmats, unsigned int **grid_hidden); +void BKE_pbvh_face_sets_color_seed_set(PBVH *bvh, int seed); + /* Layer displacement */ /* Get the node's displacement layer, creating it if necessary */ @@ -361,6 +364,7 @@ typedef struct PBVHVertexIter { short *no; float *fno; float *mask; + bool visible; } PBVHVertexIter; void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mode); @@ -390,6 +394,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo vi.mask = vi.key.has_mask ? CCG_elem_mask(&vi.key, vi.grid) : NULL; \ vi.grid = CCG_elem_next(&vi.key, vi.grid); \ vi.index++; \ + vi.visible = true; \ if (vi.gh) { \ if (BLI_BITMAP_TEST(vi.gh, vi.gy * vi.gridsize + vi.gx)) \ continue; \ @@ -397,7 +402,8 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo } \ else if (vi.mverts) { \ vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \ - if (mode == PBVH_ITER_UNIQUE && vi.mvert->flag & ME_HIDE) \ + vi.visible = !(vi.mvert->flag & ME_HIDE); \ + if (mode == PBVH_ITER_UNIQUE && !vi.visible) \ continue; \ vi.co = vi.mvert->co; \ vi.no = vi.mvert->no; \ @@ -414,7 +420,8 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_other_verts); \ BLI_gsetIterator_step(&vi.bm_other_verts); \ } \ - if (mode == PBVH_ITER_UNIQUE && BM_elem_flag_test(vi.bm_vert, BM_ELEM_HIDDEN)) \ + vi.visible = !BM_elem_flag_test_bool(vi.bm_vert, BM_ELEM_HIDDEN); \ + if (mode == PBVH_ITER_UNIQUE && !vi.visible) \ continue; \ vi.co = vi.bm_vert->co; \ vi.fno = vi.bm_vert->no; \ @@ -445,6 +452,9 @@ bool BKE_pbvh_node_vert_update_check_any(PBVH *bvh, PBVHNode *node); bool pbvh_has_mask(PBVH *bvh); void pbvh_show_mask_set(PBVH *bvh, bool show_mask); +bool pbvh_has_face_sets(PBVH *bvh); +void pbvh_show_face_sets_set(PBVH *bvh, bool show_face_sets); + /* Parallelization */ typedef void (*PBVHParallelRangeFunc)(void *__restrict userdata, const int iter, diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 8abad2d541d..a1725197a36 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1010,6 +1010,12 @@ void BKE_brush_sculpt_reset(Brush *br) br->flag &= ~BRUSH_SPACE; br->flag &= ~BRUSH_SPACE_ATTEN; break; + case SCULPT_TOOL_DRAW_FACE_SETS: + br->alpha = 0.5f; + br->flag &= ~BRUSH_ALPHA_PRESSURE; + br->flag &= ~BRUSH_SPACE; + br->flag &= ~BRUSH_SPACE_ATTEN; + break; case SCULPT_TOOL_GRAB: br->alpha = 0.4f; br->size = 75; @@ -1085,6 +1091,7 @@ void BKE_brush_sculpt_reset(Brush *br) case SCULPT_TOOL_SIMPLIFY: case SCULPT_TOOL_MASK: + case SCULPT_TOOL_DRAW_FACE_SETS: br->add_col[0] = 0.750000; br->add_col[1] = 0.750000; br->add_col[2] = 0.750000; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 93db44ce60a..33707d3f18d 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1621,6 +1621,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(short[4][3]), "", 0, NULL, NULL, NULL, NULL, layerSwap_flnor, NULL}, /* 41: CD_CUSTOMLOOPNORMAL */ {sizeof(short[2]), "vec2s", 1, NULL, NULL, NULL, NULL, NULL, NULL}, + /* 42: CD_SCULPT_FACE_SETS */ + {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, }; static const char *LAYERTYPENAMES[CD_NUMTYPES] = { @@ -1668,6 +1670,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = { /* 39-41 */ "CDMLoopTangent", "CDTessLoopNormal", "CDCustomLoopNormal", + "CDSculptFaceGroups", }; const CustomData_MeshMasks CD_MASK_BAREMESH = { @@ -1692,7 +1695,7 @@ const CustomData_MeshMasks CD_MASK_MESH = { .lmask = (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_GENERIC_DATA), .pmask = (CD_MASK_MPOLY | CD_MASK_RECAST | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | - CD_MASK_GENERIC_DATA), + CD_MASK_GENERIC_DATA | CD_MASK_SCULPT_FACE_SETS), }; const CustomData_MeshMasks CD_MASK_EDITMESH = { .vmask = (CD_MASK_MDEFORMVERT | CD_MASK_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY | @@ -1701,7 +1704,7 @@ const CustomData_MeshMasks CD_MASK_EDITMESH = { .fmask = 0, .lmask = (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_GENERIC_DATA), - .pmask = (CD_MASK_RECAST | CD_MASK_FACEMAP | CD_MASK_GENERIC_DATA), + .pmask = (CD_MASK_RECAST | CD_MASK_FACEMAP | CD_MASK_GENERIC_DATA | CD_MASK_SCULPT_FACE_SETS), }; const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { .vmask = (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN | @@ -1712,7 +1715,7 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GENERIC_DATA), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */ .pmask = (CD_MASK_ORIGINDEX | CD_MASK_RECAST | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | - CD_MASK_GENERIC_DATA), + CD_MASK_GENERIC_DATA | CD_MASK_SCULPT_FACE_SETS), }; const CustomData_MeshMasks CD_MASK_BMESH = { .vmask = (CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY | @@ -1721,7 +1724,8 @@ const CustomData_MeshMasks CD_MASK_BMESH = { .fmask = 0, .lmask = (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_GENERIC_DATA), - .pmask = (CD_MASK_RECAST | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_GENERIC_DATA), + .pmask = (CD_MASK_RECAST | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_GENERIC_DATA | + CD_MASK_SCULPT_FACE_SETS), }; /** * cover values copied by #BKE_mesh_loops_to_tessdata @@ -1750,7 +1754,8 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = { CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | CD_MASK_GENERIC_DATA), .pmask = (CD_MASK_MPOLY | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_NORMAL | - CD_MASK_RECAST | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_GENERIC_DATA), + CD_MASK_RECAST | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_GENERIC_DATA | + CD_MASK_SCULPT_FACE_SETS), }; static const LayerTypeInfo *layerType_getInfo(int type) @@ -4221,7 +4226,7 @@ bool CustomData_verify_versions(struct CustomData *data, int index) /* 0 structnum is used in writing code to tag layer types that should not be written. */ else if (typeInfo->structnum == 0 && /* XXX Not sure why those three are exception, maybe that should be fixed? */ - !ELEM(layer->type, CD_PAINT_MASK, CD_FACEMAP, CD_MTEXPOLY)) { + !ELEM(layer->type, CD_PAINT_MASK, CD_FACEMAP, CD_MTEXPOLY, CD_SCULPT_FACE_SETS)) { keeplayer = false; CLOG_WARN(&LOG, ".blend file read: removing a data layer that should not have been written"); } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 51f37254d8f..81ba48bd106 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -31,6 +31,8 @@ #include "BLI_utildefines.h" #include "BLI_bitmap.h" +#include "BLI_ghash.h" +#include "BLI_hash.h" #include "BLI_math.h" #include "BLI_linklist.h" #include "BLI_memarena.h" @@ -51,6 +53,8 @@ #include "BKE_object.h" #include "BKE_editmesh.h" +#include "PIL_time.h" + #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -542,6 +546,8 @@ void BKE_mesh_init(Mesh *me) CustomData_reset(&me->ldata); BKE_mesh_runtime_reset(me); + + me->face_sets_color_seed = BLI_hash_int(PIL_check_seconds_timer_i() & UINT_MAX); } Mesh *BKE_mesh_add(Main *bmain, const char *name) @@ -671,6 +677,8 @@ void BKE_mesh_copy_settings(Mesh *me_dst, const Mesh *me_src) me_dst->remesh_voxel_adaptivity = me_src->remesh_voxel_adaptivity; me_dst->remesh_mode = me_src->remesh_mode; + me_dst->face_sets_color_seed = me_src->face_sets_color_seed; + /* Copy texture space. */ me_dst->texflag = me_src->texflag; copy_v3_v3(me_dst->loc, me_src->loc); diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.c b/source/blender/blenkernel/intern/mesh_remesh_voxel.c index afc380fd369..983c19857dd 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.c +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.c @@ -356,6 +356,55 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source) free_bvhtree_from_mesh(&bvhtree); } +void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, Mesh *source) +{ + BVHTreeFromMesh bvhtree = { + .nearest_callback = NULL, + }; + + const MPoly *target_polys = CustomData_get_layer(&target->pdata, CD_MPOLY); + const MVert *target_verts = CustomData_get_layer(&target->vdata, CD_MVERT); + const MLoop *target_loops = CustomData_get_layer(&target->ldata, CD_MLOOP); + + int *target_face_sets; + if (CustomData_has_layer(&target->pdata, CD_SCULPT_FACE_SETS)) { + target_face_sets = CustomData_get_layer(&target->pdata, CD_SCULPT_FACE_SETS); + } + else { + target_face_sets = CustomData_add_layer( + &target->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, target->totpoly); + } + + int *source_face_sets; + if (CustomData_has_layer(&source->pdata, CD_SCULPT_FACE_SETS)) { + source_face_sets = CustomData_get_layer(&source->pdata, CD_SCULPT_FACE_SETS); + } + else { + source_face_sets = CustomData_add_layer( + &source->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, source->totpoly); + } + + const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(source); + BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_LOOPTRI, 2); + + for (int i = 0; i < target->totpoly; i++) { + float from_co[3]; + BVHTreeNearest nearest; + nearest.index = -1; + nearest.dist_sq = FLT_MAX; + const MPoly *mpoly = &target_polys[i]; + BKE_mesh_calc_poly_center(mpoly, &target_loops[mpoly->loopstart], target_verts, from_co); + BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree); + if (nearest.index != -1) { + target_face_sets[i] = source_face_sets[looptri[nearest.index].poly]; + } + else { + target_face_sets[i] = 1; + } + } + free_bvhtree_from_mesh(&bvhtree); +} + struct Mesh *BKE_mesh_remesh_voxel_fix_poles(struct Mesh *mesh) { const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh); diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 9f05b1656cd..bd585d56a51 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1212,6 +1212,7 @@ static void sculpt_update_object( ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob); ss->show_mask = (sd->flags & SCULPT_HIDE_MASK) == 0; + ss->show_face_sets = (sd->flags & SCULPT_HIDE_FACE_SETS) == 0; ss->building_vp_handle = false; @@ -1251,6 +1252,16 @@ static void sculpt_update_object( ss->mloop = me->mloop; ss->multires = NULL; ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); + + /* Sculpt Face Sets. */ + if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) { + ss->face_sets = CustomData_add_layer( + &me->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, me->totpoly); + for (int i = 0; i < me->totpoly; i++) { + ss->face_sets[i] = 1; + } + } + ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS); } ss->subdiv_ccg = me_eval->runtime.subdiv_ccg; @@ -1265,6 +1276,7 @@ static void sculpt_update_object( } pbvh_show_mask_set(ss->pbvh, ss->show_mask); + pbvh_show_face_sets_set(ss->pbvh, ss->show_face_sets); if (ss->deform_modifiers_active) { if (!ss->orig_cos) { @@ -1501,6 +1513,7 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob) ob->sculpt->cd_vert_node_offset, ob->sculpt->cd_face_node_offset); pbvh_show_mask_set(pbvh, ob->sculpt->show_mask); + pbvh_show_face_sets_set(pbvh, false); return pbvh; } @@ -1522,10 +1535,12 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform) me->totvert, &me->vdata, &me->ldata, + &me->pdata, looptri, looptris_num); pbvh_show_mask_set(pbvh, ob->sculpt->show_mask); + pbvh_show_face_sets_set(pbvh, ob->sculpt->show_face_sets); const bool is_deformed = check_sculpt_object_deformed(ob, true); if (is_deformed && me_eval_deform != NULL) { @@ -1551,6 +1566,7 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg) subdiv_ccg->grid_flag_mats, subdiv_ccg->grid_hidden); pbvh_show_mask_set(pbvh, ob->sculpt->show_mask); + pbvh_show_face_sets_set(pbvh, false); return pbvh; } diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 95e7218a920..61caccccf90 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -26,6 +26,7 @@ #include "BLI_math.h" #include "BLI_ghash.h" #include "BLI_task.h" +#include "BLI_rand.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -36,6 +37,8 @@ #include "BKE_mesh.h" /* for BKE_mesh_calc_normals */ #include "BKE_paint.h" +#include "PIL_time.h" + #include "GPU_buffers.h" #include "bmesh.h" @@ -541,6 +544,7 @@ void BKE_pbvh_build_mesh(PBVH *bvh, int totvert, struct CustomData *vdata, struct CustomData *ldata, + struct CustomData *pdata, const MLoopTri *looptri, int looptri_num) { @@ -558,6 +562,9 @@ void BKE_pbvh_build_mesh(PBVH *bvh, bvh->leaf_limit = LEAF_LIMIT; bvh->vdata = vdata; bvh->ldata = ldata; + bvh->pdata = pdata; + + bvh->face_sets_color_seed = mesh->face_sets_color_seed; BB_reset(&cb); @@ -992,6 +999,7 @@ typedef struct PBVHUpdateData { float (*vnors)[3]; int flag; bool show_vcol; + bool show_sculpt_face_sets; } PBVHUpdateData; static void pbvh_update_normals_accum_task_cb(void *__restrict userdata, @@ -1155,6 +1163,44 @@ static void pbvh_update_mask_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, in BKE_pbvh_parallel_range(0, totnode, &data, pbvh_update_mask_redraw_task_cb, &settings); } +static void pbvh_update_visibility_redraw_task_cb(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict UNUSED(tls)) +{ + + PBVHUpdateData *data = userdata; + PBVH *bvh = data->bvh; + PBVHNode *node = data->nodes[n]; + if (node->flag & PBVH_UpdateVisibility) { + node->flag &= ~PBVH_UpdateVisibility; + BKE_pbvh_node_fully_hidden_set(node, true); + if (node->flag & PBVH_Leaf) { + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL) + { + if (vd.visible) { + BKE_pbvh_node_fully_hidden_set(node, false); + return; + } + } + BKE_pbvh_vertex_iter_end; + } + } +} + +static void pbvh_update_visibility_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag) +{ + PBVHUpdateData data = { + .bvh = bvh, + .nodes = nodes, + .flag = flag, + }; + + PBVHParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range(0, totnode, &data, pbvh_update_visibility_redraw_task_cb, &settings); +} + static void pbvh_update_BB_redraw_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) @@ -1198,6 +1244,7 @@ static int pbvh_get_buffers_update_flags(PBVH *bvh, bool show_vcol) int update_flags = 0; update_flags |= bvh->show_mask ? GPU_PBVH_BUFFERS_SHOW_MASK : 0; update_flags |= show_vcol ? GPU_PBVH_BUFFERS_SHOW_VCOL : 0; + update_flags |= bvh->show_face_sets ? GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS : 0; return update_flags; } @@ -1218,14 +1265,16 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata, node->draw_buffers = GPU_pbvh_grid_buffers_build(node->totprim, bvh->grid_hidden); break; case PBVH_FACES: - node->draw_buffers = GPU_pbvh_mesh_buffers_build(node->face_vert_indices, - bvh->mpoly, - bvh->mloop, - bvh->looptri, - bvh->verts, - node->prim_indices, - node->totprim, - bvh->mesh); + node->draw_buffers = GPU_pbvh_mesh_buffers_build( + node->face_vert_indices, + bvh->mpoly, + bvh->mloop, + bvh->looptri, + bvh->verts, + node->prim_indices, + CustomData_get_layer(bvh->pdata, CD_SCULPT_FACE_SETS), + node->totprim, + bvh->mesh); break; case PBVH_BMESH: node->draw_buffers = GPU_pbvh_bmesh_buffers_build(bvh->flags & @@ -1253,6 +1302,8 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata, node->uniq_verts + node->face_verts, CustomData_get_layer(bvh->vdata, CD_PAINT_MASK), CustomData_get_layer(bvh->ldata, CD_MLOOPCOL), + CustomData_get_layer(bvh->pdata, CD_SCULPT_FACE_SETS), + bvh->face_sets_color_seed, node->face_vert_indices, update_flags); break; @@ -1373,6 +1424,10 @@ void BKE_pbvh_update_vertex_data(PBVH *bvh, int flag) pbvh_update_mask_redraw(bvh, nodes, totnode, flag); } + if (flag & (PBVH_UpdateVisibility)) { + pbvh_update_visibility_redraw(bvh, nodes, totnode, flag); + } + if (nodes) { MEM_freeN(nodes); } @@ -1650,6 +1705,12 @@ void BKE_pbvh_node_mark_update_mask(PBVHNode *node) node->flag |= PBVH_UpdateMask | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; } +void BKE_pbvh_node_mark_update_visibility(PBVHNode *node) +{ + node->flag |= PBVH_UpdateVisibility | PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | + PBVH_UpdateRedraw; +} + void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node) { node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; @@ -1665,11 +1726,6 @@ void BKE_pbvh_node_mark_normals_update(PBVHNode *node) node->flag |= PBVH_UpdateNormals; } -void BKE_pbvh_node_mark_visibility_update(PBVHNode *node) -{ - node->flag |= PBVH_UpdateVisibility; -} - void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden) { BLI_assert(node->flag & PBVH_Leaf); @@ -2559,6 +2615,11 @@ void BKE_pbvh_update_normals(PBVH *bvh, struct SubdivCCG *subdiv_ccg) MEM_SAFE_FREE(nodes); } +void BKE_pbvh_face_sets_color_seed_set(PBVH *bvh, int seed) +{ + bvh->face_sets_color_seed = seed; +} + /** * PBVH drawing, updating draw buffers as needed and culling any nodes outside * the specified frustum. @@ -2873,11 +2934,30 @@ bool pbvh_has_mask(PBVH *bvh) return false; } +bool pbvh_has_face_sets(PBVH *bvh) +{ + switch (bvh->type) { + case PBVH_GRIDS: + return false; + case PBVH_FACES: + return (bvh->pdata && CustomData_get_layer(bvh->pdata, CD_SCULPT_FACE_SETS)); + case PBVH_BMESH: + return false; + } + + return false; +} + void pbvh_show_mask_set(PBVH *bvh, bool show_mask) { bvh->show_mask = show_mask; } +void pbvh_show_face_sets_set(PBVH *bvh, bool show_face_sets) +{ + bvh->show_face_sets = show_face_sets; +} + void BKE_pbvh_parallel_range_settings(PBVHParallelSettings *settings, bool use_threading, int totnode) diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index bdee05f1aab..51342eb1faa 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -134,6 +134,9 @@ struct PBVH { const MLoopTri *looptri; CustomData *vdata; CustomData *ldata; + CustomData *pdata; + + int face_sets_color_seed; /* Grid Data */ CCGKey gridkey; @@ -154,6 +157,7 @@ struct PBVH { /* flag are verts/faces deformed */ bool deformed; bool show_mask; + bool show_face_sets; /* Dynamic topology */ BMesh *bm; |