diff --git a/source/blender/blenkernel/BKE_pbvh_api.hh b/source/blender/blenkernel/BKE_pbvh_api.hh index da8a39426ac..ce9ed36d2a6 100644 --- a/source/blender/blenkernel/BKE_pbvh_api.hh +++ b/source/blender/blenkernel/BKE_pbvh_api.hh @@ -253,6 +253,8 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh, PBVHNode *node, float (*origco)[3], bool use_origco, + blender::Span corner_verts, + const bool *hide_poly, const float ray_start[3], const float ray_normal[3], IsectRayPrecalc *isect_precalc, @@ -291,6 +293,8 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh, PBVHNode *node, float (*origco)[3], bool use_origco, + blender::Span corner_verts, + const bool *hide_poly, const float ray_start[3], const float ray_normal[3], float *depth, @@ -398,10 +402,7 @@ void BKE_pbvh_node_num_verts(const PBVH *pbvh, int BKE_pbvh_node_num_unique_verts(const PBVH &pbvh, const PBVHNode &node); blender::Span BKE_pbvh_node_get_vert_indices(const PBVHNode *node); blender::Span BKE_pbvh_node_get_unique_vert_indices(const PBVHNode *node); -void BKE_pbvh_node_get_loops(PBVH *pbvh, - PBVHNode *node, - const int **r_loop_indices, - const int **r_corner_verts); +void BKE_pbvh_node_get_loops(PBVHNode *node, const int **r_loop_indices); blender::Vector BKE_pbvh_node_calc_face_indices(const PBVH &pbvh, const PBVHNode &node); /* Get number of faces in the mesh; for PBVH_GRIDS the @@ -450,14 +451,6 @@ blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh, void BKE_pbvh_grids_update(PBVH *pbvh, CCGKey *key); void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, SubdivCCG *subdiv_ccg); -/** - * If an operation causes the hide status stored in the mesh to change, this must be called - * to update the references to those attributes, since they are only added when necessary. - */ -void BKE_pbvh_update_hide_attributes_from_mesh(PBVH *pbvh); - -/* Vertex Deformer. */ - void BKE_pbvh_vert_coords_apply(PBVH *pbvh, blender::Span vert_positions); bool BKE_pbvh_is_deformed(PBVH *pbvh); @@ -624,10 +617,6 @@ void BKE_pbvh_parallel_range_settings(TaskParallelSettings *settings, blender::MutableSpan BKE_pbvh_get_vert_positions(const PBVH *pbvh); const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3]; -const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh); -bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh); - -const bool *BKE_pbvh_get_poly_hide(const PBVH *pbvh); PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node); void BKE_pbvh_node_color_buffer_free(PBVH *pbvh); diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index c95daa95182..679ef00f3b0 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1750,7 +1750,6 @@ static void sculpt_update_object( UNUSED_VARS_NDEBUG(pbvh); BKE_pbvh_subdiv_cgg_set(ss->pbvh, ss->subdiv_ccg); - BKE_pbvh_update_hide_attributes_from_mesh(ss->pbvh); sculpt_attribute_update_refs(ob); sculpt_update_persistent_base(ob); diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index 7e3b166f67a..6ab55b191ed 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -250,16 +250,19 @@ static int partition_indices_grids(blender::MutableSpan prim_indices, } /* Returns the index of the first element on the right of the partition */ -static int partition_indices_material( - PBVH *pbvh, const int *material_indices, const bool *sharp_faces, int lo, int hi) +static int partition_indices_material(PBVH *pbvh, + const Span looptri_faces, + const int *material_indices, + const bool *sharp_faces, + int lo, + int hi) { - const Span looptri_faces = pbvh->looptri_faces; const Span flagmats = pbvh->subdiv_ccg->grid_flag_mats; MutableSpan indices = pbvh->prim_indices; int i = lo, j = hi; for (;;) { - if (!pbvh->looptri_faces.is_empty()) { + if (!looptri_faces.is_empty()) { const int first = looptri_faces[pbvh->prim_indices[lo]]; for (; face_materials_match(material_indices, sharp_faces, first, looptri_faces[indices[i]]); i++) { @@ -297,13 +300,16 @@ void pbvh_grow_nodes(PBVH *pbvh, int totnode) /* Add a vertex to the map, with a positive value for unique vertices and * a negative value for additional vertices */ -static int map_insert_vert( - PBVH *pbvh, blender::Map &map, int *face_verts, int *uniq_verts, int vertex) +static int map_insert_vert(blender::Map &map, + MutableSpan vert_bitmap, + int *face_verts, + int *uniq_verts, + int vertex) { return map.lookup_or_add_cb(vertex, [&]() { int value; - if (!pbvh->vert_bitmap[vertex]) { - pbvh->vert_bitmap[vertex] = true; + if (!vert_bitmap[vertex]) { + vert_bitmap[vertex] = true; value = *uniq_verts; (*uniq_verts)++; } @@ -316,7 +322,12 @@ static int map_insert_vert( } /* Find vertices used by the faces in this node and update the draw buffers */ -static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node) +static void build_mesh_leaf_node(const Span corner_verts, + const Span looptris, + const Span looptri_faces, + const bool *hide_poly, + MutableSpan vert_bitmap, + PBVHNode *node) { node->uniq_verts = node->face_verts = 0; const Span prim_indices = node->prim_indices; @@ -328,10 +339,10 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node) node->face_vert_indices.reinitialize(prim_indices.size()); for (const int i : prim_indices.index_range()) { - const MLoopTri &tri = pbvh->looptri[prim_indices[i]]; + const MLoopTri &tri = looptris[prim_indices[i]]; for (int j = 0; j < 3; j++) { node->face_vert_indices[i][j] = map_insert_vert( - pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->corner_verts[tri.tri[j]]); + map, vert_bitmap, &node->face_verts, &node->uniq_verts, corner_verts[tri.tri[j]]); } } @@ -355,12 +366,11 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node) } } - const bool fully_hidden = pbvh->hide_poly && - std::all_of( - prim_indices.begin(), prim_indices.end(), [&](const int tri) { - const int face = pbvh->looptri_faces[tri]; - return pbvh->hide_poly[face]; - }); + const bool fully_hidden = hide_poly && std::all_of(prim_indices.begin(), + prim_indices.end(), + [&](const int tri) { + return hide_poly[looptri_faces[tri]]; + }); BKE_pbvh_node_fully_hidden_set(node, fully_hidden); BKE_pbvh_node_mark_rebuild_draw(node); } @@ -423,37 +433,51 @@ static void build_grid_leaf_node(PBVH *pbvh, PBVHNode *node) BKE_pbvh_node_mark_rebuild_draw(node); } -static void build_leaf(PBVH *pbvh, int node_index, const Span prim_bbc, int offset, int count) +static void build_leaf(PBVH *pbvh, + const Span corner_verts, + const Span looptris, + const Span looptri_faces, + const bool *hide_poly, + int node_index, + const Span prim_bbc, + int offset, + int count) { - pbvh->nodes[node_index].flag |= PBVH_Leaf; + PBVHNode &node = pbvh->nodes[node_index]; + node.flag |= PBVH_Leaf; - pbvh->nodes[node_index].prim_indices = pbvh->prim_indices.as_span().slice(offset, count); + node.prim_indices = pbvh->prim_indices.as_span().slice(offset, count); /* Still need vb for searches */ - update_vb(pbvh, &pbvh->nodes[node_index], prim_bbc, offset, count); + update_vb(pbvh, &node, prim_bbc, offset, count); if (!pbvh->looptri.is_empty()) { - build_mesh_leaf_node(pbvh, &pbvh->nodes[node_index]); + build_mesh_leaf_node( + corner_verts, looptris, looptri_faces, hide_poly, pbvh->vert_bitmap, &node); } else { - build_grid_leaf_node(pbvh, &pbvh->nodes[node_index]); + build_grid_leaf_node(pbvh, &node); } } /* Return zero if all primitives in the node can be drawn with the * same material (including flat/smooth shading), non-zero otherwise */ -static bool leaf_needs_material_split( - PBVH *pbvh, const int *material_indices, const bool *sharp_faces, int offset, int count) +static bool leaf_needs_material_split(PBVH *pbvh, + const Span looptri_faces, + const int *material_indices, + const bool *sharp_faces, + int offset, + int count) { if (count <= 1) { return false; } if (!pbvh->looptri.is_empty()) { - const int first = pbvh->looptri_faces[pbvh->prim_indices[offset]]; + const int first = looptri_faces[pbvh->prim_indices[offset]]; for (int i = offset + count - 1; i > offset; i--) { int prim = pbvh->prim_indices[i]; - if (!face_materials_match(material_indices, sharp_faces, first, pbvh->looptri_faces[prim])) { + if (!face_materials_match(material_indices, sharp_faces, first, looptri_faces[prim])) { return true; } } @@ -491,7 +515,7 @@ static void test_face_boundaries(PBVH *pbvh) switch (BKE_pbvh_type(pbvh)) { case PBVH_FACES: { for (int j = 0; j < node->totprim; j++) { - int face_i = pbvh->looptri_faces[node->prim_indices[j]]; + int face_i = looptri_faces[node->prim_indices[j]]; if (node_map[face_i] >= 0 && node_map[face_i] != i) { int old_i = node_map[face_i]; @@ -532,6 +556,10 @@ static void test_face_boundaries(PBVH *pbvh) */ static void build_sub(PBVH *pbvh, + const Span corner_verts, + const Span looptris, + const Span looptri_faces, + const bool *hide_poly, const int *material_indices, const bool *sharp_faces, int node_index, @@ -552,8 +580,17 @@ static void build_sub(PBVH *pbvh, /* Decide whether this is a leaf or not */ const bool below_leaf_limit = count <= pbvh->leaf_limit || depth >= STACK_FIXED_DEPTH - 1; if (below_leaf_limit) { - if (!leaf_needs_material_split(pbvh, material_indices, sharp_faces, offset, count)) { - build_leaf(pbvh, node_index, prim_bbc, offset, count); + if (!leaf_needs_material_split( + pbvh, looptri_faces, material_indices, sharp_faces, offset, count)) { + build_leaf(pbvh, + corner_verts, + looptris, + looptri_faces, + hide_poly, + node_index, + prim_bbc, + offset, + count); if (node_index == 0) { MEM_SAFE_FREE(prim_scratch); @@ -590,7 +627,7 @@ static void build_sub(PBVH *pbvh, axis, (cb->bmax[axis] + cb->bmin[axis]) * 0.5f, prim_bbc, - pbvh->looptri_faces); + looptri_faces); } else { end = partition_indices_grids(pbvh->prim_indices, @@ -606,11 +643,15 @@ static void build_sub(PBVH *pbvh, else { /* Partition primitives by material */ end = partition_indices_material( - pbvh, material_indices, sharp_faces, offset, offset + count - 1); + pbvh, looptri_faces, material_indices, sharp_faces, offset, offset + count - 1); } /* Build children */ build_sub(pbvh, + corner_verts, + looptris, + looptri_faces, + hide_poly, material_indices, sharp_faces, pbvh->nodes[node_index].children_offset, @@ -621,6 +662,10 @@ static void build_sub(PBVH *pbvh, prim_scratch, depth + 1); build_sub(pbvh, + corner_verts, + looptris, + looptri_faces, + hide_poly, material_indices, sharp_faces, pbvh->nodes[node_index].children_offset + 1, @@ -637,6 +682,10 @@ static void build_sub(PBVH *pbvh, } static void pbvh_build(PBVH *pbvh, + const Span corner_verts, + const Span looptris, + const Span looptri_faces, + const bool *hide_poly, const int *material_indices, const bool *sharp_faces, BB *cb, @@ -653,7 +702,20 @@ static void pbvh_build(PBVH *pbvh, pbvh->nodes.resize(1); - build_sub(pbvh, material_indices, sharp_faces, 0, cb, prim_bbc, 0, totprim, nullptr, 0); + build_sub(pbvh, + corner_verts, + looptris, + looptri_faces, + hide_poly, + material_indices, + sharp_faces, + 0, + cb, + prim_bbc, + 0, + totprim, + nullptr, + 0); } static void pbvh_draw_args_init(const Mesh &mesh, PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) @@ -663,54 +725,42 @@ static void pbvh_draw_args_init(const Mesh &mesh, PBVH *pbvh, PBVH_GPU_Args *arg args->pbvh_type = pbvh->header.type; args->node = node; - args->grid_hidden = pbvh->subdiv_ccg->grid_hidden; args->face_sets_color_default = mesh.face_sets_color_default; args->face_sets_color_seed = mesh.face_sets_color_seed; - args->vert_positions = pbvh->vert_positions; - if (pbvh->mesh) { - args->corner_verts = pbvh->corner_verts; - args->corner_edges = pbvh->mesh->corner_edges(); - } - args->faces = pbvh->faces; - args->mlooptri = pbvh->looptri; - - if (ELEM(pbvh->header.type, PBVH_FACES, PBVH_GRIDS)) { - args->hide_poly = pbvh->face_data ? static_cast(CustomData_get_layer_named( - pbvh->face_data, CD_PROP_BOOL, ".hide_poly")) : - nullptr; - } args->active_color = mesh.active_color_attribute; args->render_color = mesh.default_color_attribute; switch (pbvh->header.type) { case PBVH_FACES: - args->vert_data = pbvh->vert_data; - args->loop_data = pbvh->loop_data; - args->face_data = pbvh->face_data; + args->vert_data = &mesh.vert_data; + args->loop_data = &mesh.loop_data; + args->face_data = &mesh.face_data; args->me = pbvh->mesh; - args->faces = pbvh->faces; + args->vert_positions = pbvh->vert_positions; + args->corner_verts = mesh.corner_verts(); + args->corner_edges = mesh.corner_edges(); + args->mlooptri = pbvh->looptri; args->vert_normals = pbvh->vert_normals; args->face_normals = pbvh->face_normals; + args->hide_poly = static_cast( + CustomData_get_layer_named(&mesh.face_data, CD_PROP_BOOL, ".hide_poly")); args->prim_indices = node->prim_indices; - args->looptri_faces = pbvh->looptri_faces; + args->looptri_faces = mesh.looptri_faces(); break; case PBVH_GRIDS: - args->vert_data = pbvh->vert_data; - args->loop_data = pbvh->loop_data; - args->face_data = pbvh->face_data; + args->vert_data = &mesh.vert_data; + args->loop_data = &mesh.loop_data; + args->face_data = &mesh.face_data; args->ccg_key = pbvh->gridkey; args->me = pbvh->mesh; args->grid_indices = node->prim_indices; args->subdiv_ccg = pbvh->subdiv_ccg; - args->faces = pbvh->faces; - args->grids = pbvh->subdiv_ccg->grids; + args->grid_hidden = pbvh->subdiv_ccg->grid_hidden; args->grid_flag_mats = pbvh->subdiv_ccg->grid_flag_mats; args->vert_normals = pbvh->vert_normals; - - args->looptri_faces = pbvh->looptri_faces; break; case PBVH_BMESH: args->bm = pbvh->header.bm; @@ -726,7 +776,7 @@ static void pbvh_draw_args_init(const Mesh &mesh, PBVH *pbvh, PBVH_GPU_Args *arg } #ifdef VALIDATE_UNIQUE_NODE_FACES -static void pbvh_validate_node_prims(PBVH *pbvh) +static void pbvh_validate_node_prims(PBVH *pbvh, const Span looptri_faces) { int totface = 0; @@ -745,7 +795,7 @@ static void pbvh_validate_node_prims(PBVH *pbvh) int face_i; if (pbvh->header.type == PBVH_FACES) { - face_i = pbvh->looptri_faces[node->prim_indices[j]]; + face_i = looptri_faces[node->prim_indices[j]]; } else { face_i = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, node->prim_indices[j]); @@ -772,7 +822,7 @@ static void pbvh_validate_node_prims(PBVH *pbvh) int face_i; if (pbvh->header.type == PBVH_FACES) { - face_i = pbvh->looptri_faces[node->prim_indices[j]]; + face_i = looptri_faces[node->prim_indices[j]]; } else { face_i = BKE_subdiv_ccg_grid_to_face_index(pbvh->subdiv_ccg, node->prim_indices[j]); @@ -795,11 +845,9 @@ static void pbvh_validate_node_prims(PBVH *pbvh) void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh) { BLI_assert(pbvh->header.type == PBVH_FACES); - pbvh->faces = mesh->faces(); pbvh->corner_verts = mesh->corner_verts(); pbvh->looptri_faces = mesh->looptri_faces(); - if (!pbvh->deformed) { /* Deformed data not matching the original mesh are owned directly by the PBVH, and are * set separately by #BKE_pbvh_vert_coords_apply. */ @@ -807,12 +855,6 @@ void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh) pbvh->vert_normals = mesh->vert_normals(); pbvh->face_normals = mesh->face_normals(); } - - BKE_pbvh_update_hide_attributes_from_mesh(pbvh); - - pbvh->vert_data = &mesh->vert_data; - pbvh->loop_data = &mesh->loop_data; - pbvh->face_data = &mesh->face_data; } void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh) @@ -824,13 +866,14 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh) const Span corner_verts = mesh->corner_verts(); pbvh->looptri.reinitialize(looptri_num); - blender::bke::mesh::looptris_calc(vert_positions, faces, corner_verts, pbvh->looptri); + const Span looptris = pbvh->looptri; pbvh->mesh = mesh; pbvh->header.type = PBVH_FACES; BKE_pbvh_update_mesh_pointers(pbvh, mesh); + const Span looptri_faces = pbvh->looptri_faces; /* Those are not set in #BKE_pbvh_update_mesh_pointers because they are owned by the #PBVH. */ pbvh->vert_bitmap = blender::Array(totvert, false); @@ -852,17 +895,17 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh) BB cb; BB_reset(&cb); cb = blender::threading::parallel_reduce( - pbvh->looptri.index_range(), + looptris.index_range(), 1024, cb, [&](const blender::IndexRange range, const BB &init) { BB current = init; for (const int i : range) { - const MLoopTri < = pbvh->looptri[i]; + const MLoopTri < = looptris[i]; BBC *bbc = &prim_bbc[i]; BB_reset((BB *)bbc); for (int j = 0; j < 3; j++) { - BB_expand((BB *)bbc, vert_positions[pbvh->corner_verts[lt.tri[j]]]); + BB_expand((BB *)bbc, vert_positions[corner_verts[lt.tri[j]]]); } BBC_update_centroid(bbc); BB_expand(¤t, bbc->bcentroid); @@ -876,14 +919,25 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh) }); if (looptri_num) { + const bool *hide_poly = static_cast( + CustomData_get_layer_named(&mesh->face_data, CD_PROP_BOOL, ".hide_poly")); const int *material_indices = static_cast( CustomData_get_layer_named(&mesh->face_data, CD_PROP_INT32, "material_index")); const bool *sharp_faces = (const bool *)CustomData_get_layer_named( &mesh->face_data, CD_PROP_BOOL, "sharp_face"); - pbvh_build(pbvh, material_indices, sharp_faces, &cb, prim_bbc, looptri_num); + pbvh_build(pbvh, + corner_verts, + looptris, + looptri_faces, + hide_poly, + material_indices, + sharp_faces, + &cb, + prim_bbc, + looptri_num); #ifdef TEST_PBVH_FACE_SPLIT - test_face_boundaries(pbvh); + test_face_boundaries(pbvh, looptri_faces); #endif } @@ -920,14 +974,6 @@ void BKE_pbvh_build_grids(PBVH *pbvh, CCGKey *key, Mesh *me, SubdivCCG *subdiv_c */ pbvh->leaf_limit = max_ii(LEAF_LIMIT / (gridsize * gridsize), max_grids); - /* We need the base mesh attribute layout for PBVH draw. */ - pbvh->vert_data = &me->vert_data; - pbvh->loop_data = &me->loop_data; - pbvh->face_data = &me->face_data; - - pbvh->faces = faces; - pbvh->corner_verts = me->corner_verts(); - /* We also need the base mesh for PBVH draw. */ pbvh->mesh = me; @@ -964,7 +1010,8 @@ void BKE_pbvh_build_grids(PBVH *pbvh, CCGKey *key, Mesh *me, SubdivCCG *subdiv_c CustomData_get_layer_named(&me->face_data, CD_PROP_INT32, "material_index")); const bool *sharp_faces = (const bool *)CustomData_get_layer_named( &me->face_data, CD_PROP_BOOL, "sharp_face"); - pbvh_build(pbvh, material_indices, sharp_faces, &cb, prim_bbc, grids.size()); + pbvh_build( + pbvh, {}, {}, {}, nullptr, material_indices, sharp_faces, &cb, prim_bbc, grids.size()); #ifdef TEST_PBVH_FACE_SPLIT test_face_boundaries(pbvh); @@ -1292,8 +1339,8 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span nodes, Mesh & using namespace blender; using namespace blender::bke; const Span positions = pbvh->vert_positions; - const OffsetIndices faces = pbvh->faces; - const Span corner_verts = pbvh->corner_verts; + const OffsetIndices faces = mesh.faces(); + const Span corner_verts = mesh.corner_verts(); MutableSpan update_tags = pbvh->vert_bitmap; @@ -1578,11 +1625,11 @@ static void pbvh_faces_node_visibility_update(const Mesh &mesh, const Span hide_vert = *attributes.lookup(".hide_vert", ATTR_DOMAIN_POINT); if (hide_vert.is_empty()) { for (PBVHNode *node : nodes) { - BKE_pbvh_node_fully_hidden_set(node, false); + BKE_pbvh_node_fully_hidden_set(node, false); node->flag &= ~PBVH_UpdateVisibility; - } - return; } + return; + } threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { for (PBVHNode *node : nodes.slice(range)) { @@ -1600,33 +1647,33 @@ static void pbvh_grids_node_visibility_update(PBVH *pbvh, const Span using namespace blender; threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { for (PBVHNode *node : nodes.slice(range)) { - CCGElem *const *grids; - const int *grid_indices; - int totgrid, i; + CCGElem *const *grids; + const int *grid_indices; + int totgrid, i; - BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids); - const Span grid_hidden = pbvh->subdiv_ccg->grid_hidden; - CCGKey key = *BKE_pbvh_get_grid_key(pbvh); + BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids); + const Span grid_hidden = pbvh->subdiv_ccg->grid_hidden; + CCGKey key = *BKE_pbvh_get_grid_key(pbvh); - for (i = 0; i < totgrid; i++) { - int g = grid_indices[i], x, y; - const BLI_bitmap *gh = grid_hidden[g]; + for (i = 0; i < totgrid; i++) { + int g = grid_indices[i], x, y; + const BLI_bitmap *gh = grid_hidden[g]; - if (!gh) { - BKE_pbvh_node_fully_hidden_set(node, false); - return; - } - - for (y = 0; y < key.grid_size; y++) { - for (x = 0; x < key.grid_size; x++) { - if (!BLI_BITMAP_TEST(gh, y * key.grid_size + x)) { + if (!gh) { BKE_pbvh_node_fully_hidden_set(node, false); return; } + + for (y = 0; y < key.grid_size; y++) { + for (x = 0; x < key.grid_size; x++) { + if (!BLI_BITMAP_TEST(gh, y * key.grid_size + x)) { + BKE_pbvh_node_fully_hidden_set(node, false); + return; + } + } + } } - } - } - BKE_pbvh_node_fully_hidden_set(node, true); + BKE_pbvh_node_fully_hidden_set(node, true); node->flag &= ~PBVH_UpdateVisibility; } }); @@ -1638,20 +1685,20 @@ static void pbvh_bmesh_node_visibility_update(const Span nodes) threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { for (PBVHNode *node : nodes.slice(range)) { for (const BMVert *v : node->bm_unique_verts) { - if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { - BKE_pbvh_node_fully_hidden_set(node, false); - return; - } - } + if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { + BKE_pbvh_node_fully_hidden_set(node, false); + return; + } + } for (const BMVert *v : node->bm_other_verts) { - if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { - BKE_pbvh_node_fully_hidden_set(node, false); - return; - } - } + if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { + BKE_pbvh_node_fully_hidden_set(node, false); + return; + } + } - BKE_pbvh_node_fully_hidden_set(node, true); + BKE_pbvh_node_fully_hidden_set(node, true); node->flag &= ~PBVH_UpdateVisibility; } }); @@ -1872,20 +1919,11 @@ void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, PBVHVertRef vertex) pbvh->vert_bitmap[vertex.i] = true; } -void BKE_pbvh_node_get_loops(PBVH *pbvh, - PBVHNode *node, - const int **r_loop_indices, - const int **r_corner_verts) +void BKE_pbvh_node_get_loops(PBVHNode *node, const int **r_loop_indices) { - BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); - if (r_loop_indices) { *r_loop_indices = node->loop_indices.data(); } - - if (r_corner_verts) { - *r_corner_verts = pbvh->corner_verts.data(); - } } int BKE_pbvh_num_faces(const PBVH *pbvh) @@ -2249,6 +2287,8 @@ bool ray_face_nearest_tri(const float ray_start[3], static bool pbvh_faces_node_raycast(PBVH *pbvh, const PBVHNode *node, float (*origco)[3], + const Span corner_verts, + const bool *hide_poly, const float ray_start[3], const float ray_normal[3], IsectRayPrecalc *isect_precalc, @@ -2258,7 +2298,6 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, float *r_face_normal) { const Span positions = pbvh->vert_positions; - const Span corner_verts = pbvh->corner_verts; bool hit = false; float nearest_vertex_co[3] = {0.0f}; @@ -2267,7 +2306,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, const MLoopTri *lt = &pbvh->looptri[looptri_i]; const blender::int3 face_verts = node->face_vert_indices[i]; - if (pbvh->hide_poly && pbvh->hide_poly[pbvh->looptri_faces[looptri_i]]) { + if (hide_poly && hide_poly[pbvh->looptri_faces[looptri_i]]) { continue; } @@ -2411,6 +2450,8 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh, PBVHNode *node, float (*origco)[3], bool use_origco, + const Span corner_verts, + const bool *hide_poly, const float ray_start[3], const float ray_normal[3], IsectRayPrecalc *isect_precalc, @@ -2430,6 +2471,8 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh, hit |= pbvh_faces_node_raycast(pbvh, node, origco, + corner_verts, + hide_poly, ray_start, ray_normal, isect_precalc, @@ -2600,13 +2643,14 @@ void BKE_pbvh_find_nearest_to_ray(PBVH *pbvh, static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh, const PBVHNode *node, float (*origco)[3], + const Span corner_verts, + const bool *hide_poly, const float ray_start[3], const float ray_normal[3], float *depth, float *dist_sq) { const Span positions = pbvh->vert_positions; - const Span corner_verts = pbvh->corner_verts; bool hit = false; for (const int i : node->prim_indices.index_range()) { @@ -2614,7 +2658,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh, const MLoopTri *lt = &pbvh->looptri[looptri_i]; const blender::int3 face_verts = node->face_vert_indices[i]; - if (pbvh->hide_poly && pbvh->hide_poly[pbvh->looptri_faces[looptri_i]]) { + if (hide_poly && hide_poly[pbvh->looptri_faces[looptri_i]]) { continue; } @@ -2709,6 +2753,8 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh, PBVHNode *node, float (*origco)[3], bool use_origco, + const Span corner_verts, + const bool *hide_poly, const float ray_start[3], const float ray_normal[3], float *depth, @@ -2723,7 +2769,7 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh, switch (pbvh->header.type) { case PBVH_FACES: hit |= pbvh_faces_node_nearest_to_ray( - pbvh, node, origco, ray_start, ray_normal, depth, dist_sq); + pbvh, node, origco, corner_verts, hide_poly, ray_start, ray_normal, depth, dist_sq); break; case PBVH_GRIDS: hit |= pbvh_grids_node_nearest_to_ray( @@ -3078,10 +3124,10 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m vi->mask = 0.0f; if (pbvh->header.type == PBVH_FACES) { vi->vert_normals = pbvh->vert_normals; - vi->hide_vert = pbvh->hide_vert; - + vi->hide_vert = static_cast( + CustomData_get_layer_named(&pbvh->mesh->vert_data, CD_PROP_BOOL, ".hide_vert")); vi->vmask = static_cast( - CustomData_get_layer_named(pbvh->vert_data, CD_PROP_FLOAT, ".sculpt_mask")); + CustomData_get_layer_named(&pbvh->mesh->vert_data, CD_PROP_FLOAT, ".sculpt_mask")); } } @@ -3154,49 +3200,11 @@ const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3] return reinterpret_cast(pbvh->vert_normals.data()); } -const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh) -{ - BLI_assert(pbvh->header.type == PBVH_FACES); - return pbvh->hide_vert; -} - -const bool *BKE_pbvh_get_poly_hide(const PBVH *pbvh) -{ - BLI_assert(ELEM(pbvh->header.type, PBVH_FACES, PBVH_GRIDS)); - return pbvh->hide_poly; -} - -bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh) -{ - BLI_assert(pbvh->header.type == PBVH_FACES); - if (pbvh->hide_vert) { - return pbvh->hide_vert; - } - pbvh->hide_vert = static_cast(CustomData_get_layer_named_for_write( - &pbvh->mesh->vert_data, CD_PROP_BOOL, ".hide_vert", pbvh->mesh->totvert)); - if (pbvh->hide_vert) { - return pbvh->hide_vert; - } - pbvh->hide_vert = static_cast(CustomData_add_layer_named( - &pbvh->mesh->vert_data, CD_PROP_BOOL, CD_SET_DEFAULT, pbvh->mesh->totvert, ".hide_vert")); - return pbvh->hide_vert; -} - void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, SubdivCCG *subdiv_ccg) { pbvh->subdiv_ccg = subdiv_ccg; } -void BKE_pbvh_update_hide_attributes_from_mesh(PBVH *pbvh) -{ - if (pbvh->header.type == PBVH_FACES) { - pbvh->hide_vert = static_cast(CustomData_get_layer_named_for_write( - &pbvh->mesh->vert_data, CD_PROP_BOOL, ".hide_vert", pbvh->mesh->totvert)); - pbvh->hide_poly = static_cast(CustomData_get_layer_named_for_write( - &pbvh->mesh->face_data, CD_PROP_BOOL, ".hide_poly", pbvh->mesh->faces_num)); - } -} - bool BKE_pbvh_is_drawing(const PBVH *pbvh) { return pbvh->is_drawing; @@ -3292,7 +3300,6 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh) switch (pbvh->header.type) { case PBVH_FACES: { BKE_mesh_flush_hidden_from_verts(mesh); - BKE_pbvh_update_hide_attributes_from_mesh(pbvh); break; } case PBVH_BMESH: { @@ -3353,7 +3360,6 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh) } BKE_mesh_flush_hidden_from_faces(mesh); - BKE_pbvh_update_hide_attributes_from_mesh(pbvh); break; } } diff --git a/source/blender/blenkernel/intern/pbvh_intern.hh b/source/blender/blenkernel/intern/pbvh_intern.hh index 24eedbc4ca5..055dd9d1d67 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.hh +++ b/source/blender/blenkernel/intern/pbvh_intern.hh @@ -164,17 +164,12 @@ struct PBVH { blender::Span vert_normals; blender::Span face_normals; - blender::OffsetIndices faces; - bool *hide_vert; - bool *hide_poly; /** Only valid for polygon meshes. */ + blender::OffsetIndices faces; blender::Span corner_verts; /* Owned by the #PBVH, because after deformations they have to be recomputed. */ blender::Array looptri; blender::Span looptri_faces; - CustomData *vert_data; - CustomData *loop_data; - CustomData *face_data; /* Grid Data */ CCGKey gridkey; diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index 16dff0eb270..e1f088967a7 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -667,7 +667,8 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image const AttributeAccessor attributes = mesh->attributes(); const VArraySpan uv_map = *attributes.lookup(active_uv_name, ATTR_DOMAIN_CORNER); - uv_islands::MeshData mesh_data(pbvh->looptri, pbvh->corner_verts, uv_map, pbvh->vert_positions); + uv_islands::MeshData mesh_data( + pbvh->looptri, mesh->corner_verts(), uv_map, pbvh->vert_positions); uv_islands::UVIslands islands(mesh_data); uv_islands::UVIslandsMask uv_masks; diff --git a/source/blender/draw/DRW_pbvh.hh b/source/blender/draw/DRW_pbvh.hh index 20565c8a93a..5b2ba7ff8ca 100644 --- a/source/blender/draw/DRW_pbvh.hh +++ b/source/blender/draw/DRW_pbvh.hh @@ -38,7 +38,6 @@ struct PBVH_GPU_Args { BMesh *bm; const Mesh *me; blender::MutableSpan vert_positions; - blender::OffsetIndices faces; blender::Span corner_verts; blender::Span corner_edges; const CustomData *vert_data; diff --git a/source/blender/editors/sculpt_paint/paint_hide.cc b/source/blender/editors/sculpt_paint/paint_hide.cc index ce457aefa1c..317cafdd29d 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.cc +++ b/source/blender/editors/sculpt_paint/paint_hide.cc @@ -211,7 +211,6 @@ static void partialvis_update_mesh(Object &object, } BKE_mesh_flush_hidden_from_verts(&mesh); - BKE_pbvh_update_hide_attributes_from_mesh(&pbvh); } /* Hide or show elements in multires grids with a special GridFlags diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 440a267ce62..743ae8a8933 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -406,7 +406,9 @@ bool SCULPT_vertex_visible_get(const SculptSession *ss, PBVHVertRef vertex) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { - const bool *hide_vert = BKE_pbvh_get_vert_hide(ss->pbvh); + const Mesh *mesh = BKE_pbvh_get_mesh(ss->pbvh); + const bool *hide_vert = static_cast( + CustomData_get_layer_named(&mesh->vert_data, CD_PROP_BOOL, ".hide_vert")); return hide_vert == nullptr || !hide_vert[vertex.i]; } case PBVH_BMESH: @@ -659,7 +661,6 @@ void SCULPT_visibility_sync_all_from_faces(Object *ob) /* We may have adjusted the ".hide_poly" attribute, now make the hide status attributes for * vertices and edges consistent. */ BKE_mesh_flush_hidden_from_faces(mesh); - BKE_pbvh_update_hide_attributes_from_mesh(ss->pbvh); break; } case PBVH_GRIDS: { @@ -3103,6 +3104,8 @@ struct SculptRaycastData { bool hit; float depth; bool original; + Span corner_verts; + const bool *hide_poly; PBVHVertRef active_vertex; float *face_normal; @@ -3119,6 +3122,8 @@ struct SculptFindNearestToRayData { float depth; float dist_sq_to_ray; bool original; + Span corner_verts; + const bool *hide_poly; }; ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3]) @@ -4978,6 +4983,8 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) node, origco, use_origco, + srd->corner_verts, + srd->hide_poly, srd->ray_start, srd->ray_normal, &srd->isect_precalc, @@ -5016,6 +5023,8 @@ static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *t node, origco, use_origco, + srd->corner_verts, + srd->hide_poly, srd->ray_start, srd->ray_normal, &srd->depth, @@ -5104,6 +5113,12 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, srd.original = original; srd.ss = ob->sculpt; srd.hit = false; + if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { + const Mesh &mesh = *static_cast(ob->data); + srd.corner_verts = mesh.corner_verts(); + srd.hide_poly = static_cast( + CustomData_get_layer_named(&mesh.face_data, CD_PROP_BOOL, ".hide_poly")); + } srd.ray_start = ray_start; srd.ray_normal = ray_normal; srd.depth = depth; @@ -5244,6 +5259,12 @@ bool SCULPT_stroke_get_location_ex(bContext *C, srd.ray_start = ray_start; srd.ray_normal = ray_normal; srd.hit = false; + if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { + const Mesh &mesh = *static_cast(ob->data); + srd.corner_verts = mesh.corner_verts(); + srd.hide_poly = static_cast( + CustomData_get_layer_named(&mesh.face_data, CD_PROP_BOOL, ".hide_poly")); + } srd.depth = depth; srd.original = original; srd.face_normal = face_normal; @@ -5266,6 +5287,12 @@ bool SCULPT_stroke_get_location_ex(bContext *C, srd.original = original; srd.ss = ob->sculpt; srd.hit = false; + if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { + const Mesh &mesh = *static_cast(ob->data); + srd.corner_verts = mesh.corner_verts(); + srd.hide_poly = static_cast( + CustomData_get_layer_named(&mesh.face_data, CD_PROP_BOOL, ".hide_poly")); + } srd.ray_start = ray_start; srd.ray_normal = ray_normal; srd.depth = FLT_MAX; diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.cc b/source/blender/editors/sculpt_paint/sculpt_ops.cc index cecae101a64..07af217407b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -1325,15 +1325,6 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op) } SCULPT_visibility_sync_all_from_faces(ob); - - /* NOTE: #SCULPT_visibility_sync_all_from_faces may have deleted - * `pbvh->hide_vert` if hide_poly did not exist, which is why - * we call #BKE_pbvh_update_hide_attributes_from_mesh here instead of - * after #CustomData_free_layer_named above. */ - if (!with_bmesh) { - BKE_pbvh_update_hide_attributes_from_mesh(ss->pbvh); - } - BKE_pbvh_update_visibility(ss->pbvh); SCULPT_undo_push_end(ob); diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index 076733e7721..da638d2205e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -494,6 +494,7 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool *modified_vertices) { + using namespace blender; const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); BKE_view_layer_synced_ensure(scene, view_layer); @@ -501,17 +502,20 @@ static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool SculptSession *ss = ob->sculpt; SubdivCCG *subdiv_ccg = ss->subdiv_ccg; - bool *hide_vert = BKE_pbvh_get_vert_hide_for_write(ss->pbvh); - if (unode->maxvert) { - for (int i = 0; i < unode->totvert; i++) { - const int vert_index = unode->index[i]; - if (unode->vert_hidden[i].test() != hide_vert[vert_index]) { + Mesh &mesh = *static_cast(ob->data); + bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); + bke::SpanAttributeWriter hide_vert = attributes.lookup_or_add_for_write_span( + ".hide_vert", ATTR_DOMAIN_POINT); + for (const int i : unode->index.index_range()) { + const int vert = unode->index[i]; + if (unode->vert_hidden[i].test() != hide_vert.span[vert]) { unode->vert_hidden[i].set(!unode->vert_hidden[i].test()); - hide_vert[vert_index] = !hide_vert[vert_index]; - modified_vertices[vert_index] = true; + hide_vert.span[vert] = !hide_vert.span[vert]; + modified_vertices[vert] = true; } } + hide_vert.finish(); } else if (unode->maxgrid && subdiv_ccg != nullptr) { blender::MutableSpan grid_hidden = subdiv_ccg->grid_hidden; @@ -1366,22 +1370,23 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode) static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode) { - PBVH *pbvh = ob->sculpt->pbvh; - PBVHNode *node = static_cast(unode->node); - - const bool *hide_vert = BKE_pbvh_get_vert_hide(pbvh); - if (hide_vert == nullptr) { - return; - } - + using namespace blender; + using namespace blender::bke; if (!unode->grids.is_empty()) { /* Already stored during allocation. */ } - else { - const blender::Span verts = BKE_pbvh_node_get_vert_indices(node); - for (const int i : verts.index_range()) - unode->vert_hidden[i].set(hide_vert[verts[i]]); + + const Mesh &mesh = *static_cast(ob->data); + const AttributeAccessor attributes = mesh.attributes(); + const VArraySpan hide_vert = *attributes.lookup(".hide_vert", ATTR_DOMAIN_POINT); + if (hide_vert.is_empty()) { + return; } + + PBVHNode *node = static_cast(unode->node); + const blender::Span verts = BKE_pbvh_node_get_vert_indices(node); + for (const int i : verts.index_range()) + unode->vert_hidden[i].set(hide_vert[verts[i]]); } static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode) @@ -1563,8 +1568,7 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType const int *loop_indices; int allloop; BKE_pbvh_node_num_loops(ss->pbvh, static_cast(unode->node), &allloop); - BKE_pbvh_node_get_loops( - ss->pbvh, static_cast(unode->node), &loop_indices, nullptr); + BKE_pbvh_node_get_loops(static_cast(unode->node), &loop_indices); if (allloop) { unode->loop_index.as_mutable_span().copy_from({loop_indices, allloop});