diff --git a/source/blender/blenkernel/BKE_pbvh.hh b/source/blender/blenkernel/BKE_pbvh.hh index 6302a0dcde1..eba6b90a494 100644 --- a/source/blender/blenkernel/BKE_pbvh.hh +++ b/source/blender/blenkernel/BKE_pbvh.hh @@ -43,12 +43,6 @@ enum PBVHNodeFlags { }; ENUM_OPERATORS(PBVHNodeFlags, PBVH_TopologyUpdated); -struct PBVHVertRef { - intptr_t i; -}; - -#define PBVH_REF_NONE -1LL - void BKE_pbvh_draw_debug_cb(blender::bke::pbvh::Tree &pbvh, void (*draw_fn)(blender::bke::pbvh::Node *node, void *user_data, diff --git a/source/blender/blenkernel/BKE_pbvh_api.hh b/source/blender/blenkernel/BKE_pbvh_api.hh index d27792f3c25..58ff6b9af61 100644 --- a/source/blender/blenkernel/BKE_pbvh_api.hh +++ b/source/blender/blenkernel/BKE_pbvh_api.hh @@ -44,6 +44,7 @@ struct Depsgraph; struct IsectRayPrecalc; struct Mesh; struct SubdivCCG; +struct SubdivCCGCoord; struct Image; struct ImageUser; struct Object; @@ -319,23 +320,40 @@ void raycast(Tree &pbvh, const float3 &ray_normal, bool original); -bool raycast_node(Tree &pbvh, - Node &node, - Span node_positions, - bool use_origco, - Span vert_positions, - OffsetIndices faces, - Span corner_verts, - Span corner_tris, - Span hide_poly, - const SubdivCCG *subdiv_ccg, - const float3 &ray_start, - const float3 &ray_normal, - IsectRayPrecalc *isect_precalc, - float *depth, - PBVHVertRef *r_active_vertex, - int &r_active_face_grid_index, - float3 &r_face_normal); +bool node_raycast_mesh(const MeshNode &node, + Span node_positions, + Span vert_positions, + OffsetIndices faces, + Span corner_verts, + Span corner_tris, + Span hide_poly, + const float3 &ray_start, + const float3 &ray_normal, + IsectRayPrecalc *isect_precalc, + float *depth, + int &r_active_vertex, + int &r_active_face_index, + float3 &r_face_normal); + +bool node_raycast_grids(const SubdivCCG &subdiv_ccg, + GridsNode &node, + Span node_positions, + const float3 &ray_start, + const float3 &ray_normal, + const IsectRayPrecalc *isect_precalc, + float *depth, + SubdivCCGCoord &r_active_vertex, + int &r_active_grid_index, + float3 &r_face_normal); + +bool node_raycast_bmesh(BMeshNode &node, + const float3 &ray_start, + const float3 &ray_normal, + IsectRayPrecalc *isect_precalc, + float *depth, + bool use_original, + BMVert **r_active_vertex, + float3 &r_face_normal); bool bmesh_node_raycast_detail(BMeshNode &node, const float3 &ray_start, diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index 57469921518..97fac4f8b7f 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -1779,7 +1779,7 @@ static void calc_mesh_intersect_data(const Span corner_verts, const int tri_index, const std::array co, const float *depth, - PBVHVertRef *r_active_vertex, + int &r_active_vertex, int &r_active_face_index, float3 &r_face_normal) @@ -1787,37 +1787,35 @@ static void calc_mesh_intersect_data(const Span corner_verts, float3 nearest_vertex_co(0.0f); normal_tri_v3(r_face_normal, co[0], co[1], co[2]); - if (r_active_vertex) { - const float3 location = ray_start + ray_normal * *depth; - for (int i = 0; i < co.size(); i++) { - /* Always assign nearest_vertex_co in the first iteration to avoid comparison against - * uninitialized values. This stores the closest vertex in the current intersecting - * triangle. */ - if (i == 0 || - len_squared_v3v3(location, co[i]) < len_squared_v3v3(location, nearest_vertex_co)) - { - nearest_vertex_co = co[i]; - r_active_vertex->i = corner_verts[corner_tris[tri_index][i]]; - r_active_face_index = face_index; - } + const float3 location = ray_start + ray_normal * *depth; + for (int i = 0; i < co.size(); i++) { + /* Always assign nearest_vertex_co in the first iteration to avoid comparison against + * uninitialized values. This stores the closest vertex in the current intersecting + * triangle. */ + if (i == 0 || + len_squared_v3v3(location, co[i]) < len_squared_v3v3(location, nearest_vertex_co)) + { + nearest_vertex_co = co[i]; + r_active_vertex = corner_verts[corner_tris[tri_index][i]]; + r_active_face_index = face_index; } } } -static bool pbvh_faces_node_raycast(const MeshNode &node, - const Span node_positions, - const Span vert_positions, - const OffsetIndices faces, - const Span corner_verts, - const Span corner_tris, - const Span hide_poly, - const float3 &ray_start, - const float3 &ray_normal, - IsectRayPrecalc *isect_precalc, - float *depth, - PBVHVertRef *r_active_vertex, - int &r_active_face_index, - float3 &r_face_normal) +bool node_raycast_mesh(const MeshNode &node, + const Span node_positions, + const Span vert_positions, + const OffsetIndices faces, + const Span corner_verts, + const Span corner_tris, + const Span hide_poly, + const float3 &ray_start, + const float3 &ray_normal, + IsectRayPrecalc *isect_precalc, + float *depth, + int &r_active_vertex, + int &r_active_face_index, + float3 &r_face_normal) { const Span face_indices = node.faces(); @@ -1886,15 +1884,14 @@ static bool pbvh_faces_node_raycast(const MeshNode &node, return hit; } -static void calc_grids_intersect_data(const CCGKey &key, - const float3 &ray_start, +static void calc_grids_intersect_data(const float3 &ray_start, const float3 &ray_normal, const int grid, const short x, const short y, const std::array co, float *depth, - PBVHVertRef *r_active_vertex, + SubdivCCGCoord &r_active_vertex, int &r_active_grid_index, float3 &r_face_normal) @@ -1902,40 +1899,35 @@ static void calc_grids_intersect_data(const CCGKey &key, float3 nearest_vertex_co; normal_quad_v3(r_face_normal, co[0], co[1], co[2], co[3]); - if (r_active_vertex) { - const float3 location = ray_start + ray_normal * *depth; + const float3 location = ray_start + ray_normal * *depth; - const int x_it[4] = {0, 1, 1, 0}; - const int y_it[4] = {1, 1, 0, 0}; + constexpr short x_it[4] = {0, 1, 1, 0}; + constexpr short y_it[4] = {1, 1, 0, 0}; - for (int i = 0; i < co.size(); i++) { - /* Always assign nearest_vertex_co in the first iteration to avoid comparison against - * uninitialized values. This stores the closest vertex in the current intersecting - * quad. */ - if (i == 0 || - len_squared_v3v3(location, co[i]) < len_squared_v3v3(location, nearest_vertex_co)) - { - copy_v3_v3(nearest_vertex_co, co[i]); - - r_active_vertex->i = key.grid_area * grid + (y + y_it[i]) * key.grid_size + (x + x_it[i]); - } + for (int i = 0; i < co.size(); i++) { + /* Always assign nearest_vertex_co in the first iteration to avoid comparison against + * uninitialized values. This stores the closest vertex in the current intersecting + * quad. */ + if (i == 0 || + len_squared_v3v3(location, co[i]) < len_squared_v3v3(location, nearest_vertex_co)) + { + copy_v3_v3(nearest_vertex_co, co[i]); + r_active_vertex = SubdivCCGCoord{grid, short(x + x_it[i]), short(y + y_it[i])}; } } - if (r_active_grid_index) { - r_active_grid_index = grid; - } + r_active_grid_index = grid; } -static bool pbvh_grids_node_raycast(const SubdivCCG &subdiv_ccg, - GridsNode &node, - const Span node_positions, - const float3 &ray_start, - const float3 &ray_normal, - const IsectRayPrecalc *isect_precalc, - float *depth, - PBVHVertRef *r_active_vertex, - int &r_active_grid_index, - float3 &r_face_normal) +bool node_raycast_grids(const SubdivCCG &subdiv_ccg, + GridsNode &node, + const Span node_positions, + const float3 &ray_start, + const float3 &ray_normal, + const IsectRayPrecalc *isect_precalc, + float *depth, + SubdivCCGCoord &r_active_vertex, + int &r_active_grid_index, + float3 &r_face_normal) { const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); const Span grids = node.grids(); @@ -1963,8 +1955,7 @@ static bool pbvh_grids_node_raycast(const SubdivCCG &subdiv_ccg, ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth)) { hit = true; - calc_grids_intersect_data(key, - ray_start, + calc_grids_intersect_data(ray_start, ray_normal, grid, x, @@ -1998,8 +1989,7 @@ static bool pbvh_grids_node_raycast(const SubdivCCG &subdiv_ccg, ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth)) { hit = true; - calc_grids_intersect_data(key, - ray_start, + calc_grids_intersect_data(ray_start, ray_normal, grid, x, @@ -2018,68 +2008,6 @@ static bool pbvh_grids_node_raycast(const SubdivCCG &subdiv_ccg, return hit; } -bool raycast_node(Tree &pbvh, - Node &node, - const Span node_positions, - bool use_origco, - const Span vert_positions, - const OffsetIndices faces, - const Span corner_verts, - const Span corner_tris, - const Span hide_poly, - const SubdivCCG *subdiv_ccg, - const float3 &ray_start, - const float3 &ray_normal, - IsectRayPrecalc *isect_precalc, - float *depth, - PBVHVertRef *r_active_vertex, - int &r_active_face_grid_index, - float3 &r_face_normal) -{ - if (node.flag_ & PBVH_FullyHidden) { - return false; - } - switch (pbvh.type()) { - case Type::Mesh: - return pbvh_faces_node_raycast(static_cast(node), - node_positions, - vert_positions, - faces, - corner_verts, - corner_tris, - hide_poly, - ray_start, - ray_normal, - isect_precalc, - depth, - r_active_vertex, - r_active_face_grid_index, - r_face_normal); - case Type::Grids: - return pbvh_grids_node_raycast(*subdiv_ccg, - static_cast(node), - node_positions, - ray_start, - ray_normal, - isect_precalc, - depth, - r_active_vertex, - r_active_face_grid_index, - r_face_normal); - case Type::BMesh: - return bmesh_node_raycast(static_cast(node), - ray_start, - ray_normal, - isect_precalc, - depth, - use_origco, - r_active_vertex, - r_face_normal); - } - BLI_assert_unreachable(); - return false; -} - void clip_ray_ortho( Tree &pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3]) { diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.cc b/source/blender/blenkernel/intern/pbvh_bmesh.cc index 9a8f2a7f87e..914eb3ea629 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.cc +++ b/source/blender/blenkernel/intern/pbvh_bmesh.cc @@ -1852,14 +1852,14 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, /************************* Called from pbvh.cc *************************/ -bool bmesh_node_raycast(BMeshNode &node, +bool node_raycast_bmesh(BMeshNode &node, const float3 &ray_start, const float3 &ray_normal, IsectRayPrecalc *isect_precalc, float *depth, bool use_original, - PBVHVertRef *r_active_vertex, - float *r_face_normal) + BMVert **r_active_vertex, + float3 &r_face_normal) { bool hit = false; float3 nearest_vertex_co(0.0f); @@ -1877,9 +1877,7 @@ bool bmesh_node_raycast(BMeshNode &node, if (ray_face_intersection_tri(ray_start, isect_precalc, cos[0], cos[1], cos[2], depth)) { hit = true; - if (r_face_normal) { - normal_tri_v3(r_face_normal, cos[0], cos[1], cos[2]); - } + normal_tri_v3(r_face_normal, cos[0], cos[1], cos[2]); if (r_active_vertex) { float3 location(0.0f); @@ -1889,7 +1887,7 @@ bool bmesh_node_raycast(BMeshNode &node, len_squared_v3v3(location, cos[i]) < len_squared_v3v3(location, nearest_vertex_co)) { copy_v3_v3(nearest_vertex_co, cos[i]); - r_active_vertex->i = intptr_t(node.orig_verts_[node.orig_tris_[tri_idx][i]]); + *r_active_vertex = node.orig_verts_[node.orig_tris_[tri_idx][i]]; } } } @@ -1909,9 +1907,7 @@ bool bmesh_node_raycast(BMeshNode &node, { hit = true; - if (r_face_normal) { - normal_tri_v3(r_face_normal, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co); - } + normal_tri_v3(r_face_normal, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co); if (r_active_vertex) { float3 location(0.0f); @@ -1921,7 +1917,7 @@ bool bmesh_node_raycast(BMeshNode &node, len_squared_v3v3(location, nearest_vertex_co)) { copy_v3_v3(nearest_vertex_co, v_tri[i]->co); - r_active_vertex->i = intptr_t(v_tri[i]); + *r_active_vertex = v_tri[i]; } } } diff --git a/source/blender/blenkernel/intern/pbvh_intern.hh b/source/blender/blenkernel/intern/pbvh_intern.hh index fa885e1401c..1c69e557ffe 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.hh +++ b/source/blender/blenkernel/intern/pbvh_intern.hh @@ -46,14 +46,6 @@ bool ray_face_nearest_tri(const float3 &ray_start, /* pbvh_bmesh.cc */ -bool bmesh_node_raycast(blender::bke::pbvh::BMeshNode &node, - const float3 &ray_start, - const float3 &ray_normal, - IsectRayPrecalc *isect_precalc, - float *depth, - bool use_original, - PBVHVertRef *r_active_vertex, - float *r_face_normal); bool bmesh_node_nearest_to_ray(blender::bke::pbvh::BMeshNode &node, const float3 &ray_start, const float3 &ray_normal, diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 9461246ab0e..ae084f33465 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2633,7 +2633,7 @@ struct SculptRaycastData { const SubdivCCG *subdiv_ccg; - PBVHVertRef active_vertex; + ActiveVert active_vertex = {}; float3 face_normal; int active_face_grid_index; @@ -4432,24 +4432,68 @@ static void sculpt_raycast_cb(blender::bke::pbvh::Node &node, SculptRaycastData } } - if (bke::pbvh::raycast_node(pbvh, - node, - origco, - use_origco, - srd.vert_positions, - srd.faces, - srd.corner_verts, - srd.corner_tris, - srd.hide_poly, - srd.subdiv_ccg, - srd.ray_start, - srd.ray_normal, - &srd.isect_precalc, - &srd.depth, - &srd.active_vertex, - srd.active_face_grid_index, - srd.face_normal)) - { + if (node.flag_ & PBVH_FullyHidden) { + return; + } + + bool hit = false; + switch (pbvh.type()) { + case bke::pbvh::Type::Mesh: { + int mesh_active_vert; + hit = bke::pbvh::node_raycast_mesh(static_cast(node), + origco, + srd.vert_positions, + srd.faces, + srd.corner_verts, + srd.corner_tris, + srd.hide_poly, + srd.ray_start, + srd.ray_normal, + &srd.isect_precalc, + &srd.depth, + mesh_active_vert, + srd.active_face_grid_index, + srd.face_normal); + if (hit) { + srd.active_vertex = mesh_active_vert; + } + break; + } + case bke::pbvh::Type::Grids: { + SubdivCCGCoord grids_active_vert; + hit = bke::pbvh::node_raycast_grids(*srd.subdiv_ccg, + static_cast(node), + origco, + srd.ray_start, + srd.ray_normal, + &srd.isect_precalc, + &srd.depth, + grids_active_vert, + srd.active_face_grid_index, + srd.face_normal); + if (hit) { + srd.active_vertex = grids_active_vert; + } + break; + } + case bke::pbvh::Type::BMesh: { + BMVert *bmesh_active_vert; + hit = bke::pbvh::node_raycast_bmesh(static_cast(node), + srd.ray_start, + srd.ray_normal, + &srd.isect_precalc, + &srd.depth, + use_origco, + &bmesh_active_vert, + srd.face_normal); + if (hit) { + srd.active_vertex = bmesh_active_vert; + } + break; + } + } + + if (hit) { srd.hit = true; *tmin = srd.depth; } @@ -4633,23 +4677,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, } /* Update the active vertex of the SculptSession. */ - const PBVHVertRef active_vertex = srd.active_vertex; - ActiveVert active_vert = {}; - switch (pbvh->type()) { - case bke::pbvh::Type::Mesh: - active_vert = int(active_vertex.i); - break; - case bke::pbvh::Type::Grids: { - const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg); - active_vert = SubdivCCGCoord::from_index(key, active_vertex.i); - break; - } - case bke::pbvh::Type::BMesh: - active_vert = reinterpret_cast(active_vertex.i); - break; - } - - ss.set_active_vert(active_vert); + ss.set_active_vert(srd.active_vertex); out->active_vertex_co = ss.active_vert_position(*depsgraph, ob); switch (pbvh->type()) {