Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_mesh_remesh_voxel.h1
-rw-r--r--source/blender/blenkernel/BKE_paint.h6
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h16
-rw-r--r--source/blender/blenkernel/intern/brush.c7
-rw-r--r--source/blender/blenkernel/intern/customdata.c17
-rw-r--r--source/blender/blenkernel/intern/mesh.c8
-rw-r--r--source/blender/blenkernel/intern/mesh_remesh_voxel.c49
-rw-r--r--source/blender/blenkernel/intern/paint.c16
-rw-r--r--source/blender/blenkernel/intern/pbvh.c106
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h4
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;