Fix T94113: Local view + Geometry Nodes is broken for instances
`GeometrySet::compute_boundbox_without_instances` may not initialize min max in some cases such as meshes without vertices. This can result in a Bounding Box with impossible dimensions (min=FLT_MAX, max=-FLT_MAX). So repeat the same solution seen in `BKE_object_boundbox_calc_from_mesh` and set boundbox values to zero. Reviewed By: HooglyBoogly Differential Revision: https://developer.blender.org/D13664
This commit is contained in:
parent
d786b48aab
commit
1c7d7c9150
Notes:
blender-bot
2023-02-14 01:52:41 +01:00
Referenced by issue #94113, Local view + Geometry Nodes is broken for instances
|
@ -372,7 +372,7 @@ struct GeometrySet {
|
|||
*/
|
||||
blender::Vector<const GeometryComponent *> get_components_for_read() const;
|
||||
|
||||
void compute_boundbox_without_instances(blender::float3 *r_min, blender::float3 *r_max) const;
|
||||
bool compute_boundbox_without_instances(blender::float3 *r_min, blender::float3 *r_max) const;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set);
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ void *BKE_pointcloud_add_default(struct Main *bmain, const char *name);
|
|||
struct PointCloud *BKE_pointcloud_new_nomain(const int totpoint);
|
||||
|
||||
struct BoundBox *BKE_pointcloud_boundbox_get(struct Object *ob);
|
||||
void BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3], float r_max[3]);
|
||||
bool BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3], float r_max[3]);
|
||||
|
||||
void BKE_pointcloud_update_customdata_pointers(struct PointCloud *pointcloud);
|
||||
bool BKE_pointcloud_customdata_required(struct PointCloud *pointcloud,
|
||||
|
|
|
@ -686,7 +686,7 @@ struct CurveEval {
|
|||
|
||||
void translate(const blender::float3 &translation);
|
||||
void transform(const blender::float4x4 &matrix);
|
||||
void bounds_min_max(blender::float3 &min, blender::float3 &max, const bool use_evaluated) const;
|
||||
bool bounds_min_max(blender::float3 &min, blender::float3 &max, const bool use_evaluated) const;
|
||||
|
||||
/**
|
||||
* Return the start indices for each of the curve spline's control points, if they were part
|
||||
|
|
|
@ -100,11 +100,17 @@ void CurveEval::transform(const float4x4 &matrix)
|
|||
}
|
||||
}
|
||||
|
||||
void CurveEval::bounds_min_max(float3 &min, float3 &max, const bool use_evaluated) const
|
||||
bool CurveEval::bounds_min_max(float3 &min, float3 &max, const bool use_evaluated) const
|
||||
{
|
||||
bool have_minmax = false;
|
||||
for (const SplinePtr &spline : this->splines()) {
|
||||
spline->bounds_min_max(min, max, use_evaluated);
|
||||
if (spline->size()) {
|
||||
spline->bounds_min_max(min, max, use_evaluated);
|
||||
have_minmax = true;
|
||||
}
|
||||
}
|
||||
|
||||
return have_minmax;
|
||||
}
|
||||
|
||||
float CurveEval::total_length() const
|
||||
|
|
|
@ -183,25 +183,27 @@ Vector<const GeometryComponent *> GeometrySet::get_components_for_read() const
|
|||
return components;
|
||||
}
|
||||
|
||||
void GeometrySet::compute_boundbox_without_instances(float3 *r_min, float3 *r_max) const
|
||||
bool GeometrySet::compute_boundbox_without_instances(float3 *r_min, float3 *r_max) const
|
||||
{
|
||||
bool have_minmax = false;
|
||||
const PointCloud *pointcloud = this->get_pointcloud_for_read();
|
||||
if (pointcloud != nullptr) {
|
||||
BKE_pointcloud_minmax(pointcloud, *r_min, *r_max);
|
||||
have_minmax |= BKE_pointcloud_minmax(pointcloud, *r_min, *r_max);
|
||||
}
|
||||
const Mesh *mesh = this->get_mesh_for_read();
|
||||
if (mesh != nullptr) {
|
||||
BKE_mesh_wrapper_minmax(mesh, *r_min, *r_max);
|
||||
have_minmax |= BKE_mesh_wrapper_minmax(mesh, *r_min, *r_max);
|
||||
}
|
||||
const Volume *volume = this->get_volume_for_read();
|
||||
if (volume != nullptr) {
|
||||
BKE_volume_min_max(volume, *r_min, *r_max);
|
||||
have_minmax |= BKE_volume_min_max(volume, *r_min, *r_max);
|
||||
}
|
||||
const CurveEval *curve = this->get_curve_for_read();
|
||||
if (curve != nullptr) {
|
||||
/* Using the evaluated positions is somewhat arbitrary, but it is probably expected. */
|
||||
curve->bounds_min_max(*r_min, *r_max, true);
|
||||
have_minmax |= curve->bounds_min_max(*r_min, *r_max, true);
|
||||
}
|
||||
return have_minmax;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set)
|
||||
|
|
|
@ -3918,11 +3918,15 @@ bool BKE_object_boundbox_calc_from_evaluated_geometry(Object *ob)
|
|||
INIT_MINMAX(min, max);
|
||||
|
||||
if (ob->runtime.geometry_set_eval) {
|
||||
ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max);
|
||||
if (!ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max)) {
|
||||
zero_v3(min);
|
||||
zero_v3(max);
|
||||
}
|
||||
}
|
||||
else if (const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob)) {
|
||||
if (!BKE_mesh_wrapper_minmax(mesh_eval, min, max)) {
|
||||
return false;
|
||||
zero_v3(min);
|
||||
zero_v3(max);
|
||||
}
|
||||
}
|
||||
else if (ob->runtime.curve_cache) {
|
||||
|
|
|
@ -261,8 +261,12 @@ PointCloud *BKE_pointcloud_new_nomain(const int totpoint)
|
|||
return pointcloud;
|
||||
}
|
||||
|
||||
void BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3], float r_max[3])
|
||||
bool BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3], float r_max[3])
|
||||
{
|
||||
if (!pointcloud->totpoint) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float(*pointcloud_co)[3] = pointcloud->co;
|
||||
float *pointcloud_radius = pointcloud->radius;
|
||||
for (int a = 0; a < pointcloud->totpoint; a++) {
|
||||
|
@ -273,6 +277,7 @@ void BKE_pointcloud_minmax(const struct PointCloud *pointcloud, float r_min[3],
|
|||
DO_MIN(co_min, r_min);
|
||||
DO_MAX(co_max, r_max);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
|
||||
|
|
Loading…
Reference in New Issue