Refactor: Improve access to object data bounds
Currently object bounds (`object.runtime.bb`) are lazily initialized
when accessed. This access happens from arbitrary threads, and
is unprotected by a mutex. This can cause access to stale data at
best, and crashes at worst. Eager calculation is meant to keep this
working, but it's fragile.
Since e8f4010611, geometry bounds are cached in the geometry
itself, which makes this object-level cache redundant. So, it's clearer
to build the `BoundBox` from those cached bounds and return it by
value, without interacting with the object's cached bounding box.
The code change is is mostly a move from `const BoundBox *` to
`std::optional<BoundBox>`. This is only one step of a larger change
described in #96968. Followup steps would include switching to
a simpler and smaller `Bounds` type, removing redundant object-
level access, and eventually removing `object.runtime.bb`.
Access of bounds from the object for mesh, curves, and point cloud
objects should now be thread-safe. Other object types still lazily
initialize the object `BoundBox` cache since they don't have
a data-level cache.
Pull Request: https://projects.blender.org/blender/blender/pulls/113465
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "DNA_curves_types.h"
|
||||
#include "DNA_object_types.h" /* #BoundBox. */
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
@@ -24,7 +25,7 @@ struct Scene;
|
||||
|
||||
void *BKE_curves_add(struct Main *bmain, const char *name);
|
||||
|
||||
struct BoundBox *BKE_curves_boundbox_get(struct Object *ob);
|
||||
BoundBox BKE_curves_boundbox_get(struct Object *ob);
|
||||
|
||||
bool BKE_curves_attribute_required(const struct Curves *curves, const char *name);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_object_types.h" /* #BoundBox. */
|
||||
|
||||
struct Main;
|
||||
struct Depsgraph;
|
||||
@@ -801,7 +802,7 @@ inline bool GreasePencil::has_active_layer() const
|
||||
void *BKE_grease_pencil_add(Main *bmain, const char *name);
|
||||
GreasePencil *BKE_grease_pencil_new_nomain();
|
||||
GreasePencil *BKE_grease_pencil_copy_for_eval(const GreasePencil *grease_pencil_src);
|
||||
BoundBox *BKE_grease_pencil_boundbox_get(Object *ob);
|
||||
BoundBox BKE_grease_pencil_boundbox_get(Object *ob);
|
||||
void BKE_grease_pencil_data_update(Depsgraph *depsgraph, Scene *scene, Object *object);
|
||||
void BKE_grease_pencil_duplicate_drawing_array(const GreasePencil *grease_pencil_src,
|
||||
GreasePencil *grease_pencil_dst);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h" /* #BoundBox. */
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
|
||||
@@ -233,7 +234,7 @@ void BKE_mesh_auto_smooth_flag_set(struct Mesh *me, bool use_auto_smooth, float
|
||||
*/
|
||||
const char *BKE_mesh_cmp(struct Mesh *me1, struct Mesh *me2, float thresh);
|
||||
|
||||
struct BoundBox *BKE_mesh_boundbox_get(struct Object *ob);
|
||||
BoundBox BKE_mesh_boundbox_get(struct Object *ob);
|
||||
|
||||
void BKE_mesh_texspace_calc(struct Mesh *me);
|
||||
void BKE_mesh_texspace_ensure(struct Mesh *me);
|
||||
|
||||
@@ -9,10 +9,13 @@
|
||||
* \brief General operations, lookup, etc. for blender objects.
|
||||
*/
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include "DNA_object_enums.h"
|
||||
#include "DNA_object_types.h" /* #BoundBox. */
|
||||
#include "DNA_userdef_enums.h"
|
||||
|
||||
struct Base;
|
||||
@@ -344,7 +347,7 @@ void BKE_boundbox_minmax(const BoundBox *bb,
|
||||
float r_min[3],
|
||||
float r_max[3]);
|
||||
|
||||
const BoundBox *BKE_object_boundbox_get(Object *ob);
|
||||
std::optional<BoundBox> BKE_object_boundbox_get(Object *ob);
|
||||
void BKE_object_dimensions_get(Object *ob, float r_vec[3]);
|
||||
/**
|
||||
* The original scale and object matrix can be passed in so any difference
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
* \brief General operations for point clouds.
|
||||
*/
|
||||
|
||||
#include "DNA_object_types.h" /* #BoundBox. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include <mutex>
|
||||
|
||||
@@ -74,7 +76,7 @@ struct PointCloud *BKE_pointcloud_new_nomain(int totpoint);
|
||||
void BKE_pointcloud_nomain_to_pointcloud(struct PointCloud *pointcloud_src,
|
||||
struct PointCloud *pointcloud_dst);
|
||||
|
||||
struct BoundBox *BKE_pointcloud_boundbox_get(struct Object *ob);
|
||||
BoundBox BKE_pointcloud_boundbox_get(struct Object *ob);
|
||||
|
||||
bool BKE_pointcloud_attribute_required(const struct PointCloud *pointcloud, const char *name);
|
||||
|
||||
|
||||
@@ -2956,17 +2956,15 @@ void BKE_pchan_minmax(const Object *ob,
|
||||
const bArmature *arm = static_cast<const bArmature *>(ob->data);
|
||||
Object *ob_custom = (arm->flag & ARM_NO_CUSTOM) ? nullptr : pchan->custom;
|
||||
const bPoseChannel *pchan_tx = (ob_custom && pchan->custom_tx) ? pchan->custom_tx : pchan;
|
||||
const BoundBox *bb_custom = nullptr;
|
||||
BoundBox bb_custom_buf;
|
||||
|
||||
std::optional<BoundBox> bb_custom;
|
||||
if (ob_custom) {
|
||||
float min[3], max[3];
|
||||
if (use_empty_drawtype && (ob_custom->type == OB_EMPTY) &&
|
||||
BKE_object_minmax_empty_drawtype(ob_custom, min, max))
|
||||
{
|
||||
memset(&bb_custom_buf, 0x0, sizeof(bb_custom_buf));
|
||||
BKE_boundbox_init_from_minmax(&bb_custom_buf, min, max);
|
||||
bb_custom = &bb_custom_buf;
|
||||
bb_custom.emplace();
|
||||
BKE_boundbox_init_from_minmax(&bb_custom.value(), min, max);
|
||||
}
|
||||
else {
|
||||
bb_custom = BKE_object_boundbox_get(ob_custom);
|
||||
@@ -2984,7 +2982,7 @@ void BKE_pchan_minmax(const Object *ob,
|
||||
pchan->custom_translation[1],
|
||||
pchan->custom_translation[2]);
|
||||
mul_m4_series(mat, ob->object_to_world, tmp, rmat, smat);
|
||||
BKE_boundbox_minmax(bb_custom, mat, r_min, r_max);
|
||||
BKE_boundbox_minmax(&bb_custom.value(), mat, r_min, r_max);
|
||||
}
|
||||
else {
|
||||
float vec[3];
|
||||
|
||||
@@ -170,28 +170,21 @@ void *BKE_curves_add(Main *bmain, const char *name)
|
||||
return curves;
|
||||
}
|
||||
|
||||
BoundBox *BKE_curves_boundbox_get(Object *ob)
|
||||
BoundBox BKE_curves_boundbox_get(Object *ob)
|
||||
{
|
||||
using namespace blender;
|
||||
BLI_assert(ob->type == OB_CURVES);
|
||||
const Curves *curves_id = static_cast<const Curves *>(ob->data);
|
||||
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
|
||||
if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
|
||||
return ob->runtime.bb;
|
||||
BoundBox bb;
|
||||
if (const std::optional<Bounds<float3>> bounds = curves.bounds_min_max()) {
|
||||
BKE_boundbox_init_from_minmax(&bb, bounds->min, bounds->max);
|
||||
}
|
||||
|
||||
if (ob->runtime.bb == nullptr) {
|
||||
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
|
||||
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
if (const std::optional<Bounds<float3>> bounds = curves.bounds_min_max()) {
|
||||
BKE_boundbox_init_from_minmax(ob->runtime.bb, bounds->min, bounds->max);
|
||||
}
|
||||
else {
|
||||
BKE_boundbox_init_from_minmax(ob->runtime.bb, float3(-1), float3(1));
|
||||
}
|
||||
else {
|
||||
BKE_boundbox_init_from_minmax(&bb, float3(-1), float3(1));
|
||||
}
|
||||
|
||||
return ob->runtime.bb;
|
||||
return bb;
|
||||
}
|
||||
|
||||
bool BKE_curves_attribute_required(const Curves * /*curves*/, const char *name)
|
||||
|
||||
@@ -1143,26 +1143,21 @@ GreasePencil *BKE_grease_pencil_copy_for_eval(const GreasePencil *grease_pencil_
|
||||
return grease_pencil;
|
||||
}
|
||||
|
||||
BoundBox *BKE_grease_pencil_boundbox_get(Object *ob)
|
||||
BoundBox BKE_grease_pencil_boundbox_get(Object *ob)
|
||||
{
|
||||
using namespace blender;
|
||||
BLI_assert(ob->type == OB_GREASE_PENCIL);
|
||||
const GreasePencil *grease_pencil = static_cast<const GreasePencil *>(ob->data);
|
||||
if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
|
||||
return ob->runtime.bb;
|
||||
}
|
||||
if (ob->runtime.bb == nullptr) {
|
||||
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
|
||||
}
|
||||
|
||||
BoundBox bb;
|
||||
if (const std::optional<Bounds<float3>> bounds = grease_pencil->bounds_min_max()) {
|
||||
BKE_boundbox_init_from_minmax(ob->runtime.bb, bounds->min, bounds->max);
|
||||
BKE_boundbox_init_from_minmax(&bb, bounds->min, bounds->max);
|
||||
}
|
||||
else {
|
||||
BKE_boundbox_init_from_minmax(ob->runtime.bb, float3(-1), float3(1));
|
||||
BKE_boundbox_init_from_minmax(&bb, float3(-1), float3(1));
|
||||
}
|
||||
|
||||
return ob->runtime.bb;
|
||||
return bb;
|
||||
}
|
||||
|
||||
static void grease_pencil_evaluate_modifiers(Depsgraph *depsgraph,
|
||||
|
||||
@@ -1155,28 +1155,20 @@ void BKE_mesh_ensure_default_orig_index_customdata_no_check(Mesh *mesh)
|
||||
ensure_orig_index_layer(mesh->face_data, mesh->faces_num);
|
||||
}
|
||||
|
||||
BoundBox *BKE_mesh_boundbox_get(Object *ob)
|
||||
BoundBox BKE_mesh_boundbox_get(Object *ob)
|
||||
{
|
||||
/* This is Object-level data access,
|
||||
* DO NOT touch to Mesh's bb, would be totally thread-unsafe. */
|
||||
if (ob->runtime.bb == nullptr || ob->runtime.bb->flag & BOUNDBOX_DIRTY) {
|
||||
Mesh *me = static_cast<Mesh *>(ob->data);
|
||||
float min[3], max[3];
|
||||
Mesh *me = static_cast<Mesh *>(ob->data);
|
||||
float min[3], max[3];
|
||||
|
||||
INIT_MINMAX(min, max);
|
||||
if (!BKE_mesh_wrapper_minmax(me, min, max)) {
|
||||
min[0] = min[1] = min[2] = -1.0f;
|
||||
max[0] = max[1] = max[2] = 1.0f;
|
||||
}
|
||||
|
||||
if (ob->runtime.bb == nullptr) {
|
||||
ob->runtime.bb = (BoundBox *)MEM_mallocN(sizeof(*ob->runtime.bb), __func__);
|
||||
}
|
||||
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
|
||||
ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY;
|
||||
INIT_MINMAX(min, max);
|
||||
if (!BKE_mesh_wrapper_minmax(me, min, max)) {
|
||||
min[0] = min[1] = min[2] = -1.0f;
|
||||
max[0] = max[1] = max[2] = 1.0f;
|
||||
}
|
||||
|
||||
return ob->runtime.bb;
|
||||
BoundBox bb;
|
||||
BKE_boundbox_init_from_minmax(&bb, min, max);
|
||||
return bb;
|
||||
}
|
||||
|
||||
void BKE_mesh_texspace_calc(Mesh *me)
|
||||
|
||||
@@ -3558,46 +3558,36 @@ void BKE_boundbox_minmax(const BoundBox *bb,
|
||||
}
|
||||
}
|
||||
|
||||
const BoundBox *BKE_object_boundbox_get(Object *ob)
|
||||
std::optional<BoundBox> BKE_object_boundbox_get(Object *ob)
|
||||
{
|
||||
BoundBox *bb = nullptr;
|
||||
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
bb = BKE_mesh_boundbox_get(ob);
|
||||
break;
|
||||
return BKE_mesh_boundbox_get(ob);
|
||||
case OB_CURVES_LEGACY:
|
||||
case OB_SURF:
|
||||
case OB_FONT:
|
||||
bb = BKE_curve_boundbox_get(ob);
|
||||
break;
|
||||
return *BKE_curve_boundbox_get(ob);
|
||||
case OB_MBALL:
|
||||
bb = BKE_mball_boundbox_get(ob);
|
||||
break;
|
||||
if (const BoundBox *bb = BKE_mball_boundbox_get(ob)) {
|
||||
return *bb;
|
||||
}
|
||||
return std::nullopt;
|
||||
case OB_LATTICE:
|
||||
bb = BKE_lattice_boundbox_get(ob);
|
||||
break;
|
||||
return *BKE_lattice_boundbox_get(ob);
|
||||
case OB_ARMATURE:
|
||||
bb = BKE_armature_boundbox_get(ob);
|
||||
break;
|
||||
return *BKE_armature_boundbox_get(ob);
|
||||
case OB_GPENCIL_LEGACY:
|
||||
bb = BKE_gpencil_boundbox_get(ob);
|
||||
break;
|
||||
return *BKE_gpencil_boundbox_get(ob);
|
||||
case OB_CURVES:
|
||||
bb = BKE_curves_boundbox_get(ob);
|
||||
break;
|
||||
return BKE_curves_boundbox_get(ob);
|
||||
case OB_POINTCLOUD:
|
||||
bb = BKE_pointcloud_boundbox_get(ob);
|
||||
break;
|
||||
return BKE_pointcloud_boundbox_get(ob);
|
||||
case OB_VOLUME:
|
||||
bb = BKE_volume_boundbox_get(ob);
|
||||
break;
|
||||
return *BKE_volume_boundbox_get(ob);
|
||||
case OB_GREASE_PENCIL:
|
||||
bb = BKE_grease_pencil_boundbox_get(ob);
|
||||
default:
|
||||
break;
|
||||
return BKE_grease_pencil_boundbox_get(ob);
|
||||
}
|
||||
return bb;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void BKE_object_boundbox_calc_from_mesh(Object *ob, const Mesh *me_eval)
|
||||
@@ -3663,8 +3653,7 @@ bool BKE_object_boundbox_calc_from_evaluated_geometry(Object *ob)
|
||||
|
||||
void BKE_object_dimensions_get(Object *ob, float r_vec[3])
|
||||
{
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
if (bb) {
|
||||
if (const std::optional<BoundBox> bb = BKE_object_boundbox_get(ob)) {
|
||||
float3 scale;
|
||||
mat4_to_size(scale, ob->object_to_world);
|
||||
|
||||
@@ -3683,8 +3672,7 @@ void BKE_object_dimensions_set_ex(Object *ob,
|
||||
const float ob_scale_orig[3],
|
||||
const float ob_obmat_orig[4][4])
|
||||
{
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
if (bb) {
|
||||
if (const std::optional<BoundBox> bb = BKE_object_boundbox_get(ob)) {
|
||||
float3 len;
|
||||
len.x = bb->vec[4][0] - bb->vec[0][0];
|
||||
len.y = bb->vec[2][1] - bb->vec[0][1];
|
||||
@@ -3728,7 +3716,7 @@ void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3], const bool us
|
||||
break;
|
||||
}
|
||||
case OB_MESH: {
|
||||
const BoundBox bb = *BKE_mesh_boundbox_get(ob);
|
||||
const BoundBox bb = BKE_mesh_boundbox_get(ob);
|
||||
BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
|
||||
changed = true;
|
||||
break;
|
||||
@@ -3772,13 +3760,13 @@ void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3], const bool us
|
||||
break;
|
||||
}
|
||||
case OB_CURVES: {
|
||||
const BoundBox bb = *BKE_curves_boundbox_get(ob);
|
||||
const BoundBox bb = BKE_curves_boundbox_get(ob);
|
||||
BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
case OB_POINTCLOUD: {
|
||||
const BoundBox bb = *BKE_pointcloud_boundbox_get(ob);
|
||||
const BoundBox bb = BKE_pointcloud_boundbox_get(ob);
|
||||
BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
|
||||
changed = true;
|
||||
break;
|
||||
@@ -3790,7 +3778,7 @@ void BKE_object_minmax(Object *ob, float r_min[3], float r_max[3], const bool us
|
||||
break;
|
||||
}
|
||||
case OB_GREASE_PENCIL: {
|
||||
const BoundBox bb = *BKE_grease_pencil_boundbox_get(ob);
|
||||
const BoundBox bb = BKE_grease_pencil_boundbox_get(ob);
|
||||
BKE_boundbox_minmax(&bb, ob->object_to_world, r_min, r_max);
|
||||
changed = true;
|
||||
break;
|
||||
@@ -3978,9 +3966,7 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
|
||||
/* Do not modify the original bounding-box. */
|
||||
temp_ob.runtime.bb = nullptr;
|
||||
BKE_object_replace_data_on_shallow_copy(&temp_ob, dob->ob_data);
|
||||
const BoundBox *bb = BKE_object_boundbox_get(&temp_ob);
|
||||
|
||||
if (bb) {
|
||||
if (const std::optional<BoundBox> bb = BKE_object_boundbox_get(&temp_ob)) {
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
float3 vec;
|
||||
|
||||
@@ -243,13 +243,11 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
|
||||
/** Bounding box from evaluated geometry. */
|
||||
static void object_sync_boundbox_to_original(Object *object_orig, Object *object_eval)
|
||||
{
|
||||
const BoundBox *bb = object_eval->runtime.bb;
|
||||
if (!bb || (bb->flag & BOUNDBOX_DIRTY)) {
|
||||
if (!object_eval->runtime.bb || (object_eval->runtime.bb->flag & BOUNDBOX_DIRTY)) {
|
||||
BKE_object_boundbox_calc_from_evaluated_geometry(object_eval);
|
||||
}
|
||||
|
||||
bb = BKE_object_boundbox_get(object_eval);
|
||||
if (bb != nullptr) {
|
||||
if (const std::optional<BoundBox> bb = BKE_object_boundbox_get(object_eval)) {
|
||||
if (object_orig->runtime.bb == nullptr) {
|
||||
object_orig->runtime.bb = MEM_new<BoundBox>(__func__);
|
||||
}
|
||||
|
||||
@@ -259,16 +259,10 @@ std::optional<blender::Bounds<blender::float3>> PointCloud::bounds_min_max() con
|
||||
return this->runtime->bounds_cache.data();
|
||||
}
|
||||
|
||||
BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
|
||||
BoundBox BKE_pointcloud_boundbox_get(Object *ob)
|
||||
{
|
||||
using namespace blender;
|
||||
BLI_assert(ob->type == OB_POINTCLOUD);
|
||||
if (ob->runtime.bb != nullptr && (ob->runtime.bb->flag & BOUNDBOX_DIRTY) == 0) {
|
||||
return ob->runtime.bb;
|
||||
}
|
||||
if (ob->runtime.bb == nullptr) {
|
||||
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
|
||||
}
|
||||
|
||||
std::optional<Bounds<float3>> bounds;
|
||||
if (ob->runtime.geometry_set_eval) {
|
||||
@@ -279,14 +273,15 @@ BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
|
||||
bounds = pointcloud->bounds_min_max();
|
||||
}
|
||||
|
||||
BoundBox bb;
|
||||
if (bounds) {
|
||||
BKE_boundbox_init_from_minmax(ob->runtime.bb, bounds->min, bounds->max);
|
||||
BKE_boundbox_init_from_minmax(&bb, bounds->min, bounds->max);
|
||||
}
|
||||
else {
|
||||
BKE_boundbox_init_from_minmax(ob->runtime.bb, float3(-1), float3(1));
|
||||
BKE_boundbox_init_from_minmax(&bb, float3(-1), float3(1));
|
||||
}
|
||||
|
||||
return ob->runtime.bb;
|
||||
return bb;
|
||||
}
|
||||
|
||||
bool BKE_pointcloud_attribute_required(const PointCloud * /*pointcloud*/, const char *name)
|
||||
|
||||
@@ -492,8 +492,7 @@ static rbCollisionShape *rigidbody_validate_sim_shape_helper(RigidBodyWorld *rbw
|
||||
*/
|
||||
/* XXX: all dimensions are auto-determined now... later can add stored settings for this */
|
||||
/* get object dimensions without scaling */
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
if (bb) {
|
||||
if (const std::optional<BoundBox> bb = BKE_object_boundbox_get(ob)) {
|
||||
size[0] = (bb->vec[4][0] - bb->vec[0][0]);
|
||||
size[1] = (bb->vec[2][1] - bb->vec[0][1]);
|
||||
size[2] = (bb->vec[1][2] - bb->vec[0][2]);
|
||||
@@ -1769,7 +1768,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO
|
||||
float(*positions)[3] = reinterpret_cast<float(*)[3]>(
|
||||
mesh->vert_positions_for_write().data());
|
||||
int totvert = mesh->totvert;
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
const std::optional<BoundBox> bb = BKE_object_boundbox_get(ob);
|
||||
|
||||
RB_shape_trimesh_update(static_cast<rbCollisionShape *>(rbo->shared->physics_shape),
|
||||
(float *)positions,
|
||||
|
||||
@@ -155,12 +155,12 @@ void EEVEE_shadows_caster_register(EEVEE_ViewLayerData *sldata, Object *ob)
|
||||
}
|
||||
|
||||
/* Update World AABB in frontbuffer. */
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
const BoundBox bb = *BKE_object_boundbox_get(ob);
|
||||
float min[3], max[3];
|
||||
INIT_MINMAX(min, max);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
float vec[3];
|
||||
copy_v3_v3(vec, bb->vec[i]);
|
||||
copy_v3_v3(vec, bb.vec[i]);
|
||||
mul_m4_v3(ob->object_to_world, vec);
|
||||
minmax_v3v3_v3(min, max, vec);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ VolumeModule::GridAABB::GridAABB(Object *ob, const Camera &camera, const Volumes
|
||||
return int3(grid_coords * float3(data.tex_size) + 0.5);
|
||||
};
|
||||
|
||||
const BoundBox &bbox = *BKE_object_boundbox_get(ob);
|
||||
const BoundBox bbox = *BKE_object_boundbox_get(ob);
|
||||
min = int3(INT32_MAX);
|
||||
max = int3(INT32_MIN);
|
||||
|
||||
|
||||
@@ -63,11 +63,11 @@ GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob)
|
||||
* strokes not aligned with the object axes. Maybe we could try to
|
||||
* compute the minimum axis of all strokes. But this would be more
|
||||
* computationally heavy and should go into the GPData evaluation. */
|
||||
const BoundBox *bbox = BKE_object_boundbox_get(ob);
|
||||
const std::optional<BoundBox> bbox = BKE_object_boundbox_get(ob);
|
||||
/* Convert bbox to matrix */
|
||||
float mat[4][4], size[3], center[3];
|
||||
BKE_boundbox_calc_size_aabb(bbox, size);
|
||||
BKE_boundbox_calc_center_aabb(bbox, center);
|
||||
BKE_boundbox_calc_size_aabb(&bbox.value(), size);
|
||||
BKE_boundbox_calc_center_aabb(&bbox.value(), center);
|
||||
unit_m4(mat);
|
||||
copy_v3_v3(mat[3], center);
|
||||
/* Avoid division by 0.0 later. */
|
||||
|
||||
@@ -360,21 +360,21 @@ static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb,
|
||||
return;
|
||||
}
|
||||
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
std::optional<BoundBox> bb = BKE_object_boundbox_get(ob);
|
||||
BoundBox bb_local;
|
||||
if (bb == nullptr) {
|
||||
if (!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_local, min, max);
|
||||
bb = &bb_local;
|
||||
bb.emplace(bb_local);
|
||||
}
|
||||
|
||||
BKE_boundbox_calc_size_aabb(bb, size);
|
||||
BKE_boundbox_calc_size_aabb(&*bb, size);
|
||||
|
||||
if (around_origin) {
|
||||
zero_v3(center);
|
||||
}
|
||||
else {
|
||||
BKE_boundbox_calc_center_aabb(bb, center);
|
||||
BKE_boundbox_calc_center_aabb(&*bb, center);
|
||||
}
|
||||
|
||||
switch (boundtype) {
|
||||
|
||||
@@ -33,11 +33,11 @@ static void gpencil_depth_plane(Object *ob, float r_plane[4])
|
||||
* strokes not aligned with the object axes. Maybe we could try to
|
||||
* compute the minimum axis of all strokes. But this would be more
|
||||
* computationally heavy and should go into the GPData evaluation. */
|
||||
const BoundBox *bbox = BKE_object_boundbox_get(ob);
|
||||
const BoundBox bbox = *BKE_object_boundbox_get(ob);
|
||||
/* Convert bbox to matrix */
|
||||
float mat[4][4], size[3], center[3];
|
||||
BKE_boundbox_calc_size_aabb(bbox, size);
|
||||
BKE_boundbox_calc_center_aabb(bbox, center);
|
||||
BKE_boundbox_calc_size_aabb(&bbox, size);
|
||||
BKE_boundbox_calc_center_aabb(&bbox, center);
|
||||
unit_m4(mat);
|
||||
copy_v3_v3(mat[3], center);
|
||||
/* Avoid division by 0.0 later. */
|
||||
|
||||
@@ -183,11 +183,11 @@ void ShadowPass::ShadowView::setup(View &view, float3 light_direction, bool forc
|
||||
bool ShadowPass::ShadowView::debug_object_culling(Object *ob)
|
||||
{
|
||||
printf("Test %s\n", ob->id.name);
|
||||
const BoundBox *_bbox = BKE_object_boundbox_get(ob);
|
||||
const BoundBox _bbox = *BKE_object_boundbox_get(ob);
|
||||
for (int p : IndexRange(extruded_frustum_.planes_count)) {
|
||||
float4 plane = extruded_frustum_.planes[p];
|
||||
bool separating_axis = true;
|
||||
for (float3 corner : _bbox->vec) {
|
||||
for (float3 corner : _bbox.vec) {
|
||||
corner = math::transform_point(float4x4(ob->object_to_world), corner);
|
||||
float signed_distance = math::dot(corner, float3(plane)) - plane.w;
|
||||
if (signed_distance <= 0) {
|
||||
|
||||
@@ -730,7 +730,7 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
|
||||
|
||||
static void drw_call_culling_init(DRWCullingState *cull, Object *ob)
|
||||
{
|
||||
const BoundBox *bbox;
|
||||
std::optional<BoundBox> bbox;
|
||||
if (ob != nullptr && (bbox = BKE_object_boundbox_get(ob))) {
|
||||
float corner[3];
|
||||
/* Get BoundSphere center and radius from the BoundBox. */
|
||||
|
||||
@@ -161,8 +161,8 @@ inline void ObjectBounds::sync()
|
||||
|
||||
inline void ObjectBounds::sync(Object &ob)
|
||||
{
|
||||
const BoundBox *bbox = BKE_object_boundbox_get(&ob);
|
||||
if (bbox == nullptr) {
|
||||
const std::optional<BoundBox> bbox = BKE_object_boundbox_get(&ob);
|
||||
if (!bbox) {
|
||||
bounding_sphere.w = -1.0f; /* Disable test. */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1065,14 +1065,14 @@ static void cursor_draw_tiling_preview(const uint gpuattr,
|
||||
Object *ob,
|
||||
const float radius)
|
||||
{
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
const BoundBox bb = *BKE_object_boundbox_get(ob);
|
||||
float orgLoc[3], location[3];
|
||||
int tile_pass = 0;
|
||||
int start[3];
|
||||
int end[3];
|
||||
int cur[3];
|
||||
const float *bbMin = bb->vec[0];
|
||||
const float *bbMax = bb->vec[6];
|
||||
const float *bbMin = bb.vec[0];
|
||||
const float *bbMax = bb.vec[6];
|
||||
const float *step = sd->paint.tile_offset;
|
||||
|
||||
copy_v3_v3(orgLoc, true_location);
|
||||
|
||||
@@ -811,14 +811,14 @@ static blender::float3 paint_init_pivot_mesh(Object *ob)
|
||||
|
||||
static void paint_init_pivot_curves(Object *ob, float location[3])
|
||||
{
|
||||
const BoundBox *bbox = BKE_object_boundbox_get(ob);
|
||||
interp_v3_v3v3(location, bbox->vec[0], bbox->vec[6], 0.5f);
|
||||
const BoundBox bbox = *BKE_object_boundbox_get(ob);
|
||||
interp_v3_v3v3(location, bbox.vec[0], bbox.vec[6], 0.5f);
|
||||
}
|
||||
|
||||
static void paint_init_pivot_grease_pencil(Object *ob, float location[3])
|
||||
{
|
||||
const BoundBox *bbox = BKE_object_boundbox_get(ob);
|
||||
interp_v3_v3v3(location, bbox->vec[0], bbox->vec[6], 0.5f);
|
||||
const BoundBox bbox = *BKE_object_boundbox_get(ob);
|
||||
interp_v3_v3v3(location, bbox.vec[0], bbox.vec[6], 0.5f);
|
||||
}
|
||||
|
||||
void paint_init_pivot(Object *ob, Scene *scene)
|
||||
|
||||
@@ -4044,9 +4044,9 @@ static void do_tiled(Sculpt *sd,
|
||||
SculptSession *ss = ob->sculpt;
|
||||
StrokeCache *cache = ss->cache;
|
||||
const float radius = cache->radius;
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
const float *bbMin = bb->vec[0];
|
||||
const float *bbMax = bb->vec[6];
|
||||
const BoundBox bb = *BKE_object_boundbox_get(ob);
|
||||
const float *bbMin = bb.vec[0];
|
||||
const float *bbMax = bb.vec[6];
|
||||
const float *step = sd->paint.tile_offset;
|
||||
|
||||
/* These are integer locations, for real location: multiply with step and add orgLoc.
|
||||
|
||||
@@ -796,10 +796,9 @@ static void view3d_ob_drop_matrix_from_snap(V3DSnapCursorState *snap_state,
|
||||
mat4_to_size(scale, ob->object_to_world);
|
||||
rescale_m4(obmat_final, scale);
|
||||
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
if (bb) {
|
||||
if (const std::optional<BoundBox> bb = BKE_object_boundbox_get(ob)) {
|
||||
float offset[3];
|
||||
BKE_boundbox_calc_center_aabb(bb, offset);
|
||||
BKE_boundbox_calc_center_aabb(&bb.value(), offset);
|
||||
offset[2] = bb->vec[0][2];
|
||||
mul_mat3_m4_v3(obmat_final, offset);
|
||||
sub_v3_v3(obmat_final[3], offset);
|
||||
|
||||
@@ -898,12 +898,12 @@ static int gizmo_3d_foreach_selected(const bContext *C,
|
||||
}
|
||||
|
||||
/* Get the boundbox out of the evaluated object. */
|
||||
const BoundBox *bb = nullptr;
|
||||
std::optional<BoundBox> bb;
|
||||
if (use_only_center == false) {
|
||||
bb = BKE_object_boundbox_get(base->object);
|
||||
}
|
||||
|
||||
if (use_only_center || (bb == nullptr)) {
|
||||
if (use_only_center || !bb) {
|
||||
user_fn(base->object->object_to_world[3]);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1316,7 +1316,7 @@ static void snap_source_closest_fn(TransInfo *t)
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td;
|
||||
for (td = tc->data, i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
|
||||
const BoundBox *bb = nullptr;
|
||||
std::optional<BoundBox> bb;
|
||||
|
||||
if ((t->options & CTX_OBMODE_XFORM_OBDATA) == 0) {
|
||||
bb = BKE_object_boundbox_get(td->ob);
|
||||
|
||||
@@ -99,7 +99,7 @@ const Imath::Box3d &ABCAbstractWriter::bounding_box() const
|
||||
|
||||
void ABCAbstractWriter::update_bounding_box(Object *object)
|
||||
{
|
||||
const BoundBox *bb = BKE_object_boundbox_get(object);
|
||||
const std::optional<BoundBox> bb = BKE_object_boundbox_get(object);
|
||||
|
||||
if (!bb) {
|
||||
if (object->type != OB_CAMERA) {
|
||||
|
||||
@@ -116,8 +116,8 @@ void transform_object(Object *object, const OBJImportParams &import_params)
|
||||
if (import_params.clamp_size != 0.0f) {
|
||||
float3 max_coord(-INT_MAX);
|
||||
float3 min_coord(INT_MAX);
|
||||
BoundBox *bb = BKE_mesh_boundbox_get(object);
|
||||
for (const float(&vertex)[3] : bb->vec) {
|
||||
const BoundBox bb = BKE_mesh_boundbox_get(object);
|
||||
for (const float(&vertex)[3] : bb.vec) {
|
||||
for (int axis = 0; axis < 3; axis++) {
|
||||
max_coord[axis] = max_ff(max_coord[axis], vertex[axis]);
|
||||
min_coord[axis] = min_ff(min_coord[axis], vertex[axis]);
|
||||
|
||||
@@ -1990,8 +1990,7 @@ static void rna_Object_shaderfx_clear(Object *object, bContext *C)
|
||||
static void rna_Object_boundbox_get(PointerRNA *ptr, float *values)
|
||||
{
|
||||
Object *ob = reinterpret_cast<Object *>(ptr->owner_id);
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
if (bb) {
|
||||
if (const std::optional<BoundBox> bb = BKE_object_boundbox_get(ob)) {
|
||||
memcpy(values, bb->vec, sizeof(bb->vec));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -608,7 +608,7 @@ static void rna_Object_ray_cast(Object *ob,
|
||||
}
|
||||
|
||||
/* Test BoundBox first (efficiency) */
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
const std::optional<BoundBox> bb = BKE_object_boundbox_get(ob);
|
||||
float distmin;
|
||||
|
||||
/* Needed for valid distance check from #isect_ray_aabb_v3_simple() call. */
|
||||
|
||||
@@ -853,10 +853,7 @@ void RE_point_density_minmax(Depsgraph *depsgraph,
|
||||
}
|
||||
else {
|
||||
const float radius[3] = {pd->radius, pd->radius, pd->radius};
|
||||
const BoundBox *bb = BKE_object_boundbox_get(object);
|
||||
|
||||
if (bb != nullptr) {
|
||||
BLI_assert((bb->flag & BOUNDBOX_DIRTY) == 0);
|
||||
if (const std::optional<BoundBox> bb = BKE_object_boundbox_get(object)) {
|
||||
copy_v3_v3(r_min, bb->vec[0]);
|
||||
copy_v3_v3(r_max, bb->vec[6]);
|
||||
/* Adjust texture space to include density points on the boundaries. */
|
||||
|
||||
Reference in New Issue
Block a user