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:
authorJoseph Eagar <joeedh@gmail.com>2022-10-15 09:14:21 +0300
committerJoseph Eagar <joeedh@gmail.com>2022-10-15 09:14:21 +0300
commitae412d54e36185aef7103110a3e79c83877ee74f (patch)
treefd52c86469b779f9bf61f92754b060dadf342f86
parentd582920e18a9c95df90119b806bec3873cf8bce5 (diff)
parentebe9804cfa421b746148f3067797f16e7f460551 (diff)
Merge branch 'master' into temp-pbvh-texpaint-automaskingtemp-pbvh-texpaint-automasking
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h3
-rw-r--r--source/blender/blenkernel/intern/paint.cc3
-rw-r--r--source/blender/blenkernel/intern/pbvh.c191
-rw-r--r--source/blender/draw/intern/draw_pbvh.cc17
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.cc5
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h2
6 files changed, 209 insertions, 12 deletions
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index ba22091d1a1..046750e3bd0 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -267,7 +267,8 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
void **gridfaces,
struct DMFlagMat *flagmats,
unsigned int **grid_hidden,
- struct Mesh *me);
+ struct Mesh *me,
+ struct SubdivCCG *subdiv_ccg);
/**
* Build a PBVH from a BMesh.
*/
diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc
index d45ce776b64..934cfb3cc46 100644
--- a/source/blender/blenkernel/intern/paint.cc
+++ b/source/blender/blenkernel/intern/paint.cc
@@ -2237,7 +2237,8 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
(void **)subdiv_ccg->grid_faces,
subdiv_ccg->grid_flag_mats,
subdiv_ccg->grid_hidden,
- base_mesh);
+ base_mesh,
+ subdiv_ccg);
pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
pbvh_show_face_sets_set(pbvh, ob->sculpt->show_face_sets);
return pbvh;
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index dfa66e594f5..5476434ffe3 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -39,8 +39,10 @@
#define LEAF_LIMIT 10000
-//#define PERFCNTRS
+/* Uncomment to test that faces are only assigned to one PBVHNode */
+//#define VALIDATE_UNIQUE_NODE_FACES
+//#define PERFCNTRS
#define STACK_FIXED_DEPTH 100
typedef struct PBVHStack {
@@ -422,6 +424,56 @@ static bool leaf_needs_material_split(PBVH *pbvh, int offset, int count)
return false;
}
+static int adjust_partition_faces(PBVH *pbvh, int offset, int mid, int count)
+{
+ int poly = pbvh->looptri[pbvh->prim_indices[mid]].poly;
+
+ /* Scan backwards. */
+ while (mid > offset + 2) { /* First node should have at least 1 primitive */
+ if (pbvh->looptri[pbvh->prim_indices[mid - 1]].poly != poly) {
+ return mid;
+ }
+
+ mid--;
+ }
+
+ /* If that didn't work try scanning forward. */
+ while (mid < pbvh->totprim + count) {
+ if (pbvh->looptri[pbvh->prim_indices[mid]].poly != poly) {
+ break;
+ }
+
+ mid++;
+ }
+
+ return mid;
+}
+
+static int adjust_partition_grids(PBVH *pbvh, int offset, int mid, int count)
+{
+ int poly = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, pbvh->prim_indices[mid]);
+
+ /* Scan backwards. */
+ while (mid > offset + 2) { /* First node should have at least 1 primitive */
+ if (BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, pbvh->prim_indices[mid - 1]) != poly) {
+ return mid;
+ }
+
+ mid--;
+ }
+
+ /* If that didn't work try scanning forward. */
+ while (mid < pbvh->totprim + count) {
+ if (BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, pbvh->prim_indices[mid]) != poly) {
+ break;
+ }
+
+ mid++;
+ }
+
+ return mid;
+}
+
/* Recursively build a node in the tree
*
* vb is the voxel box around all of the primitives contained in
@@ -478,6 +530,13 @@ static void build_sub(PBVH *pbvh, int node_index, BB *cb, BBC *prim_bbc, int off
end = partition_indices_material(pbvh, offset, offset + count - 1);
}
+ if (pbvh->header.type == PBVH_FACES) {
+ end = adjust_partition_faces(pbvh, offset, end, count);
+ }
+ else {
+ end = adjust_partition_grids(pbvh, offset, end, count);
+ }
+
/* Build children */
build_sub(pbvh, pbvh->nodes[node_index].children_offset, NULL, prim_bbc, offset, end - offset);
build_sub(pbvh,
@@ -587,6 +646,73 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node)
}
}
+#ifdef VALIDATE_UNIQUE_NODE_FACES
+static void pbvh_validate_node_prims(PBVH *pbvh)
+{
+ int totface = 0;
+
+ if (pbvh->header.type == PBVH_BMESH) {
+ return;
+ }
+
+ for (int i = 0; i < pbvh->totnode; i++) {
+ PBVHNode *node = pbvh->nodes + i;
+
+ if (!(node->flag & PBVH_Leaf)) {
+ continue;
+ }
+
+ for (int j = 0; j < node->totprim; j++) {
+ int poly;
+
+ if (pbvh->header.type == PBVH_FACES) {
+ poly = pbvh->looptri[node->prim_indices[j]].poly;
+ }
+ else {
+ poly = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, node->prim_indices[j]);
+ }
+
+ totface = max_ii(totface, poly + 1);
+ }
+ }
+
+ int *facemap = (int *)MEM_malloc_arrayN(totface, sizeof(*facemap), __func__);
+
+ for (int i = 0; i < totface; i++) {
+ facemap[i] = -1;
+ }
+
+ for (int i = 0; i < pbvh->totnode; i++) {
+ PBVHNode *node = pbvh->nodes + i;
+
+ if (!(node->flag & PBVH_Leaf)) {
+ continue;
+ }
+
+ for (int j = 0; j < node->totprim; j++) {
+ int poly;
+
+ if (pbvh->header.type == PBVH_FACES) {
+ poly = pbvh->looptri[node->prim_indices[j]].poly;
+ }
+ else {
+ poly = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, node->prim_indices[j]);
+ }
+
+ if (facemap[poly] != -1 && facemap[poly] != i) {
+ printf("%s: error: face spanned multiple nodes (old: %d new: %d)\n",
+ __func__,
+ facemap[poly],
+ i);
+ }
+
+ facemap[poly] = i;
+ }
+ }
+ MEM_SAFE_FREE(facemap);
+}
+#endif
+
void BKE_pbvh_build_mesh(PBVH *pbvh,
Mesh *mesh,
const MPoly *mpoly,
@@ -645,6 +771,32 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
BB_expand(&cb, bbc->bcentroid);
}
+ /* Ensure all primitives belonging to the same base face
+ * have the same bounds. This is needed to prevent them
+ * from being swapped away from each other inside the partition
+ * array.
+ */
+ for (int i = 0; i < looptri_num; i++) {
+ const MLoopTri *lt = &looptri[i];
+ int poly = lt->poly;
+ BBC *bbc = prim_bbc + i;
+ int j = i + 1;
+
+ while (j < looptri_num && looptri[j].poly == poly) {
+ BBC *bbc2 = prim_bbc + j;
+
+ BB_expand((BB *)bbc, bbc2->bmin);
+ BB_expand((BB *)bbc, bbc2->bmax);
+ j++;
+ }
+
+ j = i + 1;
+ while (j < looptri_num && looptri[j].poly == poly) {
+ prim_bbc[j] = prim_bbc[i];
+ j++;
+ }
+ }
+
if (looptri_num) {
pbvh_build(pbvh, &cb, prim_bbc, looptri_num);
}
@@ -655,6 +807,10 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
memset(pbvh->vert_bitmap, 0, sizeof(bool) * totvert);
BKE_pbvh_update_active_vcol(pbvh, mesh);
+
+#ifdef VALIDATE_UNIQUE_NODE_FACES
+ pbvh_validate_node_prims(pbvh);
+#endif
}
void BKE_pbvh_build_grids(PBVH *pbvh,
@@ -664,7 +820,8 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
void **gridfaces,
DMFlagMat *flagmats,
BLI_bitmap **grid_hidden,
- Mesh *me)
+ Mesh *me,
+ SubdivCCG *subdiv_ccg)
{
const int gridsize = key->grid_size;
@@ -675,6 +832,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
pbvh->totgrid = totgrid;
pbvh->gridkey = *key;
pbvh->grid_hidden = grid_hidden;
+ pbvh->subdiv_ccg = subdiv_ccg;
pbvh->leaf_limit = max_ii(LEAF_LIMIT / (gridsize * gridsize), 1);
/* We need the base mesh attribute layout for PBVH draw. */
@@ -706,11 +864,40 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
BB_expand(&cb, bbc->bcentroid);
}
+ /* Ensure all primitives belonging to the same base face
+ * have the same bounds. This is needed to prevent them
+ * from being swapped away from each other inside the partition
+ * array.
+ */
+ for (int i = 0; i < totgrid; i++) {
+ int poly = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, i);
+
+ BBC *bbc = prim_bbc + i;
+ int j = i + 1;
+
+ while (j < totgrid && BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, j) == poly) {
+ BBC *bbc2 = prim_bbc + j;
+
+ BB_expand((BB *)bbc, bbc2->bmin);
+ BB_expand((BB *)bbc, bbc2->bmax);
+ j++;
+ }
+
+ j = i + 1;
+ while (j < totgrid && BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, j) == poly) {
+ prim_bbc[j] = prim_bbc[i];
+ j++;
+ }
+ }
+
if (totgrid) {
pbvh_build(pbvh, &cb, prim_bbc, totgrid);
}
MEM_freeN(prim_bbc);
+#ifdef VALIDATE_UNIQUE_NODE_FACES
+ pbvh_validate_node_prims(pbvh);
+#endif
}
PBVH *BKE_pbvh_new(PBVHType type)
diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc
index 880a5a445f4..60a0d4e6bb2 100644
--- a/source/blender/draw/intern/draw_pbvh.cc
+++ b/source/blender/draw/intern/draw_pbvh.cc
@@ -389,12 +389,19 @@ struct PBVHBatches {
break;
case CD_PBVH_MASK_TYPE:
- foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
- float *mask = CCG_elem_mask(&args->ccg_key, elems[i]);
+ if (args->ccg_key.has_mask) {
+ foreach_grids([&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem *elems[4], int i) {
+ float *mask = CCG_elem_mask(&args->ccg_key, elems[i]);
- *static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = mask ? uchar(*mask * 255.0f) :
- 255;
- });
+ *static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = uchar(*mask * 255.0f);
+ });
+ }
+ else {
+ foreach_grids(
+ [&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem * /*elems*/[4], int i) {
+ *static_cast<uchar *>(GPU_vertbuf_raw_step(&access)) = 0;
+ });
+ }
break;
case CD_PBVH_FSET_TYPE: {
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc
index 5f5a555b428..ee1238e0f24 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc
@@ -198,8 +198,8 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
const bool relax_face_sets = !(ss->cache->iteration_count % 3 == 0);
/* This operations needs a strength tweak as the relax deformation is too weak by default. */
- if (relax_face_sets) {
- bstrength *= 2.0f;
+ if (relax_face_sets && data->iteration < 2) {
+ bstrength *= 1.5f;
}
const int thread_id = BLI_task_parallel_thread_id(tls);
@@ -261,6 +261,7 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
if (ss->cache->alt_smooth) {
SCULPT_boundary_info_ensure(ob);
for (int i = 0; i < 4; i++) {
+ data.iteration = i;
BLI_task_parallel_range(0, totnode, &data, do_relax_face_sets_brush_task_cb_ex, &settings);
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index a99c57ac145..d52eabfcd18 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -332,7 +332,7 @@ typedef struct SculptThreadedTaskData {
int mask_init_seed;
ThreadMutex mutex;
-
+ int iteration;
} SculptThreadedTaskData;
/*************** Brush testing declarations ****************/