diff options
author | Joseph Eagar <joeedh@gmail.com> | 2022-10-15 09:14:21 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2022-10-15 09:14:21 +0300 |
commit | ae412d54e36185aef7103110a3e79c83877ee74f (patch) | |
tree | fd52c86469b779f9bf61f92754b060dadf342f86 /source/blender | |
parent | d582920e18a9c95df90119b806bec3873cf8bce5 (diff) | |
parent | ebe9804cfa421b746148f3067797f16e7f460551 (diff) |
Merge branch 'master' into temp-pbvh-texpaint-automaskingtemp-pbvh-texpaint-automasking
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_pbvh.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.cc | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 191 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_pbvh.cc | 17 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_face_set.cc | 5 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_intern.h | 2 |
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 ****************/ |