Fix #114870: Object dimensions does not used evaluated geometry

Refactoring of object bounds to make evaluated to original syncing
more explicit wasn't accounted for yet. This was a mistake in the most
recent refactor 1cbd0f5a85.

To fix this, add separate functions to account for `runtime.bb` which
is the data synced from the evalauted object to the original. In future
refactors, `runtime.bb` will be changed more, including a more helpful
name that reflects this purpose.

Pull Request: https://projects.blender.org/blender/blender/pulls/114897
This commit is contained in:
Hans Goudey 2023-11-15 11:03:04 +01:00 committed by Hans Goudey
parent d7b7938706
commit 14eb08c3a5
5 changed files with 42 additions and 6 deletions

View File

@ -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<BoundBox> 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<BoundBox> 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,

View File

@ -3591,6 +3591,14 @@ std::optional<BoundBox> BKE_object_boundbox_get(Object *ob)
return std::nullopt;
}
std::optional<BoundBox> 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<BoundBox> bb,
float r_vec[3])
{
if (const std::optional<BoundBox> 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,

View File

@ -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);

View File

@ -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);

View File

@ -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<Object *>(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<Object *>(ptr->owner_id);
if (const std::optional<BoundBox> bb = BKE_object_boundbox_get(ob)) {
if (const std::optional<BoundBox> bb = BKE_object_boundbox_eval_cached_get(ob)) {
memcpy(values, bb->vec, sizeof(bb->vec));
}
else {