Refactor: Use C++ bounds corners function

Remove the last uses of `BKE_boundbox_init_from_minmax` in
favor of the newer `bounds::corners`. Besides clearer naming
and better ergonomics, it's also inline-able which seems to be a
good thing for such a simple function.

In order to get the same behavior as before I changed the
C++ bounds function to give the same vertex order as the
older function.

Pull Request: https://projects.blender.org/blender/blender/pulls/140401
This commit is contained in:
Hans Goudey
2025-06-16 15:49:14 +02:00
committed by Hans Goudey
parent 84212bae4b
commit c16ee2c939
15 changed files with 78 additions and 87 deletions

View File

@@ -335,14 +335,6 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
*/
void BKE_object_where_is_calc_mat4(const Object *ob, float r_obmat[4][4]);
/* Possibly belong in its own module? */
void BKE_boundbox_init_from_minmax(BoundBox *bb, const float min[3], const float max[3]);
void BKE_boundbox_minmax(const BoundBox &bb,
const blender::float4x4 &matrix,
blender::float3 &r_min,
blender::float3 &r_max);
/**
* Retrieve the bounds of the object's evaluated geometry. This is important because it includes
* all geometry component types created during evaluation rather than just #Object::data. This

View File

@@ -17,6 +17,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_bounds.hh"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
@@ -3172,9 +3173,9 @@ void BKE_pchan_minmax(const Object *ob,
pchan->custom_translation[1],
pchan->custom_translation[2]);
mul_m4_series(mat.ptr(), tmp.ptr(), rmat.ptr(), smat.ptr());
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, bb_custom->min, bb_custom->max);
BKE_boundbox_minmax(bb, mat, r_min, r_max);
const Bounds tranformed_bounds = bounds::transform_bounds(mat, *bb_custom);
r_min = math::min(tranformed_bounds.min, r_min);
r_max = math::max(tranformed_bounds.max, r_max);
}
else {
minmax_v3v3_v3(r_min, r_max, pchan_tx->pose_head);

View File

@@ -48,6 +48,7 @@
#include "DNA_shader_fx_types.h"
#include "DNA_view3d_types.h"
#include "BLI_bounds.hh"
#include "BLI_kdtree.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
@@ -3507,26 +3508,6 @@ void BKE_object_apply_parent_inverse(Object *ob)
/** \name Object Bounding Box API
* \{ */
void BKE_boundbox_init_from_minmax(BoundBox *bb, const float min[3], const float max[3])
{
bb->vec[0][0] = bb->vec[1][0] = bb->vec[2][0] = bb->vec[3][0] = min[0];
bb->vec[4][0] = bb->vec[5][0] = bb->vec[6][0] = bb->vec[7][0] = max[0];
bb->vec[0][1] = bb->vec[1][1] = bb->vec[4][1] = bb->vec[5][1] = min[1];
bb->vec[2][1] = bb->vec[3][1] = bb->vec[6][1] = bb->vec[7][1] = max[1];
bb->vec[0][2] = bb->vec[3][2] = bb->vec[4][2] = bb->vec[7][2] = min[2];
bb->vec[1][2] = bb->vec[2][2] = bb->vec[5][2] = bb->vec[6][2] = max[2];
}
void BKE_boundbox_minmax(const BoundBox &bb, const float4x4 &matrix, float3 &r_min, float3 &r_max)
{
using namespace blender;
for (const int i : IndexRange(ARRAY_SIZE(bb.vec))) {
math::min_max(math::transform_point(matrix, float3(bb.vec[i])), r_min, r_max);
}
}
std::optional<blender::Bounds<blender::float3>> BKE_object_boundbox_get(const Object *ob)
{
switch (ob->type) {
@@ -3824,9 +3805,9 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
temp_ob.runtime->bounds_eval.reset();
BKE_object_replace_data_on_shallow_copy(&temp_ob, dob.ob_data);
if (const std::optional<Bounds<float3>> bounds = BKE_object_boundbox_get(&temp_ob)) {
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, bounds->min, bounds->max);
BKE_boundbox_minmax(bb, float4x4(dob.mat), r_min, r_max);
const Bounds tranformed_bounds = bounds::transform_bounds(float4x4(dob.mat), *bounds);
r_min = math::min(tranformed_bounds.min, r_min);
r_max = math::max(tranformed_bounds.max, r_max);
ok = true;
}
}

View File

@@ -186,6 +186,22 @@ template<typename T> inline std::optional<T> max(const VArray<T> &values)
/**
* Return the eight corners of a 3D bounding box.
* <pre>
*
* Z Y
* | /
* |/
* .-----X
* 2----------6
* /| /|
* / | / |
* 1----------5 |
* | | | |
* | 3-------|--7
* | / | /
* |/ |/
* 0----------4
* </pre>
*/
template<typename T>
inline std::array<VecBase<T, 3>, 8> corners(const Bounds<VecBase<T, 3>> &bounds)
@@ -193,12 +209,12 @@ inline std::array<VecBase<T, 3>, 8> corners(const Bounds<VecBase<T, 3>> &bounds)
return {
VecBase<T, 3>{bounds.min[0], bounds.min[1], bounds.min[2]},
VecBase<T, 3>{bounds.min[0], bounds.min[1], bounds.max[2]},
VecBase<T, 3>{bounds.min[0], bounds.max[1], bounds.min[2]},
VecBase<T, 3>{bounds.min[0], bounds.max[1], bounds.max[2]},
VecBase<T, 3>{bounds.min[0], bounds.max[1], bounds.min[2]},
VecBase<T, 3>{bounds.max[0], bounds.min[1], bounds.min[2]},
VecBase<T, 3>{bounds.max[0], bounds.min[1], bounds.max[2]},
VecBase<T, 3>{bounds.max[0], bounds.max[1], bounds.min[2]},
VecBase<T, 3>{bounds.max[0], bounds.max[1], bounds.max[2]},
VecBase<T, 3>{bounds.max[0], bounds.max[1], bounds.min[2]},
};
}

View File

@@ -1174,13 +1174,12 @@ VolumeObjectBounds::VolumeObjectBounds(const Camera &camera, Object *ob)
const Bounds<float3> bounds = BKE_object_boundbox_get(ob).value_or(Bounds(float3(0.0f)));
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, bounds.min, bounds.max);
const std::array<float3, 8> corners = bounds::corners(bounds);
screen_bounds = std::nullopt;
z_range = std::nullopt;
for (float3 l_corner : bb.vec) {
for (const float3 &l_corner : corners) {
float3 ws_corner = math::transform_point(ob->object_to_world(), l_corner);
/* Split view and projection for precision. */
float3 vs_corner = math::transform_point(view_matrix, ws_corner);

View File

@@ -182,12 +182,11 @@ bool ShadowPass::ShadowView::debug_object_culling(Object *ob)
{
printf("Test %s\n", ob->id.name);
const Bounds<float3> bounds = *BKE_object_boundbox_get(ob);
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, bounds.min, bounds.max);
const std::array<float3, 8> corners = bounds::corners(bounds);
for (int p : IndexRange(extruded_frustum_.planes_count)) {
float4 plane = extruded_frustum_.planes[p];
bool separating_axis = true;
for (float3 corner : bb.vec) {
for (float3 corner : corners) {
corner = math::transform_point(ob->object_to_world(), corner);
float signed_distance = math::dot(corner, float3(plane)) - plane.w;
if (signed_distance <= 0) {

View File

@@ -183,10 +183,9 @@ void drw_debug_matrix(const float4x4 &m4, const uint lifetime)
void drw_debug_matrix_as_bbox(const float4x4 &mat, const float4 color, const uint lifetime)
{
BoundBox bb;
const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f, 1.0f};
BKE_boundbox_init_from_minmax(&bb, min, max);
std::array<float3, 8> corners = bounds::corners(Bounds<float3>(float3(-1), float3(1)));
for (auto i : IndexRange(8)) {
mul_project_m4_v3(mat.ptr(), bb.vec[i]);
mul_project_m4_v3(mat.ptr(), corners[i]);
}
drw_debug_bbox(bb, color, lifetime);
}

View File

@@ -11,6 +11,7 @@
* Each of them are reference by resource index (#ResourceHandle).
*/
#include "BLI_bounds.hh"
#include "BLI_math_base.h"
#include "BLI_math_matrix.hh"
@@ -205,12 +206,11 @@ inline void ObjectBounds::sync(const Object &ob, float inflate_bounds)
bounding_sphere.w = -1.0f; /* Disable test. */
return;
}
BoundBox bbox;
BKE_boundbox_init_from_minmax(&bbox, bounds->min, bounds->max);
*reinterpret_cast<float3 *>(&bounding_corners[0]) = bbox.vec[0];
*reinterpret_cast<float3 *>(&bounding_corners[1]) = bbox.vec[4];
*reinterpret_cast<float3 *>(&bounding_corners[2]) = bbox.vec[3];
*reinterpret_cast<float3 *>(&bounding_corners[3]) = bbox.vec[1];
const std::array<float3, 8> corners = blender::bounds::corners(*bounds);
*reinterpret_cast<float3 *>(&bounding_corners[0]) = corners[0];
*reinterpret_cast<float3 *>(&bounding_corners[1]) = corners[4];
*reinterpret_cast<float3 *>(&bounding_corners[2]) = corners[3];
*reinterpret_cast<float3 *>(&bounding_corners[3]) = corners[1];
bounding_sphere.w = 0.0f; /* Enable test. */
if (inflate_bounds != 0.0f) {

View File

@@ -47,9 +47,9 @@ void View::frustum_boundbox_calc(int view_id)
{
/* Extract the 8 corners from a Projection Matrix. */
#if 0 /* Equivalent to this but it has accuracy problems. */
BKE_boundbox_init_from_minmax(&bbox, float3(-1.0f), float3(1.0f));
std::array<float3, 8> box = bounds::corners(Bounds<float3>(float3 (-1), float3 (1)));
for (int i = 0; i < 8; i++) {
mul_project_m4_v3(data_.wininv.ptr(), bbox.vec[i]);
mul_project_m4_v3(data_.wininv.ptr(), box[i]);
}
#endif

View File

@@ -14,6 +14,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_bounds.hh"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_string_utf8.h"
@@ -455,8 +456,7 @@ static wmOperatorStatus voxel_size_edit_invoke(bContext *C, wmOperator *op, cons
/* Select the front facing face of the mesh bounding box. */
const Bounds<float3> bounds = *mesh->bounds_min_max();
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, bounds.min, bounds.max);
const std::array<float3, 8> bounds_box = bounds::corners(bounds);
/* Indices of the Bounding Box faces. */
const int BB_faces[6][4] = {
@@ -468,10 +468,10 @@ static wmOperatorStatus voxel_size_edit_invoke(bContext *C, wmOperator *op, cons
{2, 3, 7, 6},
};
copy_v3_v3(cd->preview_plane[0], bb.vec[BB_faces[0][0]]);
copy_v3_v3(cd->preview_plane[1], bb.vec[BB_faces[0][1]]);
copy_v3_v3(cd->preview_plane[2], bb.vec[BB_faces[0][2]]);
copy_v3_v3(cd->preview_plane[3], bb.vec[BB_faces[0][3]]);
copy_v3_v3(cd->preview_plane[0], bounds_box[BB_faces[0][0]]);
copy_v3_v3(cd->preview_plane[1], bounds_box[BB_faces[0][1]]);
copy_v3_v3(cd->preview_plane[2], bounds_box[BB_faces[0][2]]);
copy_v3_v3(cd->preview_plane[3], bounds_box[BB_faces[0][3]]);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -495,16 +495,18 @@ static wmOperatorStatus voxel_size_edit_invoke(bContext *C, wmOperator *op, cons
/* Check if there is a face that is more aligned towards the view. */
for (int i = 0; i < 6; i++) {
normal_tri_v3(
current_normal, bb.vec[BB_faces[i][0]], bb.vec[BB_faces[i][1]], bb.vec[BB_faces[i][2]]);
normal_tri_v3(current_normal,
bounds_box[BB_faces[i][0]],
bounds_box[BB_faces[i][1]],
bounds_box[BB_faces[i][2]]);
current_dot = dot_v3v3(current_normal, view_normal);
if (current_dot < min_dot) {
min_dot = current_dot;
copy_v3_v3(cd->preview_plane[0], bb.vec[BB_faces[i][0]]);
copy_v3_v3(cd->preview_plane[1], bb.vec[BB_faces[i][1]]);
copy_v3_v3(cd->preview_plane[2], bb.vec[BB_faces[i][2]]);
copy_v3_v3(cd->preview_plane[3], bb.vec[BB_faces[i][3]]);
copy_v3_v3(cd->preview_plane[0], bounds_box[BB_faces[i][0]]);
copy_v3_v3(cd->preview_plane[1], bounds_box[BB_faces[i][1]]);
copy_v3_v3(cd->preview_plane[2], bounds_box[BB_faces[i][2]]);
copy_v3_v3(cd->preview_plane[3], bounds_box[BB_faces[i][3]]);
}
}

View File

@@ -11,6 +11,7 @@
*/
#include "BLI_array_utils.h"
#include "BLI_bounds.hh"
#include "BLI_function_ref.hh"
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
@@ -903,11 +904,10 @@ static int gizmo_3d_foreach_selected(const bContext *C,
}
/* Get the boundbox out of the evaluated object. */
std::optional<BoundBox> bb;
std::optional<std::array<float3, 8>> bb;
if (use_only_center == false) {
if (std::optional<Bounds<float3>> bounds = BKE_object_boundbox_get(base->object)) {
bb.emplace();
BKE_boundbox_init_from_minmax(&*bb, bounds->min, bounds->max);
bb.emplace(bounds::corners(*bounds));
}
}
@@ -917,7 +917,7 @@ static int gizmo_3d_foreach_selected(const bContext *C,
else {
for (uint j = 0; j < 8; j++) {
float co[3];
mul_v3_m4v3(co, base->object->object_to_world().ptr(), bb->vec[j]);
mul_v3_m4v3(co, base->object->object_to_world().ptr(), (*bb)[j]);
user_fn(co);
}
}

View File

@@ -6,6 +6,7 @@
* \ingroup edtransform
*/
#include "BLI_bounds.hh"
#include "BLI_listbase.h"
#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
@@ -1475,15 +1476,14 @@ static void snap_source_closest_fn(TransInfo *t)
/* Use bound-box if possible. */
if (bounds) {
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, bounds->min, bounds->max);
const std::array<float3, 8> bounds_corners = bounds::corners(*bounds);
int j;
for (j = 0; j < 8; j++) {
float loc[3];
float dist;
copy_v3_v3(loc, bb.vec[j]);
copy_v3_v3(loc, bounds_corners[j]);
mul_m4_v3(td->ext->obmat, loc);
dist = t->mode_info->snap_distance_fn(t, loc, t->tsnap.snap_target);

View File

@@ -1,8 +1,11 @@
/* SPDX-FileCopyrightText: 2020 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "abc_writer_abstract.h"
#include "BLI_bounds.hh"
#include "abc_hierarchy_iterator.h"
#include "abc_writer_abstract.h"
#include "BKE_object.hh"
@@ -105,17 +108,16 @@ void ABCAbstractWriter::update_bounding_box(Object *object)
return;
}
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, bounds->min, bounds->max);
const std::array<float3, 8> corners = blender::bounds::corners(*bounds);
/* Convert Z-up to Y-up. This also changes which vector goes into which min/max property. */
bounding_box_.min.x = bb.vec[0][0];
bounding_box_.min.y = bb.vec[0][2];
bounding_box_.min.z = -bb.vec[6][1];
bounding_box_.min.x = corners[0][0];
bounding_box_.min.y = corners[0][2];
bounding_box_.min.z = -corners[6][1];
bounding_box_.max.x = bb.vec[6][0];
bounding_box_.max.y = bb.vec[6][2];
bounding_box_.max.z = -bb.vec[0][1];
bounding_box_.max.x = corners[6][0];
bounding_box_.max.y = corners[6][2];
bounding_box_.max.z = -corners[0][1];
}
void ABCAbstractWriter::write_visibility(const HierarchyContext &context)

View File

@@ -289,6 +289,8 @@ const EnumPropertyItem rna_enum_object_axis_items[] = {
# include <fmt/format.h>
# include "BLI_bounds.hh"
# include "DNA_ID.h"
# include "DNA_constraint_types.h"
# include "DNA_gpencil_legacy_types.h"
@@ -1892,9 +1894,7 @@ static void rna_Object_boundbox_get(PointerRNA *ptr, float *values)
using namespace blender;
Object *ob = reinterpret_cast<Object *>(ptr->owner_id);
if (const std::optional<Bounds<float3>> bounds = BKE_object_boundbox_eval_cached_get(ob)) {
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, bounds->min, bounds->max);
memcpy(values, bb.vec, sizeof(bb.vec));
*reinterpret_cast<std::array<float3, 8> *>(values) = blender::bounds::corners(*bounds);
}
else {
copy_vn_fl(values, 8 * 3, 0.0f);

View File

@@ -10,6 +10,7 @@
#include "MOD_lineart.hh"
#include "BLI_bounds.hh"
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
@@ -2433,13 +2434,12 @@ static bool lineart_geometry_check_visible(double model_view_proj[4][4],
if (!bounds.has_value()) {
return false;
}
BoundBox bb;
BKE_boundbox_init_from_minmax(&bb, bounds.value().min, bounds.value().max);
const std::array<float3, 8> corners = blender::bounds::corners(*bounds);
double co[8][4];
double tmp[3];
for (int i = 0; i < 8; i++) {
copy_v3db_v3fl(co[i], bb.vec[i]);
copy_v3db_v3fl(co[i], corners[i]);
copy_v3_v3_db(tmp, co[i]);
mul_v4_m4v3_db(co[i], model_view_proj, tmp);
co[i][0] -= shift_x * 2 * co[i][3];