Fix T90808: wrong BoundBox after undo curve selection
There are two functions that recalculate the boundbox of an object: - One that considers the evaluated geometry - Another that only considers the object's `data`. Most of the time, the bound box is calculated on the final object (with modifiers), so it doesn't seem right to just rely on `ob->data` to recalculate the `ob->runtime.bb`. Be sure to calculate the BoundBox based on the final geometry and only use `ob->data` as a fallback Differential Revision: https://developer.blender.org/D12282
This commit is contained in:
parent
7a7ae4df43
commit
752c6d668b
Notes:
blender-bot
2023-02-14 07:08:26 +01:00
Referenced by commit dae9917915
, Fix T93384: Objects with Constraints to curves have wrong locations on file load
Referenced by issue #94282, Geometry Nodes causes insane dimension property
Referenced by issue #94113, Local view + Geometry Nodes is broken for instances
Referenced by issue #93384, Regression: objects with Constraints to curves have wrong locations on file load (curve boundingbox problem)
Referenced by issue #90808, BoundBox/Dimensions of curve not showing correct values
|
@ -240,6 +240,7 @@ void BKE_object_dimensions_set(struct Object *ob, const float value[3], int axis
|
|||
void BKE_object_empty_draw_type_set(struct Object *ob, const int value);
|
||||
void BKE_object_boundbox_flag(struct Object *ob, int flag, const bool set);
|
||||
void BKE_object_boundbox_calc_from_mesh(struct Object *ob, const struct Mesh *me_eval);
|
||||
bool BKE_object_boundbox_calc_from_evaluated_geometry(struct Object *ob);
|
||||
void BKE_object_minmax(struct Object *ob, float r_min[3], float r_max[3], const bool use_hidden);
|
||||
bool BKE_object_minmax_dupli(struct Depsgraph *depsgraph,
|
||||
struct Scene *scene,
|
||||
|
|
|
@ -66,8 +66,6 @@
|
|||
|
||||
using blender::IndexRange;
|
||||
|
||||
static void boundbox_displist_object(Object *ob);
|
||||
|
||||
static void displist_elem_free(DispList *dl)
|
||||
{
|
||||
if (dl) {
|
||||
|
@ -1528,7 +1526,9 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
|
|||
ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry));
|
||||
}
|
||||
|
||||
boundbox_displist_object(ob);
|
||||
if (ob->runtime.bb) {
|
||||
ob->runtime.bb->flag |= BOUNDBOX_DIRTY;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_displist_minmax(const ListBase *dispbase, float min[3], float max[3])
|
||||
|
@ -1551,30 +1551,3 @@ void BKE_displist_minmax(const ListBase *dispbase, float min[3], float max[3])
|
|||
zero_v3(max);
|
||||
}
|
||||
}
|
||||
|
||||
/* this is confusing, there's also min_max_object, applying the obmat... */
|
||||
static void boundbox_displist_object(Object *ob)
|
||||
{
|
||||
BLI_assert(ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT));
|
||||
/* Curve's BB is already calculated as a part of modifier stack,
|
||||
* here we only calculate object BB based on final display list. */
|
||||
|
||||
/* object's BB is calculated from final displist */
|
||||
if (ob->runtime.bb == nullptr) {
|
||||
ob->runtime.bb = (BoundBox *)MEM_callocN(sizeof(BoundBox), __func__);
|
||||
}
|
||||
|
||||
const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
|
||||
if (mesh_eval) {
|
||||
BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
|
||||
}
|
||||
else {
|
||||
float min[3], max[3];
|
||||
|
||||
INIT_MINMAX(min, max);
|
||||
BKE_displist_minmax(&ob->runtime.curve_cache->disp, min, max);
|
||||
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
|
||||
|
||||
ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3965,6 +3965,37 @@ void BKE_object_boundbox_calc_from_mesh(Object *ob, const Mesh *me_eval)
|
|||
ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY;
|
||||
}
|
||||
|
||||
bool BKE_object_boundbox_calc_from_evaluated_geometry(Object *ob)
|
||||
{
|
||||
blender::float3 min, max;
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
if (ob->runtime.geometry_set_eval) {
|
||||
ob->runtime.geometry_set_eval->compute_boundbox_without_instances(&min, &max);
|
||||
}
|
||||
else if (const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob)) {
|
||||
if (!BKE_mesh_wrapper_minmax(mesh_eval, min, max)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (ob->runtime.curve_cache) {
|
||||
BKE_displist_minmax(&ob->runtime.curve_cache->disp, min, max);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ob->runtime.bb == nullptr) {
|
||||
ob->runtime.bb = (BoundBox *)MEM_callocN(sizeof(BoundBox), __func__);
|
||||
}
|
||||
|
||||
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
|
||||
|
||||
ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -282,7 +282,12 @@ 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)
|
||||
{
|
||||
BoundBox *bb = BKE_object_boundbox_get(object_eval);
|
||||
BoundBox *bb = object_eval->runtime.bb;
|
||||
if (!bb || (bb->flag & BOUNDBOX_DIRTY)) {
|
||||
BKE_object_boundbox_calc_from_evaluated_geometry(object_eval);
|
||||
}
|
||||
|
||||
bb = BKE_object_boundbox_get(object_eval);
|
||||
if (bb != NULL) {
|
||||
if (object_orig->runtime.bb == NULL) {
|
||||
object_orig->runtime.bb = MEM_mallocN(sizeof(*object_orig->runtime.bb), __func__);
|
||||
|
|
Loading…
Reference in New Issue