Refactor: Sculpt: Remove usage of PBVHVertRef in raycast methods

Part of #118145.

This commit removes the `PBVHVertRef` abstraction and changes the last
remaining usage of it. The `raycast_node` API has been turned into a
static function and the corresponding typed APIs exposed for direct
usage.

Pull Request: https://projects.blender.org/blender/blender/pulls/127933
This commit is contained in:
Sean Kim
2024-09-21 20:17:18 +02:00
committed by Sean Kim
parent 0d8149d4ff
commit fc8a163892
6 changed files with 159 additions and 203 deletions

View File

@@ -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,

View File

@@ -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<float3> node_positions,
bool use_origco,
Span<float3> vert_positions,
OffsetIndices<int> faces,
Span<int> corner_verts,
Span<int3> corner_tris,
Span<bool> 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<float3> node_positions,
Span<float3> vert_positions,
OffsetIndices<int> faces,
Span<int> corner_verts,
Span<int3> corner_tris,
Span<bool> 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<float3> 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,

View File

@@ -1779,7 +1779,7 @@ static void calc_mesh_intersect_data(const Span<int> corner_verts,
const int tri_index,
const std::array<const float *, 3> 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<int> 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<float3> node_positions,
const Span<float3> vert_positions,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const Span<bool> 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<float3> node_positions,
const Span<float3> vert_positions,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const Span<bool> 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<int> 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<const float *, 4> 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<float3> 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<float3> 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<int> 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<float3> node_positions,
bool use_origco,
const Span<float3> vert_positions,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const Span<bool> 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<MeshNode &>(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<GridsNode &>(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<BMeshNode &>(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])
{

View File

@@ -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];
}
}
}

View File

@@ -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,

View File

@@ -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<bke::pbvh::MeshNode &>(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<bke::pbvh::GridsNode &>(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<bke::pbvh::BMeshNode &>(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<BMVert *>(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()) {