Blender  V2.93
object_utils.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "DNA_anim_types.h"
25 #include "DNA_armature_types.h"
26 #include "DNA_collection_types.h"
27 #include "DNA_meta_types.h"
28 #include "DNA_object_types.h"
29 #include "DNA_scene_types.h"
30 
31 #include "BLI_listbase.h"
32 #include "BLI_math.h"
33 #include "BLI_utildefines.h"
34 
35 #include "BKE_action.h"
36 #include "BKE_armature.h"
37 #include "BKE_editmesh.h"
38 #include "BKE_lattice.h"
39 #include "BKE_scene.h"
40 
41 #include "DEG_depsgraph_query.h"
42 
43 #include "WM_types.h"
44 
45 #include "ED_curve.h"
46 #include "ED_object.h" /* own include */
47 
48 #include "MEM_guardedalloc.h"
49 
50 /* -------------------------------------------------------------------- */
55  const bool select_only,
56  float r_center[3])
57 {
58  switch (obedit->type) {
59  case OB_MESH: {
61  BMEditSelection ese;
62 
63  if (BM_select_history_active_get(em->bm, &ese)) {
64  BM_editselection_center(&ese, r_center);
65  return true;
66  }
67  break;
68  }
69  case OB_ARMATURE: {
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  Curve *cu = obedit->data;
83 
84  if (ED_curve_active_center(cu, r_center)) {
85  return true;
86  }
87  break;
88  }
89  case OB_MBALL: {
90  MetaBall *mb = obedit->data;
91  MetaElem *ml_act = mb->lastelem;
92 
93  if (ml_act && (!select_only || (ml_act->flag & SELECT))) {
94  copy_v3_v3(r_center, &ml_act->x);
95  return true;
96  }
97  break;
98  }
99  case OB_LATTICE: {
100  BPoint *actbp = BKE_lattice_active_point_get(obedit->data);
101 
102  if (actbp) {
103  copy_v3_v3(r_center, actbp->vec);
104  return true;
105  }
106  break;
107  }
108  }
109 
110  return false;
111 }
112 
114  const bool select_only,
115  float r_center[3])
116 {
118  if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) {
119  copy_v3_v3(r_center, pchan->pose_head);
120  return true;
121  }
122  return false;
123 }
124 
125 bool ED_object_calc_active_center(Object *ob, const bool select_only, float r_center[3])
126 {
127  if (ob->mode & OB_MODE_EDIT) {
128  if (ED_object_calc_active_center_for_editmode(ob, select_only, r_center)) {
129  mul_m4_v3(ob->obmat, r_center);
130  return true;
131  }
132  return false;
133  }
134  if (ob->mode & OB_MODE_POSE) {
135  if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
136  mul_m4_v3(ob->obmat, r_center);
137  return true;
138  }
139  return false;
140  }
141  if (!select_only || (ob->base_flag & BASE_SELECTED)) {
142  copy_v3_v3(r_center, ob->obmat[3]);
143  return true;
144  }
145  return false;
146 }
147 
150 /* -------------------------------------------------------------------- */
162 };
163 
165  float obmat_orig[4][4];
166  float parent_obmat_orig[4][4];
169  float parentinv_orig[4][4];
171  int mode;
172 };
173 
175 {
176  struct XFormObjectSkipChild_Container *xcs = MEM_callocN(sizeof(*xcs), __func__);
177  if (xcs->obchild_in_obmode_map == NULL) {
178  xcs->obchild_in_obmode_map = BLI_ghash_ptr_new(__func__);
179  }
180  return xcs;
181 }
182 
184  struct XFormObjectSkipChild_Container *xcs,
185  ViewLayer *view_layer,
186  Object **objects,
187  uint objects_len)
188 {
189  GSet *objects_in_transdata = BLI_gset_ptr_new_ex(__func__, objects_len);
190  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
191  Object *ob = objects[ob_index];
192  BLI_gset_add(objects_in_transdata, ob);
193  }
194 
195  LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
196  Object *ob = base->object;
197  if (ob->parent != NULL) {
198  if (!BLI_gset_haskey(objects_in_transdata, ob)) {
199  if (BLI_gset_haskey(objects_in_transdata, ob->parent)) {
202  }
203  }
204  else {
205  if (!BLI_gset_haskey(objects_in_transdata, ob->parent)) {
206  Object *ob_parent_recurse = ob->parent;
207  if (ob_parent_recurse != NULL) {
208  while (ob_parent_recurse != NULL) {
209  if (BLI_gset_haskey(objects_in_transdata, ob_parent_recurse)) {
210  break;
211  }
212  ob_parent_recurse = ob_parent_recurse->parent;
213  }
214 
215  if (ob_parent_recurse) {
217  xcs, ob, ob_parent_recurse, XFORM_OB_SKIP_CHILD_PARENT_APPLY);
218  }
219  }
220  }
221  }
222  }
223  }
224 
225  LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
226  Object *ob = base->object;
227 
228  if (BLI_gset_haskey(objects_in_transdata, ob)) {
229  /* pass. */
230  }
231  else if (ob->parent != NULL) {
232  if (BLI_gset_haskey(objects_in_transdata, ob->parent)) {
233  if (!BLI_gset_haskey(objects_in_transdata, ob)) {
236  }
237  }
238  }
239  }
240  BLI_gset_free(objects_in_transdata, NULL);
241 }
242 
244 {
246  MEM_freeN(xcs);
247 }
248 
250  Object *ob,
251  Object *ob_parent_recurse,
252  int mode)
253 {
254  void **xf_p;
255  if (!BLI_ghash_ensure_p(xcs->obchild_in_obmode_map, ob, &xf_p)) {
256  struct XFormObjectSkipChild *xf = MEM_mallocN(sizeof(*xf), __func__);
258  copy_m4_m4(xf->obmat_orig, ob->obmat);
261  if (ob_parent_recurse) {
263  }
264  xf->mode = mode;
266  *xf_p = xf;
267  }
268 }
269 
271  struct Main *bmain,
272  struct Depsgraph *depsgraph)
273 {
275 
276  GHashIterator gh_iter;
277  GHASH_ITER (gh_iter, xcs->obchild_in_obmode_map) {
278  Object *ob = BLI_ghashIterator_getKey(&gh_iter);
279  struct XFormObjectSkipChild *xf = BLI_ghashIterator_getValue(&gh_iter);
280 
281  /* The following blocks below assign 'dmat'. */
282  float dmat[4][4];
283 
285  /* Parent is transformed, this isn't so compensate. */
286  Object *ob_parent_eval = DEG_get_evaluated_object(depsgraph, ob->parent);
287  mul_m4_m4m4(dmat, xf->parent_obmat_inv_orig, ob_parent_eval->obmat);
288  invert_m4(dmat);
289  }
291  /* Calculate parent matrix (from the root transform). */
292  Object *ob_parent_recurse_eval = DEG_get_evaluated_object(depsgraph, xf->ob_parent_recurse);
293  float parent_recurse_obmat_inv[4][4];
294  invert_m4_m4(parent_recurse_obmat_inv, ob_parent_recurse_eval->obmat);
295  mul_m4_m4m4(dmat, xf->parent_recurse_obmat_orig, parent_recurse_obmat_inv);
296  invert_m4(dmat);
297  float parent_obmat_calc[4][4];
298  mul_m4_m4m4(parent_obmat_calc, dmat, xf->parent_obmat_orig);
299 
300  /* Apply to the parent inverse matrix. */
301  mul_m4_m4m4(dmat, xf->parent_obmat_inv_orig, parent_obmat_calc);
302  invert_m4(dmat);
303  }
304  else {
306  /* Transform this - without transform data. */
307  Object *ob_parent_recurse_eval = DEG_get_evaluated_object(depsgraph, xf->ob_parent_recurse);
308  float parent_recurse_obmat_inv[4][4];
309  invert_m4_m4(parent_recurse_obmat_inv, ob_parent_recurse_eval->obmat);
310  mul_m4_m4m4(dmat, xf->parent_recurse_obmat_orig, parent_recurse_obmat_inv);
311  invert_m4(dmat);
312  float obmat_calc[4][4];
313  mul_m4_m4m4(obmat_calc, dmat, xf->obmat_orig);
314  /* obmat_calc is just obmat. */
315 
316  /* Get the matrices relative to the parent. */
317  float obmat_parent_relative_orig[4][4];
318  float obmat_parent_relative_calc[4][4];
319  float obmat_parent_relative_inv_orig[4][4];
320 
321  mul_m4_m4m4(obmat_parent_relative_orig, xf->parent_obmat_inv_orig, xf->obmat_orig);
322  mul_m4_m4m4(obmat_parent_relative_calc, xf->parent_obmat_inv_orig, obmat_calc);
323  invert_m4_m4(obmat_parent_relative_inv_orig, obmat_parent_relative_orig);
324 
325  /* Apply to the parent inverse matrix. */
326  mul_m4_m4m4(dmat, obmat_parent_relative_calc, obmat_parent_relative_inv_orig);
327  }
328 
329  mul_m4_m4m4(ob->parentinv, dmat, xf->parentinv_orig);
330 
332  }
333 }
334 
337 /* -------------------------------------------------------------------- */
346 };
347 
350  float obmat_orig[4][4];
352 };
353 
355 {
356  if (xds->obdata_in_obmode_map == NULL) {
357  xds->obdata_in_obmode_map = BLI_ghash_ptr_new(__func__);
358  }
359 
360  void **xf_p;
361  if (!BLI_ghash_ensure_p(xds->obdata_in_obmode_map, ob->data, &xf_p)) {
362  struct XFormObjectData_Extra *xf = MEM_mallocN(sizeof(*xf), __func__);
363  copy_m4_m4(xf->obmat_orig, ob->obmat);
364  xf->ob = ob;
365  /* Result may be NULL, that's OK. */
367  *xf_p = xf;
368  }
369 }
370 
376  struct Main *bmain,
378 {
379  if (xds->obdata_in_obmode_map == NULL) {
380  return;
381  }
383 
384  GHashIterator gh_iter;
385  GHASH_ITER (gh_iter, xds->obdata_in_obmode_map) {
386  ID *id = BLI_ghashIterator_getKey(&gh_iter);
387  struct XFormObjectData_Extra *xf = BLI_ghashIterator_getValue(&gh_iter);
388  if (xf->xod == NULL) {
389  continue;
390  }
391 
392  Object *ob_eval = DEG_get_evaluated_object(depsgraph, xf->ob);
393  float imat[4][4], dmat[4][4];
394  invert_m4_m4(imat, xf->obmat_orig);
395  mul_m4_m4m4(dmat, imat, ob_eval->obmat);
396  invert_m4(dmat);
397 
399  if (xf->ob->type == OB_ARMATURE) {
400  /* TODO: none of the current flags properly update armatures, needs investigation. */
401  DEG_id_tag_update(id, 0);
402  }
403  else {
405  }
406  }
407 }
408 
410 static void trans_obdata_in_obmode_free_elem(void *xf_p)
411 {
412  struct XFormObjectData_Extra *xf = xf_p;
413  if (xf->xod) {
415  }
416  MEM_freeN(xf);
417 }
418 
420 {
421  struct XFormObjectData_Container *xds = MEM_callocN(sizeof(*xds), __func__);
422  xds->obdata_in_obmode_map = BLI_ghash_ptr_new(__func__);
423  return xds;
424 }
425 
427 {
429  MEM_freeN(xds);
430 }
431 
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_active(struct Object *ob)
Definition: action.c:708
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:85
struct BPoint * BKE_lattice_active_point_get(struct Lattice *lt)
Definition: lattice.c:606
void BKE_scene_graph_evaluated_ensure(struct Depsgraph *depsgraph, struct Main *bmain)
Definition: scene.c:2718
#define BLI_assert(a)
Definition: BLI_assert.h:58
struct GSet GSet
Definition: BLI_ghash.h:189
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:146
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:150
#define GHASH_ITER(gh_iter_, ghash_)
Definition: BLI_ghash.h:169
bool BLI_gset_haskey(GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1216
GSet * BLI_gset_ptr_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1253
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:851
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:1160
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
bool invert_m4(float R[4][4])
Definition: math_matrix.c:1187
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
MINLINE void copy_v3_v3(float r[3], const float a[3])
unsigned int uint
Definition: BLI_sys_types.h:83
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update(struct ID *id, int flag)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:599
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ BONE_ROOTSEL
@ BONE_SELECTED
Object groups, one object can be in many groups at once.
@ BASE_SELECTED
@ OB_MODE_EDIT
@ OB_MODE_POSE
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVE
@ XFORM_OB_SKIP_CHILD_PARENT_APPLY
Definition: ED_object.h:105
@ XFORM_OB_SKIP_CHILD_PARENT_IS_XFORM_INDIRECT
Definition: ED_object.h:98
@ XFORM_OB_SKIP_CHILD_PARENT_IS_XFORM
Definition: ED_object.h:93
void ED_object_data_xform_destroy(struct XFormObjectData *xod_base)
void ED_object_data_xform_by_mat4(struct XFormObjectData *xod, const float mat[4][4])
struct XFormObjectData * ED_object_data_xform_create(struct ID *id)
Read Guarded memory(de)allocation.
void BM_editselection_center(BMEditSelection *ese, float r_center[3])
bool BM_select_history_active_get(BMesh *bm, BMEditSelection *ese)
#define SELECT
const Depsgraph * depsgraph
bool ED_curve_active_center(Curve *cu, float center[3])
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
void ED_object_xform_skip_child_container_update_all(struct XFormObjectSkipChild_Container *xcs, struct Main *bmain, struct Depsgraph *depsgraph)
Definition: object_utils.c:270
void ED_object_xform_skip_child_container_destroy(struct XFormObjectSkipChild_Container *xcs)
Definition: object_utils.c:243
struct XFormObjectSkipChild_Container * ED_object_xform_skip_child_container_create(void)
Definition: object_utils.c:174
void ED_object_data_xform_container_update_all(struct XFormObjectData_Container *xds, struct Main *bmain, Depsgraph *depsgraph)
Definition: object_utils.c:375
static void trans_obdata_in_obmode_free_elem(void *xf_p)
Definition: object_utils.c:410
bool ED_object_calc_active_center(Object *ob, const bool select_only, float r_center[3])
Definition: object_utils.c:125
void ED_object_data_xform_container_destroy(struct XFormObjectData_Container *xds)
Definition: object_utils.c:426
bool ED_object_calc_active_center_for_editmode(Object *obedit, const bool select_only, float r_center[3])
Definition: object_utils.c:54
void ED_object_xform_skip_child_container_item_ensure(struct XFormObjectSkipChild_Container *xcs, Object *ob, Object *ob_parent_recurse, int mode)
Definition: object_utils.c:249
void ED_object_data_xform_container_item_ensure(struct XFormObjectData_Container *xds, Object *ob)
Definition: object_utils.c:354
bool ED_object_calc_active_center_for_posemode(Object *ob, const bool select_only, float r_center[3])
Definition: object_utils.c:113
void ED_object_xform_skip_child_container_item_ensure_from_array(struct XFormObjectSkipChild_Container *xcs, ViewLayer *view_layer, Object **objects, uint objects_len)
Definition: object_utils.c:183
struct XFormObjectData_Container * ED_object_data_xform_container_create(void)
Definition: object_utils.c:419
struct BMesh * bm
Definition: BKE_editmesh.h:52
float vec[4]
float head[3]
Definition: BKE_armature.h:65
Definition: DNA_ID.h:273
Definition: BKE_main.h:116
MetaElem * lastelem
short flag
short base_flag
float parentinv[4][4]
float obmat[4][4]
struct Object * parent
void * data
ListBase object_bases
struct XFormObjectData * xod
Definition: object_utils.c:351
float obmat_orig[4][4]
Definition: object_utils.c:350
float obmat_orig[4][4]
Definition: object_utils.c:165
float parent_obmat_inv_orig[4][4]
Definition: object_utils.c:167
Object * ob_parent_recurse
Definition: object_utils.c:170
float parent_obmat_orig[4][4]
Definition: object_utils.c:166
float parent_recurse_obmat_orig[4][4]
Definition: object_utils.c:168
float parentinv_orig[4][4]
Definition: object_utils.c:169
struct EditBone * act_edbone
struct Bone * bone
float pose_head[3]