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:
@@ -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_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_flag(struct Object *ob, int flag, const bool set);
|
||||||
void BKE_object_boundbox_calc_from_mesh(struct Object *ob, const struct Mesh *me_eval);
|
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);
|
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,
|
bool BKE_object_minmax_dupli(struct Depsgraph *depsgraph,
|
||||||
struct Scene *scene,
|
struct Scene *scene,
|
||||||
|
|||||||
@@ -66,8 +66,6 @@
|
|||||||
|
|
||||||
using blender::IndexRange;
|
using blender::IndexRange;
|
||||||
|
|
||||||
static void boundbox_displist_object(Object *ob);
|
|
||||||
|
|
||||||
static void displist_elem_free(DispList *dl)
|
static void displist_elem_free(DispList *dl)
|
||||||
{
|
{
|
||||||
if (dl) {
|
if (dl) {
|
||||||
@@ -1528,7 +1526,9 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
|
|||||||
ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry));
|
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])
|
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);
|
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;
|
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. */
|
/** Bounding box from evaluated geometry. */
|
||||||
static void object_sync_boundbox_to_original(Object *object_orig, Object *object_eval)
|
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 (bb != NULL) {
|
||||||
if (object_orig->runtime.bb == NULL) {
|
if (object_orig->runtime.bb == NULL) {
|
||||||
object_orig->runtime.bb = MEM_mallocN(sizeof(*object_orig->runtime.bb), __func__);
|
object_orig->runtime.bb = MEM_mallocN(sizeof(*object_orig->runtime.bb), __func__);
|
||||||
|
|||||||
Reference in New Issue
Block a user