Refactor: Sculpt: Miscellaneous cleanups to node intersect/nearest loops

- Use `float3` C++ vector instead of pointers
- Return directly instead of using temporary boolean variable
- Use separate loops for "original positions" case to simplify hot loops
This commit is contained in:
Hans Goudey
2024-09-04 11:07:18 -04:00
parent 40ae2d7df6
commit e5988cf912
5 changed files with 365 additions and 284 deletions

View File

@@ -239,13 +239,13 @@ void free(std::unique_ptr<Tree> &pbvh);
void raycast(Tree &pbvh,
FunctionRef<void(Node &node, float *tmin)> cb,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
bool original);
bool raycast_node(Tree &pbvh,
Node &node,
const float (*origco)[3],
Span<float3> node_positions,
bool use_origco,
Span<float3> vert_positions,
Span<int> corner_verts,
@@ -253,8 +253,8 @@ bool raycast_node(Tree &pbvh,
Span<int> corner_tri_faces,
Span<bool> hide_poly,
const SubdivCCG *subdiv_ccg,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
IsectRayPrecalc *isect_precalc,
float *depth,
PBVHVertRef *active_vertex,
@@ -262,7 +262,7 @@ bool raycast_node(Tree &pbvh,
float *face_normal);
bool bmesh_node_raycast_detail(BMeshNode &node,
const float ray_start[3],
const float3 &ray_start,
IsectRayPrecalc *isect_precalc,
float *depth,
float *r_edge_length);
@@ -282,13 +282,13 @@ void clip_ray_ortho(
void find_nearest_to_ray(Tree &pbvh,
const FunctionRef<void(Node &node, float *tmin)> fn,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
bool original);
bool find_nearest_to_ray_node(Tree &pbvh,
Node &node,
const float (*origco)[3],
Span<float3> node_positions,
bool use_origco,
Span<float3> vert_positions,
Span<int> corner_verts,

View File

@@ -1875,8 +1875,8 @@ static bool ray_aabb_intersect(Node &node, const RaycastData &rcd)
void raycast(Tree &pbvh,
const FunctionRef<void(Node &node, float *tmin)> hit_fn,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
bool original)
{
RaycastData rcd;
@@ -1888,12 +1888,12 @@ void raycast(Tree &pbvh,
pbvh, [&](Node &node) { return ray_aabb_intersect(node, rcd); }, hit_fn);
}
bool ray_face_intersection_quad(const float ray_start[3],
bool ray_face_intersection_quad(const float3 &ray_start,
IsectRayPrecalc *isect_precalc,
const float t0[3],
const float t1[3],
const float t2[3],
const float t3[3],
const float3 &t0,
const float3 &t1,
const float3 &t2,
const float3 &t3,
float *depth)
{
float depth_test;
@@ -1910,11 +1910,11 @@ bool ray_face_intersection_quad(const float ray_start[3],
return false;
}
bool ray_face_intersection_tri(const float ray_start[3],
bool ray_face_intersection_tri(const float3 &ray_start,
IsectRayPrecalc *isect_precalc,
const float t0[3],
const float t1[3],
const float t2[3],
const float3 &t0,
const float3 &t1,
const float3 &t2,
float *depth)
{
float depth_test;
@@ -1930,18 +1930,19 @@ bool ray_face_intersection_tri(const float ray_start[3],
/* Take advantage of the fact we know this won't be an intersection.
* Just handle ray-tri edges. */
static float dist_squared_ray_to_tri_v3_fast(const float ray_origin[3],
const float ray_direction[3],
const float v0[3],
const float v1[3],
const float v2[3],
float r_point[3],
static float dist_squared_ray_to_tri_v3_fast(const float3 &ray_origin,
const float3 &ray_direction,
const float3 &v0,
const float3 &v1,
const float3 &v2,
float3 &r_point,
float *r_depth)
{
const float *tri[3] = {v0, v1, v2};
float dist_sq_best = FLT_MAX;
for (int i = 0, j = 2; i < 3; j = i++) {
float point_test[3], depth_test = FLT_MAX;
float3 point_test;
float depth_test = FLT_MAX;
const float dist_sq_test = dist_squared_ray_to_seg_v3(
ray_origin, ray_direction, tri[i], tri[j], point_test, &depth_test);
if (dist_sq_test < dist_sq_best || i == 0) {
@@ -1953,17 +1954,18 @@ static float dist_squared_ray_to_tri_v3_fast(const float ray_origin[3],
return dist_sq_best;
}
bool ray_face_nearest_quad(const float ray_start[3],
const float ray_normal[3],
const float t0[3],
const float t1[3],
const float t2[3],
const float t3[3],
bool ray_face_nearest_quad(const float3 &ray_start,
const float3 &ray_normal,
const float3 &t0,
const float3 &t1,
const float3 &t2,
const float3 &t3,
float *depth,
float *dist_sq)
{
float dist_sq_test;
float co[3], depth_test;
float3 co;
float depth_test;
if ((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
@@ -1982,16 +1984,17 @@ bool ray_face_nearest_quad(const float ray_start[3],
return false;
}
bool ray_face_nearest_tri(const float ray_start[3],
const float ray_normal[3],
const float t0[3],
const float t1[3],
const float t2[3],
bool ray_face_nearest_tri(const float3 &ray_start,
const float3 &ray_normal,
const float3 &t0,
const float3 &t1,
const float3 &t2,
float *depth,
float *dist_sq)
{
float dist_sq_test;
float co[3], depth_test;
float3 co;
float depth_test;
if ((dist_sq_test = dist_squared_ray_to_tri_v3_fast(
ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)
@@ -2004,71 +2007,109 @@ bool ray_face_nearest_tri(const float ray_start[3],
return false;
}
static void calc_mesh_intersect_data(const Span<int> corner_verts,
const Span<int3> corner_tris,
const Span<int> corner_tri_faces,
const float3 &ray_start,
const float3 &ray_normal,
const int tri_index,
const std::array<const float *, 3> co,
float *depth,
PBVHVertRef *r_active_vertex,
int *r_active_face_index,
float *r_face_normal)
{
float nearest_vertex_co[3] = {0.0f};
if (r_face_normal) {
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 j = 0; j < 3; j++) {
/* 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 (j == 0 ||
len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co))
{
copy_v3_v3(nearest_vertex_co, co[j]);
r_active_vertex->i = corner_verts[corner_tris[tri_index][j]];
*r_active_face_index = corner_tri_faces[tri_index];
}
}
}
}
static bool pbvh_faces_node_raycast(const MeshNode &node,
const float (*origco)[3],
const Span<float3> node_positions,
const Span<float3> vert_positions,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const Span<int> corner_tri_faces,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
IsectRayPrecalc *isect_precalc,
float *depth,
PBVHVertRef *r_active_vertex,
int *r_active_face_index,
float *r_face_normal)
{
using namespace blender;
bool hit = false;
float nearest_vertex_co[3] = {0.0f};
const Span<int> tris = node_tri_indices(node);
for (const int i : tris.index_range()) {
const int tri_i = tris[i];
const int3 &tri = corner_tris[tri_i];
const int3 face_verts = node.face_vert_indices_[i];
if (!hide_poly.is_empty() && hide_poly[corner_tri_faces[tri_i]]) {
continue;
}
const float *co[3];
if (origco) {
/* Intersect with backed up original coordinates. */
co[0] = origco[face_verts[0]];
co[1] = origco[face_verts[1]];
co[2] = origco[face_verts[2]];
}
else {
/* intersect with current coordinates */
co[0] = vert_positions[corner_verts[tri[0]]];
co[1] = vert_positions[corner_verts[tri[1]]];
co[2] = vert_positions[corner_verts[tri[2]]];
}
if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) {
hit = true;
if (r_face_normal) {
normal_tri_v3(r_face_normal, co[0], co[1], co[2]);
bool hit = false;
if (node_positions.is_empty()) {
for (const int i : tris.index_range()) {
const int tri_i = tris[i];
const int3 &tri = corner_tris[tri_i];
if (!hide_poly.is_empty() && hide_poly[corner_tri_faces[tri_i]]) {
continue;
}
if (r_active_vertex) {
float location[3] = {0.0f};
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
for (int j = 0; j < 3; j++) {
/* 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 (j == 0 ||
len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co))
{
copy_v3_v3(nearest_vertex_co, co[j]);
r_active_vertex->i = corner_verts[tri[j]];
*r_active_face_index = corner_tri_faces[tri_i];
}
}
const std::array<const float *, 3> co{{vert_positions[corner_verts[tri[0]]],
vert_positions[corner_verts[tri[1]]],
vert_positions[corner_verts[tri[2]]]}};
if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) {
hit = true;
calc_mesh_intersect_data(corner_verts,
corner_tris,
corner_tri_faces,
ray_start,
ray_normal,
tri_i,
co,
depth,
r_active_vertex,
r_active_face_index,
r_face_normal);
}
}
}
else {
for (const int i : tris.index_range()) {
const int tri_i = tris[i];
const int3 face_verts = node.face_vert_indices_[i];
if (!hide_poly.is_empty() && hide_poly[corner_tri_faces[tri_i]]) {
continue;
}
const std::array<const float *, 3> co{{node_positions[face_verts[0]],
node_positions[face_verts[1]],
node_positions[face_verts[2]]}};
if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) {
hit = true;
calc_mesh_intersect_data(corner_verts,
corner_tris,
corner_tri_faces,
ray_start,
ray_normal,
tri_i,
co,
depth,
r_active_vertex,
r_active_face_index,
r_face_normal);
}
}
}
@@ -2076,11 +2117,53 @@ static bool pbvh_faces_node_raycast(const MeshNode &node,
return hit;
}
static void calc_grids_intersect_data(const CCGKey &key,
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,
int *r_active_grid_index,
float *r_face_normal)
{
float3 nearest_vertex_co;
if (r_face_normal) {
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 int x_it[4] = {0, 1, 1, 0};
const int y_it[4] = {1, 1, 0, 0};
for (int j = 0; j < 4; j++) {
/* 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 (j == 0 ||
len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co))
{
copy_v3_v3(nearest_vertex_co, co[j]);
r_active_vertex->i = key.grid_area * grid + (y + y_it[j]) * key.grid_size + (x + x_it[j]);
}
}
}
if (r_active_grid_index) {
*r_active_grid_index = grid;
}
}
static bool pbvh_grids_node_raycast(const SubdivCCG &subdiv_ccg,
GridsNode &node,
const float (*origco)[3],
const float ray_start[3],
const float ray_normal[3],
const Span<float3> node_positions,
const float3 &ray_start,
const float3 &ray_normal,
IsectRayPrecalc *isect_precalc,
float *depth,
PBVHVertRef *r_active_vertex,
@@ -2089,77 +2172,79 @@ static bool pbvh_grids_node_raycast(const SubdivCCG &subdiv_ccg,
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<int> grids = node_grid_indices(node);
const int gridsize = key.grid_size;
const int grid_size = key.grid_size;
bool hit = false;
float nearest_vertex_co[3] = {0.0};
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
const Span<CCGElem *> elems = subdiv_ccg.grids;
for (const int grid : grids) {
CCGElem *elem = elems[grid];
if (node_positions.is_empty()) {
for (const int grid : grids) {
CCGElem *elem = elems[grid];
for (int y = 0; y < gridsize - 1; y++) {
for (int x = 0; x < gridsize - 1; x++) {
/* check if grid face is hidden */
if (!grid_hidden.is_empty()) {
if (paint_is_grid_face_hidden(grid_hidden[grid], gridsize, x, y)) {
continue;
}
}
const float *co[4];
if (origco) {
co[0] = origco[(y + 1) * gridsize + x];
co[1] = origco[(y + 1) * gridsize + x + 1];
co[2] = origco[y * gridsize + x + 1];
co[3] = origco[y * gridsize + x];
}
else {
co[0] = CCG_grid_elem_co(key, elem, x, y + 1);
co[1] = CCG_grid_elem_co(key, elem, x + 1, y + 1);
co[2] = CCG_grid_elem_co(key, elem, x + 1, y);
co[3] = CCG_grid_elem_co(key, elem, x, y);
}
if (ray_face_intersection_quad(
ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
{
hit = true;
if (r_face_normal) {
normal_quad_v3(r_face_normal, co[0], co[1], co[2], co[3]);
}
if (r_active_vertex) {
float location[3] = {0.0};
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
const int x_it[4] = {0, 1, 1, 0};
const int y_it[4] = {1, 1, 0, 0};
for (int j = 0; j < 4; j++) {
/* 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 (j == 0 || len_squared_v3v3(location, co[j]) <
len_squared_v3v3(location, nearest_vertex_co))
{
copy_v3_v3(nearest_vertex_co, co[j]);
r_active_vertex->i = key.grid_area * grid + (y + y_it[j]) * key.grid_size +
(x + x_it[j]);
}
for (const short y : IndexRange(grid_size - 1)) {
for (const short x : IndexRange(grid_size - 1)) {
if (!grid_hidden.is_empty()) {
if (paint_is_grid_face_hidden(grid_hidden[grid], grid_size, x, y)) {
continue;
}
}
if (r_active_grid_index) {
*r_active_grid_index = grid;
const std::array<const float *, 4> co{{CCG_grid_elem_co(key, elem, x, y + 1),
CCG_grid_elem_co(key, elem, x + 1, y + 1),
CCG_grid_elem_co(key, elem, x + 1, y),
CCG_grid_elem_co(key, elem, x, y)}};
if (ray_face_intersection_quad(
ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
{
hit = true;
calc_grids_intersect_data(key,
ray_start,
ray_normal,
grid,
x,
y,
co,
depth,
r_active_vertex,
r_active_grid_index,
r_face_normal);
}
}
}
}
if (origco) {
origco += gridsize * gridsize;
}
else {
for (const int i : grids.index_range()) {
const int grid = grids[i];
const Span<float3> grid_positions = node_positions.slice(key.grid_area * i, key.grid_area);
for (const short y : IndexRange(grid_size - 1)) {
for (const short x : IndexRange(grid_size - 1)) {
if (!grid_hidden.is_empty()) {
if (paint_is_grid_face_hidden(grid_hidden[grid], grid_size, x, y)) {
continue;
}
}
const std::array<const float *, 4> co{grid_positions[(y + 1) * grid_size + x],
grid_positions[(y + 1) * grid_size + x + 1],
grid_positions[y * grid_size + x + 1],
grid_positions[y * grid_size + x]};
if (ray_face_intersection_quad(
ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth))
{
hit = true;
calc_grids_intersect_data(key,
ray_start,
ray_normal,
grid,
x,
y,
co,
depth,
r_active_vertex,
r_active_grid_index,
r_face_normal);
}
}
}
}
}
@@ -2168,7 +2253,7 @@ static bool pbvh_grids_node_raycast(const SubdivCCG &subdiv_ccg,
bool raycast_node(Tree &pbvh,
Node &node,
const float (*origco)[3],
const Span<float3> node_positions,
bool use_origco,
const Span<float3> vert_positions,
const Span<int> corner_verts,
@@ -2176,24 +2261,21 @@ bool raycast_node(Tree &pbvh,
const Span<int> corner_tri_faces,
const Span<bool> hide_poly,
const SubdivCCG *subdiv_ccg,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
IsectRayPrecalc *isect_precalc,
float *depth,
PBVHVertRef *active_vertex,
int *active_face_grid_index,
float *face_normal)
{
bool hit = false;
if (node.flag_ & PBVH_FullyHidden) {
return false;
}
switch (pbvh.type()) {
case Type::Mesh:
hit |= pbvh_faces_node_raycast(static_cast<MeshNode &>(node),
origco,
return pbvh_faces_node_raycast(static_cast<MeshNode &>(node),
node_positions,
vert_positions,
corner_verts,
corner_tris,
@@ -2206,11 +2288,10 @@ bool raycast_node(Tree &pbvh,
active_vertex,
active_face_grid_index,
face_normal);
break;
case Type::Grids:
hit |= pbvh_grids_node_raycast(*subdiv_ccg,
return pbvh_grids_node_raycast(*subdiv_ccg,
static_cast<GridsNode &>(node),
origco,
node_positions,
ray_start,
ray_normal,
isect_precalc,
@@ -2218,20 +2299,18 @@ bool raycast_node(Tree &pbvh,
active_vertex,
active_face_grid_index,
face_normal);
break;
case Type::BMesh:
hit = bmesh_node_raycast(static_cast<BMeshNode &>(node),
ray_start,
ray_normal,
isect_precalc,
depth,
use_origco,
active_vertex,
face_normal);
break;
return bmesh_node_raycast(static_cast<BMeshNode &>(node),
ray_start,
ray_normal,
isect_precalc,
depth,
use_origco,
active_vertex,
face_normal);
}
return hit;
BLI_assert_unreachable();
return false;
}
void clip_ray_ortho(
@@ -2348,8 +2427,8 @@ static bool nearest_to_ray_aabb_dist_sq(Node *node,
void find_nearest_to_ray(Tree &pbvh,
const FunctionRef<void(Node &node, float *tmin)> fn,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
const bool original)
{
const DistRayAABB_Precalc ray_dist_precalc = dist_squared_ray_to_aabb_v3_precalc(ray_start,
@@ -2362,41 +2441,27 @@ void find_nearest_to_ray(Tree &pbvh,
}
static bool pbvh_faces_node_nearest_to_ray(const MeshNode &node,
const float (*origco)[3],
const Span<float3> node_positions,
const Span<float3> vert_positions,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const Span<int> corner_tri_faces,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
float *depth,
float *dist_sq)
{
bool hit = false;
const Span<int> tris = node_tri_indices(node);
for (const int i : tris.index_range()) {
const int tri_i = tris[i];
const int3 &corner_tri = corner_tris[tri_i];
const int3 face_verts = node.face_vert_indices_[i];
if (!hide_poly.is_empty() && hide_poly[corner_tri_faces[tri_i]]) {
continue;
}
if (origco) {
/* Intersect with backed-up original coordinates. */
hit |= ray_face_nearest_tri(ray_start,
ray_normal,
origco[face_verts[0]],
origco[face_verts[1]],
origco[face_verts[2]],
depth,
dist_sq);
}
else {
/* intersect with current coordinates */
bool hit = false;
if (node_positions.is_empty()) {
for (const int i : tris.index_range()) {
const int tri_i = tris[i];
const int3 &corner_tri = corner_tris[tri_i];
if (!hide_poly.is_empty() && hide_poly[corner_tri_faces[tri_i]]) {
continue;
}
hit |= ray_face_nearest_tri(ray_start,
ray_normal,
vert_positions[corner_verts[corner_tri[0]]],
@@ -2406,13 +2471,29 @@ static bool pbvh_faces_node_nearest_to_ray(const MeshNode &node,
dist_sq);
}
}
else {
for (const int i : tris.index_range()) {
const int tri_i = tris[i];
const int3 face_verts = node.face_vert_indices_[i];
if (!hide_poly.is_empty() && hide_poly[corner_tri_faces[tri_i]]) {
continue;
}
hit |= ray_face_nearest_tri(ray_start,
ray_normal,
node_positions[face_verts[0]],
node_positions[face_verts[1]],
node_positions[face_verts[2]],
depth,
dist_sq);
}
}
return hit;
}
static bool pbvh_grids_node_nearest_to_ray(const SubdivCCG &subdiv_ccg,
GridsNode &node,
const float (*origco)[3],
const Span<float3> node_positions,
const float ray_start[3],
const float ray_normal[3],
float *depth,
@@ -2420,34 +2501,21 @@ static bool pbvh_grids_node_nearest_to_ray(const SubdivCCG &subdiv_ccg,
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<int> grids = node_grid_indices(node);
const int gridsize = key.grid_size;
bool hit = false;
const int grid_size = key.grid_size;
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
const Span<CCGElem *> elems = subdiv_ccg.grids;
for (const int grid : grids) {
CCGElem *elem = elems[grid];
for (int y = 0; y < gridsize - 1; y++) {
for (int x = 0; x < gridsize - 1; x++) {
/* check if grid face is hidden */
if (!grid_hidden.is_empty()) {
if (paint_is_grid_face_hidden(grid_hidden[grid], gridsize, x, y)) {
continue;
bool hit = false;
if (node_positions.is_empty()) {
for (const int grid : grids) {
CCGElem *elem = elems[grid];
for (const short y : IndexRange(grid_size - 1)) {
for (const short x : IndexRange(grid_size - 1)) {
if (!grid_hidden.is_empty()) {
if (paint_is_grid_face_hidden(grid_hidden[grid], grid_size, x, y)) {
continue;
}
}
}
if (origco) {
hit |= ray_face_nearest_quad(ray_start,
ray_normal,
origco[y * gridsize + x],
origco[y * gridsize + x + 1],
origco[(y + 1) * gridsize + x + 1],
origco[(y + 1) * gridsize + x],
depth,
dist_sq);
}
else {
hit |= ray_face_nearest_quad(ray_start,
ray_normal,
CCG_grid_elem_co(key, elem, x, y),
@@ -2459,9 +2527,28 @@ static bool pbvh_grids_node_nearest_to_ray(const SubdivCCG &subdiv_ccg,
}
}
}
if (origco) {
origco += gridsize * gridsize;
}
else {
for (const int i : grids.index_range()) {
const int grid = grids[i];
const Span<float3> grid_positions = node_positions.slice(key.grid_area * i, key.grid_area);
for (const short y : IndexRange(grid_size - 1)) {
for (const short x : IndexRange(grid_size - 1)) {
if (!grid_hidden.is_empty()) {
if (paint_is_grid_face_hidden(grid_hidden[grid], grid_size, x, y)) {
continue;
}
}
hit |= ray_face_nearest_quad(ray_start,
ray_normal,
grid_positions[y * grid_size + x],
grid_positions[y * grid_size + x + 1],
grid_positions[(y + 1) * grid_size + x + 1],
grid_positions[(y + 1) * grid_size + x],
depth,
dist_sq);
}
}
}
}
@@ -2470,7 +2557,7 @@ static bool pbvh_grids_node_nearest_to_ray(const SubdivCCG &subdiv_ccg,
bool find_nearest_to_ray_node(Tree &pbvh,
Node &node,
const float (*origco)[3],
const Span<float3> node_positions,
bool use_origco,
const Span<float3> vert_positions,
const Span<int> corner_verts,
@@ -2483,16 +2570,13 @@ bool find_nearest_to_ray_node(Tree &pbvh,
float *depth,
float *dist_sq)
{
bool hit = false;
if (node.flag_ & PBVH_FullyHidden) {
return false;
}
switch (pbvh.type()) {
case Type::Mesh:
hit |= pbvh_faces_node_nearest_to_ray(static_cast<MeshNode &>(node),
origco,
return pbvh_faces_node_nearest_to_ray(static_cast<MeshNode &>(node),
node_positions,
vert_positions,
corner_verts,
corner_tris,
@@ -2502,23 +2586,20 @@ bool find_nearest_to_ray_node(Tree &pbvh,
ray_normal,
depth,
dist_sq);
break;
case Type::Grids:
hit |= pbvh_grids_node_nearest_to_ray(*subdiv_ccg,
return pbvh_grids_node_nearest_to_ray(*subdiv_ccg,
static_cast<GridsNode &>(node),
origco,
node_positions,
ray_start,
ray_normal,
depth,
dist_sq);
break;
case Type::BMesh:
hit = bmesh_node_nearest_to_ray(
return bmesh_node_nearest_to_ray(
static_cast<BMeshNode &>(node), ray_start, ray_normal, depth, dist_sq, use_origco);
break;
}
return hit;
BLI_assert_unreachable();
return false;
}
enum PlaneAABBIsect {

View File

@@ -1830,8 +1830,8 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
/************************* Called from pbvh.cc *************************/
bool bmesh_node_raycast(BMeshNode &node,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
IsectRayPrecalc *isect_precalc,
float *depth,
bool use_original,
@@ -1911,7 +1911,7 @@ bool bmesh_node_raycast(BMeshNode &node,
}
bool bmesh_node_raycast_detail(BMeshNode &node,
const float ray_start[3],
const float3 &ray_start,
IsectRayPrecalc *isect_precalc,
float *depth,
float *r_edge_length)
@@ -1954,8 +1954,8 @@ bool bmesh_node_raycast_detail(BMeshNode &node,
}
bool bmesh_node_nearest_to_ray(BMeshNode &node,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
float *depth,
float *dist_sq,
bool use_original)

View File

@@ -14,49 +14,49 @@
namespace blender::bke::pbvh {
bool ray_face_intersection_quad(const float ray_start[3],
bool ray_face_intersection_quad(const float3 &ray_start,
IsectRayPrecalc *isect_precalc,
const float t0[3],
const float t1[3],
const float t2[3],
const float t3[3],
const float3 &t0,
const float3 &t1,
const float3 &t2,
const float3 &t3,
float *depth);
bool ray_face_intersection_tri(const float ray_start[3],
bool ray_face_intersection_tri(const float3 &ray_start,
IsectRayPrecalc *isect_precalc,
const float t0[3],
const float t1[3],
const float t2[3],
const float3 &t0,
const float3 &t1,
const float3 &t2,
float *depth);
bool ray_face_nearest_quad(const float ray_start[3],
const float ray_normal[3],
const float t0[3],
const float t1[3],
const float t2[3],
const float t3[3],
bool ray_face_nearest_quad(const float3 &ray_start,
const float3 &ray_normal,
const float3 &t0,
const float3 &t1,
const float3 &t2,
const float3 &t3,
float *r_depth,
float *r_dist_sq);
bool ray_face_nearest_tri(const float ray_start[3],
const float ray_normal[3],
const float t0[3],
const float t1[3],
const float t2[3],
bool ray_face_nearest_tri(const float3 &ray_start,
const float3 &ray_normal,
const float3 &t0,
const float3 &t1,
const float3 &t2,
float *r_depth,
float *r_dist_sq);
/* pbvh_bmesh.cc */
bool bmesh_node_raycast(blender::bke::pbvh::BMeshNode &node,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
IsectRayPrecalc *isect_precalc,
float *dist,
bool use_original,
PBVHVertRef *r_active_vertex,
float *r_face_normal);
bool bmesh_node_nearest_to_ray(blender::bke::pbvh::BMeshNode &node,
const float ray_start[3],
const float ray_normal[3],
const float3 &ray_start,
const float3 &ray_normal,
float *depth,
float *dist_sq,
bool use_original);

View File

@@ -4761,18 +4761,18 @@ static void sculpt_raycast_cb(blender::bke::pbvh::Node &node, SculptRaycastData
if (BKE_pbvh_node_get_tmin(&node) >= *tmin) {
return;
}
const float(*origco)[3] = nullptr;
bool use_origco = false;
Span<float3> origco;
if (srd.original && srd.ss->cache) {
if (srd.ss->pbvh->type() == bke::pbvh::Type::BMesh) {
use_origco = true;
}
else {
/* Intersect with coordinates from before we started stroke. */
const undo::Node *unode = undo::get_node(&node, undo::Type::Position);
origco = (unode) ? reinterpret_cast<const float(*)[3]>(unode->position.data()) : nullptr;
use_origco = origco ? true : false;
if (const undo::Node *unode = undo::get_node(&node, undo::Type::Position)) {
use_origco = true;
origco = unode->position.as_span();
}
}
}
@@ -4808,18 +4808,18 @@ static void sculpt_find_nearest_to_ray_cb(blender::bke::pbvh::Node &node,
if (BKE_pbvh_node_get_tmin(&node) >= *tmin) {
return;
}
const float(*origco)[3] = nullptr;
bool use_origco = false;
Span<float3> origco;
if (srd.original && srd.ss->cache) {
if (srd.ss->pbvh->type() == bke::pbvh::Type::BMesh) {
use_origco = true;
}
else {
/* Intersect with coordinates from before we started stroke. */
const undo::Node *unode = undo::get_node(&node, undo::Type::Position);
origco = (unode) ? reinterpret_cast<const float(*)[3]>(unode->position.data()) : nullptr;
use_origco = origco ? true : false;
if (const undo::Node *unode = undo::get_node(&node, undo::Type::Position)) {
use_origco = true;
origco = unode->position.as_span();
}
}
}