diff --git a/source/blender/blenkernel/BKE_object.hh b/source/blender/blenkernel/BKE_object.hh index e6bf896a005..98450274df3 100644 --- a/source/blender/blenkernel/BKE_object.hh +++ b/source/blender/blenkernel/BKE_object.hh @@ -347,8 +347,24 @@ void BKE_boundbox_minmax(const BoundBox *bb, float r_min[3], float r_max[3]); +/** + * Retrieve the bounds of the object's geometry, in the local space of the object + * (not accounting for the object's transform). For evaluated objects, this includes + * the evaluated geometry (not just #Object.data). + */ std::optional BKE_object_boundbox_get(Object *ob); void BKE_object_dimensions_get(Object *ob, float r_vec[3]); + +/** + * Retrieve the bounds of the evalauted object's geometry, stored on the original object as part of + * the latest dependency graph evaluation, or fall back to the current bounds of the object if no + * such cache exists. For evaluated objects this indirection is unnecessary, so + * #BKE_object_boundbox_get should be used instead. + */ +std::optional BKE_object_boundbox_eval_cached_get(Object *ob); +/** Similar to #BKE_object_boundbox_eval_cached_get but gives the size of the bounds instead. */ +void BKE_object_dimensions_eval_cached_get(Object *ob, float r_vec[3]); + /** * The original scale and object matrix can be passed in so any difference * of the objects matrix and the final matrix can be accounted for, diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index ed3ff6bb3ce..43528d995b3 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -3591,6 +3591,14 @@ std::optional BKE_object_boundbox_get(Object *ob) return std::nullopt; } +std::optional BKE_object_boundbox_eval_cached_get(Object *ob) +{ + if (ob->runtime.bb) { + return *ob->runtime.bb; + } + return BKE_object_boundbox_get(ob); +} + void BKE_object_boundbox_calc_from_mesh(Object *ob, const Mesh *me_eval) { float3 min(FLT_MAX); @@ -3652,9 +3660,11 @@ bool BKE_object_boundbox_calc_from_evaluated_geometry(Object *ob) * \warning Setting dimensions is prone to feedback loops in evaluation. * \{ */ -void BKE_object_dimensions_get(Object *ob, float r_vec[3]) +static void boundbox_to_dimensions(const Object *ob, + const std::optional bb, + float r_vec[3]) { - if (const std::optional bb = BKE_object_boundbox_get(ob)) { + if (bb) { float3 scale; mat4_to_size(scale, ob->object_to_world); @@ -3667,6 +3677,16 @@ void BKE_object_dimensions_get(Object *ob, float r_vec[3]) } } +void BKE_object_dimensions_get(Object *ob, float r_vec[3]) +{ + boundbox_to_dimensions(ob, BKE_object_boundbox_get(ob), r_vec); +} + +void BKE_object_dimensions_eval_cached_get(Object *ob, float r_vec[3]) +{ + boundbox_to_dimensions(ob, BKE_object_boundbox_eval_cached_get(ob), r_vec); +} + void BKE_object_dimensions_set_ex(Object *ob, const float value[3], int axis_mask, diff --git a/source/blender/editors/space_view3d/space_view3d.cc b/source/blender/editors/space_view3d/space_view3d.cc index d8bd38dce15..e06147f4b25 100644 --- a/source/blender/editors/space_view3d/space_view3d.cc +++ b/source/blender/editors/space_view3d/space_view3d.cc @@ -511,7 +511,7 @@ static void view3d_ob_drop_on_enter(wmDropBox *drop, wmDrag *drag) float dimensions[3] = {0.0f}; if (drag->type == WM_DRAG_ID) { Object *ob = (Object *)WM_drag_get_local_ID(drag, ID_OB); - BKE_object_dimensions_get(ob, dimensions); + BKE_object_dimensions_eval_cached_get(ob, dimensions); } else { AssetMetaData *meta_data = WM_drag_get_asset_meta_data(drag, ID_OB); diff --git a/source/blender/editors/space_view3d/view3d_buttons.cc b/source/blender/editors/space_view3d/view3d_buttons.cc index 2065678e16c..296b1a4d792 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.cc +++ b/source/blender/editors/space_view3d/view3d_buttons.cc @@ -1237,7 +1237,7 @@ static void v3d_object_dimension_buts(bContext *C, uiLayout *layout, View3D *v3d const int butw = 200; const int buth = 20 * UI_SCALE_FAC; - BKE_object_dimensions_get(ob, tfp->ob_dims); + BKE_object_dimensions_eval_cached_get(ob, tfp->ob_dims); copy_v3_v3(tfp->ob_dims_orig, tfp->ob_dims); copy_v3_v3(tfp->ob_scale_orig, ob->scale); copy_m4_m4(tfp->ob_obmat_orig, ob->object_to_world); diff --git a/source/blender/makesrna/intern/rna_object.cc b/source/blender/makesrna/intern/rna_object.cc index 621305f695c..328d5d51d37 100644 --- a/source/blender/makesrna/intern/rna_object.cc +++ b/source/blender/makesrna/intern/rna_object.cc @@ -1233,7 +1233,7 @@ static void rna_Object_rotation_mode_set(PointerRNA *ptr, int value) static void rna_Object_dimensions_get(PointerRNA *ptr, float *value) { Object *ob = static_cast(ptr->data); - BKE_object_dimensions_get(ob, value); + BKE_object_dimensions_eval_cached_get(ob, value); } static void rna_Object_dimensions_set(PointerRNA *ptr, const float *value) @@ -1990,7 +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(ptr->owner_id); - if (const std::optional bb = BKE_object_boundbox_get(ob)) { + if (const std::optional bb = BKE_object_boundbox_eval_cached_get(ob)) { memcpy(values, bb->vec, sizeof(bb->vec)); } else {