Fix some inconsistencies in object visibility/selectability tests.
[blender.git] / source / blender / editors / object / object_utils.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/editors/object/object_utils.c
22  *  \ingroup edobj
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "DNA_anim_types.h"
29 #include "DNA_armature_types.h"
30 #include "DNA_meta_types.h"
31 #include "DNA_object_types.h"
32 #include "DNA_scene_types.h"
33 #include "DNA_collection_types.h"
34
35 #include "BLI_math.h"
36 #include "BLI_utildefines.h"
37
38 #include "BKE_action.h"
39 #include "BKE_editmesh.h"
40 #include "BKE_lattice.h"
41
42 #include "WM_types.h"
43
44 #include "ED_armature.h"
45 #include "ED_curve.h"
46 #include "ED_object.h"  /* own include */
47
48
49 /* -------------------------------------------------------------------- */
50 /** \name Active Element Center
51  * \{ */
52
53 bool ED_object_calc_active_center_for_editmode(
54         Object *obedit, const bool select_only, float r_center[3])
55 {
56         switch (obedit->type) {
57                 case OB_MESH:
58                 {
59                         BMEditMesh *em = BKE_editmesh_from_object(obedit);
60                         BMEditSelection ese;
61
62                         if (BM_select_history_active_get(em->bm, &ese)) {
63                                 BM_editselection_center(&ese, r_center);
64                                 return true;
65                         }
66                         break;
67                 }
68                 case OB_ARMATURE:
69                 {
70                         bArmature *arm = obedit->data;
71                         EditBone *ebo = arm->act_edbone;
72
73                         if (ebo && (!select_only || (ebo->flag & (BONE_SELECTED | BONE_ROOTSEL)))) {
74                                 copy_v3_v3(r_center, ebo->head);
75                                 return true;
76                         }
77
78                         break;
79                 }
80                 case OB_CURVE:
81                 case OB_SURF:
82                 {
83                         Curve *cu = obedit->data;
84
85                         if (ED_curve_active_center(cu, r_center)) {
86                                 return true;
87                         }
88                         break;
89                 }
90                 case OB_MBALL:
91                 {
92                         MetaBall *mb = obedit->data;
93                         MetaElem *ml_act = mb->lastelem;
94
95                         if (ml_act && (!select_only || (ml_act->flag & SELECT))) {
96                                 copy_v3_v3(r_center, &ml_act->x);
97                                 return true;
98                         }
99                         break;
100                 }
101                 case OB_LATTICE:
102                 {
103                         BPoint *actbp = BKE_lattice_active_point_get(obedit->data);
104
105                         if (actbp) {
106                                 copy_v3_v3(r_center, actbp->vec);
107                                 return true;
108                         }
109                         break;
110                 }
111         }
112
113         return false;
114 }
115
116 bool ED_object_calc_active_center_for_posemode(
117         Object *ob, const bool select_only, float r_center[3])
118 {
119         bPoseChannel *pchan = BKE_pose_channel_active(ob);
120         if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) {
121                 copy_v3_v3(r_center, pchan->pose_head);
122                 return true;
123         }
124         return false;
125 }
126
127 bool ED_object_calc_active_center(
128         Object *ob, const bool select_only, float r_center[3])
129 {
130         if (ob->mode & OB_MODE_EDIT) {
131                 if (ED_object_calc_active_center_for_editmode(ob, select_only, r_center)) {
132                         mul_m4_v3(ob->obmat, r_center);
133                         return true;
134                 }
135                 return false;
136         }
137         else if (ob->mode & OB_MODE_POSE) {
138                 if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
139                         mul_m4_v3(ob->obmat, r_center);
140                         return true;
141                 }
142                 return false;
143         }
144         else {
145                 if (!select_only || (ob->flag & SELECT)) {
146                         copy_v3_v3(r_center, ob->obmat[3]);
147                         return true;
148                 }
149                 return false;
150         }
151 }
152
153 /** \} */