Fix T92160: Geometry Proximity node can produce invalid values

Check when the node fails to create BVH trees, and fill the result
with zero in that case, which is most likely the expected value when
the node encounters an error. Warnings will be added with a separate
patch.
This commit is contained in:
Hans Goudey 2021-10-12 15:28:11 -05:00
parent eb56e8cd78
commit 9d03990e32
Notes: blender-bot 2023-02-14 00:44:02 +01:00
Referenced by issue #92160, Geometry Nodes: Geometry Proximity produces invalid values
1 changed files with 22 additions and 10 deletions

View File

@ -50,7 +50,7 @@ static void geo_proximity_init(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = node_storage;
}
static void calculate_mesh_proximity(const VArray<float3> &positions,
static bool calculate_mesh_proximity(const VArray<float3> &positions,
const IndexMask mask,
const Mesh &mesh,
const GeometryNodeProximityTargetType type,
@ -71,7 +71,7 @@ static void calculate_mesh_proximity(const VArray<float3> &positions,
}
if (bvh_data.tree == nullptr) {
return;
return false;
}
threading::parallel_for(mask.index_range(), 512, [&](IndexRange range) {
@ -97,18 +97,19 @@ static void calculate_mesh_proximity(const VArray<float3> &positions,
});
free_bvhtree_from_mesh(&bvh_data);
return true;
}
static void calculate_pointcloud_proximity(const VArray<float3> &positions,
static bool calculate_pointcloud_proximity(const VArray<float3> &positions,
const IndexMask mask,
const PointCloud &pointcloud,
const MutableSpan<float> r_distances,
const MutableSpan<float3> r_locations)
MutableSpan<float> r_distances,
MutableSpan<float3> r_locations)
{
BVHTreeFromPointCloud bvh_data;
BKE_bvhtree_from_pointcloud_get(&bvh_data, &pointcloud, 2);
if (bvh_data.tree == nullptr) {
return;
return false;
}
threading::parallel_for(mask.index_range(), 512, [&](IndexRange range) {
@ -136,6 +137,7 @@ static void calculate_pointcloud_proximity(const VArray<float3> &positions,
});
free_bvhtree_from_pointcloud(&bvh_data);
return true;
}
class ProximityFunction : public fn::MultiFunction {
@ -174,16 +176,23 @@ class ProximityFunction : public fn::MultiFunction {
distances.fill(FLT_MAX);
bool success = false;
if (target_.has_mesh()) {
calculate_mesh_proximity(
success |= calculate_mesh_proximity(
src_positions, mask, *target_.get_mesh_for_read(), type_, distances, positions);
}
if (target_.has_pointcloud() && type_ == GEO_NODE_PROX_TARGET_POINTS) {
calculate_pointcloud_proximity(
success |= calculate_pointcloud_proximity(
src_positions, mask, *target_.get_pointcloud_for_read(), distances, positions);
}
if (!success) {
positions.fill(float3(0));
distances.fill(0.0f);
return;
}
if (params.single_output_is_required(2, "Distance")) {
threading::parallel_for(mask.index_range(), 2048, [&](IndexRange range) {
for (const int i : range) {
@ -199,10 +208,13 @@ static void geo_node_proximity_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set_target = params.extract_input<GeometrySet>("Target");
if (!geometry_set_target.has_mesh() && !geometry_set_target.has_pointcloud()) {
auto return_default = [&]() {
params.set_output("Position", fn::make_constant_field<float3>({0.0f, 0.0f, 0.0f}));
params.set_output("Distance", fn::make_constant_field<float>(0.0f));
return;
};
if (!geometry_set_target.has_mesh() && !geometry_set_target.has_pointcloud()) {
return return_default();
}
const NodeGeometryProximity &storage = *(const NodeGeometryProximity *)params.node().storage;