diff --git a/source/blender/blenkernel/BKE_armature.hh b/source/blender/blenkernel/BKE_armature.hh index 7df93c38b70..62061e8684e 100644 --- a/source/blender/blenkernel/BKE_armature.hh +++ b/source/blender/blenkernel/BKE_armature.hh @@ -155,7 +155,10 @@ void BKE_armature_copy_bone_transforms(bArmature *armature_dst, const bArmature void BKE_armature_transform(bArmature *arm, const float mat[4][4], bool do_props); -std::optional> BKE_armature_min_max(const bPose *pose); +/** + * Return the posed Armature bounding box in object-local coordinate space. + */ +std::optional> BKE_armature_min_max(const Object *ob); /** * Calculate the axis-aligned bounds of `pchan` in world-space, diff --git a/source/blender/blenkernel/intern/armature.cc b/source/blender/blenkernel/intern/armature.cc index a5d28c6b92e..2da4971837c 100644 --- a/source/blender/blenkernel/intern/armature.cc +++ b/source/blender/blenkernel/intern/armature.cc @@ -22,6 +22,7 @@ #include "BLI_listbase.h" #include "BLI_math_geom.h" #include "BLI_math_matrix.h" +#include "BLI_math_matrix.hh" #include "BLI_math_rotation.h" #include "BLI_math_vector.h" #include "BLI_span.hh" @@ -3020,21 +3021,23 @@ void BKE_pose_where_is(Depsgraph *depsgraph, Scene *scene, Object *ob) /** \name Calculate Bounding Box (Armature & Pose) * \{ */ -std::optional> BKE_armature_min_max(const bPose *pose) +std::optional> BKE_armature_min_max(const Object *ob) { - if (BLI_listbase_is_empty(&pose->chanbase)) { - return std::nullopt; - } + BLI_assert(ob->data); + BLI_assert(ob->type == OB_ARMATURE); + BLI_assert(GS(static_cast(ob->data)->name) == ID_AR); + blender::float3 min(std::numeric_limits::max()); blender::float3 max(std::numeric_limits::lowest()); - /* For now, we assume BKE_pose_where_is has already been called - * (hence we have valid data in pachan). */ - LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) { - minmax_v3v3_v3(min, max, pchan->pose_head); - minmax_v3v3_v3(min, max, pchan->pose_tail); + + const bool has_minmax = BKE_pose_minmax(ob, &min[0], &max[0], false, false); + + if (!has_minmax) { + return std::nullopt; } - return blender::Bounds{min, max}; + return blender::Bounds{math::transform_point(ob->world_to_object(), min), + math::transform_point(ob->world_to_object(), max)}; } void BKE_pchan_minmax(const Object *ob, diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 49bb0c0bea0..0e25e24974c 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -3569,7 +3569,7 @@ std::optional> BKE_object_boundbox_get(const Ob case OB_LATTICE: return BKE_lattice_minmax(static_cast(ob->data)); case OB_ARMATURE: - return BKE_armature_min_max(ob->pose); + return BKE_armature_min_max(ob); case OB_GPENCIL_LEGACY: return BKE_gpencil_data_minmax(static_cast(ob->data)); case OB_CURVES: diff --git a/source/blender/editors/transform/transform_snap_object_armature.cc b/source/blender/editors/transform/transform_snap_object_armature.cc index e26e3837f51..9947c941f58 100644 --- a/source/blender/editors/transform/transform_snap_object_armature.cc +++ b/source/blender/editors/transform/transform_snap_object_armature.cc @@ -39,8 +39,7 @@ eSnapMode snapArmature(SnapObjectContext *sctx, const bool is_editmode = arm->edbo != nullptr; if (is_editmode == false) { - const std::optional> bounds = BKE_armature_min_max( - ob_eval->pose); + const std::optional> bounds = BKE_armature_min_max(ob_eval); if (bounds && !nearest2d.snap_boundbox(bounds->min, bounds->max)) { return retval; }