View-Selected: use custom bones boundbox

Support using custom pose-bone transform and object when calculating view bounds.
This commit is contained in:
Campbell Barton 2015-09-04 04:18:49 +10:00
parent 54ad576666
commit c3fef001ee
Notes: blender-bot 2023-02-14 08:41:44 +01:00
Referenced by commit b98a937db6, Fix T99364: Unable to select bones when custom shape display is disabled
Referenced by issue #46009, Render view not updated when Images Draw Method is GLSL
5 changed files with 57 additions and 46 deletions

View File

@ -80,6 +80,8 @@ struct bArmature *BKE_armature_copy(struct bArmature *arm);
/* Bounding box. */
struct BoundBox *BKE_armature_boundbox_get(struct Object *ob);
bool BKE_pose_minmax(struct Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select);
int bone_autoside_name(char name[64], int strip_number, short axis, float head, float tail);
struct Bone *BKE_armature_find_bone_name(struct bArmature *arm, const char *name);

View File

@ -142,6 +142,7 @@ bool BKE_boundbox_ray_hit_check(
float *r_lambda);
void BKE_boundbox_calc_center_aabb(const struct BoundBox *bb, float r_cent[3]);
void BKE_boundbox_calc_size_aabb(const struct BoundBox *bb, float r_size[3]);
void BKE_boundbox_minmax(const struct BoundBox *bb, float obmat[4][4], float r_min[3], float r_max[3]);
struct BoundBox *BKE_object_boundbox_get(struct Object *ob);
void BKE_object_dimensions_get(struct Object *ob, float vec[3]);

View File

@ -2209,6 +2209,45 @@ BoundBox *BKE_armature_boundbox_get(Object *ob)
return ob->bb;
}
bool BKE_pose_minmax(Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select)
{
bool changed = false;
if (ob->pose) {
bArmature *arm = ob->data;
bPoseChannel *pchan;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment
* (editarmature.c:2592)... Skip in this case too! */
if (pchan->bone &&
(!((use_hidden == false) && (PBONE_VISIBLE(arm, pchan->bone) == false)) &&
!((use_select == true) && ((pchan->bone->flag & BONE_SELECTED) == 0))))
{
bPoseChannel *pchan_tx = (pchan->custom && pchan->custom_tx) ? pchan->custom_tx : pchan;
BoundBox *bb_custom = pchan->custom ? BKE_object_boundbox_get(pchan->custom) : NULL;
if (bb_custom) {
float mat[4][4];
mul_m4_m4m4(mat, ob->obmat, pchan_tx->pose_mat);
BKE_boundbox_minmax(bb_custom, mat, r_min, r_max);
}
else {
float vec[3];
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
minmax_v3v3_v3(r_min, r_max, vec);
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
minmax_v3v3_v3(r_min, r_max, vec);
}
changed = true;
}
}
}
return changed;
}
/************** Graph evaluation ********************/
bPoseChannel *BKE_armature_ik_solver_find_root(

View File

@ -2655,6 +2655,16 @@ void BKE_boundbox_calc_size_aabb(const BoundBox *bb, float r_size[3])
r_size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]);
}
void BKE_boundbox_minmax(const BoundBox *bb, float obmat[4][4], float r_min[3], float r_max[3])
{
int i;
for (i = 0; i < 8; i++) {
float vec[3];
mul_v3_m4v3(vec, obmat, bb->vec[i]);
minmax_v3v3_v3(r_min, r_max, vec);
}
}
BoundBox *BKE_object_boundbox_get(Object *ob)
{
BoundBox *bb = NULL;
@ -2730,7 +2740,6 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us
{
BoundBox bb;
float vec[3];
int a;
bool changed = false;
switch (ob->type) {
@ -2739,11 +2748,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us
case OB_SURF:
{
bb = *BKE_curve_boundbox_get(ob);
for (a = 0; a < 8; a++) {
mul_m4_v3(ob->obmat, bb.vec[a]);
minmax_v3v3_v3(min_r, max_r, bb.vec[a]);
}
BKE_boundbox_minmax(&bb, ob->obmat, min_r, max_r);
changed = true;
break;
}
@ -2766,23 +2771,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us
}
case OB_ARMATURE:
{
if (ob->pose) {
bArmature *arm = ob->data;
bPoseChannel *pchan;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment
* (editarmature.c:2592)... Skip in this case too! */
if (pchan->bone && !((use_hidden == false) && (PBONE_VISIBLE(arm, pchan->bone) == false))) {
mul_v3_m4v3(vec, ob->obmat, pchan->pose_head);
minmax_v3v3_v3(min_r, max_r, vec);
mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail);
minmax_v3v3_v3(min_r, max_r, vec);
changed = true;
}
}
}
changed = BKE_pose_minmax(ob, min_r, max_r, use_hidden, false);
break;
}
case OB_MESH:
@ -2791,11 +2780,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us
if (me) {
bb = *BKE_mesh_boundbox_get(ob);
for (a = 0; a < 8; a++) {
mul_m4_v3(ob->obmat, bb.vec[a]);
minmax_v3v3_v3(min_r, max_r, bb.vec[a]);
}
BKE_boundbox_minmax(&bb, ob->obmat, min_r, max_r);
changed = true;
}
break;

View File

@ -44,6 +44,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_armature.h"
#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_font.h"
@ -3042,24 +3043,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
ok = ED_view3d_minmax_verts(obedit, min, max); /* only selected */
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
if (ob->pose) {
bArmature *arm = ob->data;
bPoseChannel *pchan;
float vec[3];
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->flag & BONE_SELECTED) {
if (pchan->bone->layer & arm->layer) {
bPoseChannel *pchan_tx = pchan->custom_tx ? pchan->custom_tx : pchan;
ok = 1;
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
minmax_v3v3_v3(min, max, vec);
mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
minmax_v3v3_v3(min, max, vec);
}
}
}
}
ok = BKE_pose_minmax(ob, min, max, true, true);
}
else if (BKE_paint_select_face_test(ob)) {
ok = paintface_minmax(ob, min, max);