Merge branch 'blender-v2.90-release'
[blender.git] / source / blender / editors / object / object_data_transform.c
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  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edobj
22  *
23  * Use to transform object origins only.
24  *
25  * This is a small API to store & apply transformations to object data,
26  * where a transformation matrix can be continually applied ontop of the original values
27  * so we don't loose precision over time.
28  */
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "DNA_anim_types.h"
34 #include "DNA_armature_types.h"
35 #include "DNA_collection_types.h"
36 #include "DNA_gpencil_types.h"
37 #include "DNA_lattice_types.h"
38 #include "DNA_mesh_types.h"
39 #include "DNA_meta_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_scene_types.h"
42
43 #include "BLI_listbase.h"
44 #include "BLI_math.h"
45 #include "BLI_utildefines.h"
46
47 #include "BKE_armature.h"
48 #include "BKE_curve.h"
49 #include "BKE_editmesh.h"
50 #include "BKE_gpencil_geom.h"
51 #include "BKE_key.h"
52 #include "BKE_lattice.h"
53 #include "BKE_mball.h"
54 #include "BKE_mesh.h"
55 #include "BKE_scene.h"
56
57 #include "bmesh.h"
58
59 #include "DEG_depsgraph.h"
60 #include "DEG_depsgraph_query.h"
61
62 #include "WM_types.h"
63
64 #include "ED_armature.h"
65 #include "ED_mesh.h"
66 #include "ED_object.h"
67
68 #include "MEM_guardedalloc.h"
69
70 /* -------------------------------------------------------------------- */
71 /** \name Internal Transform Get/Apply
72  *
73  * Some object data types don't have utility functions to access their transformation data.
74  * Define these locally.
75  *
76  * \{ */
77
78 /* Armature */
79
80 struct ElemData_Armature {
81   float tail[3];
82   float head[3];
83   float roll;
84   float arm_tail[3];
85   float arm_head[3];
86   float arm_roll;
87   float rad_tail;
88   float rad_head;
89   float dist;
90   float xwidth;
91   float zwidth;
92 };
93
94 static struct ElemData_Armature *armature_coords_and_quats_get_recurse(
95     const ListBase *bone_base, struct ElemData_Armature *elem_array)
96 {
97   struct ElemData_Armature *elem = elem_array;
98   LISTBASE_FOREACH (const Bone *, bone, bone_base) {
99
100 #define COPY_PTR(member) memcpy(elem->member, bone->member, sizeof(bone->member))
101 #define COPY_VAL(member) memcpy(&elem->member, &bone->member, sizeof(bone->member))
102     COPY_PTR(head);
103     COPY_PTR(tail);
104     COPY_VAL(roll);
105     COPY_PTR(arm_head);
106     COPY_PTR(arm_tail);
107     COPY_VAL(arm_roll);
108     COPY_VAL(rad_tail);
109     COPY_VAL(rad_head);
110     COPY_VAL(dist);
111     COPY_VAL(xwidth);
112     COPY_VAL(zwidth);
113 #undef COPY_PTR
114 #undef COPY_VAL
115
116     elem = armature_coords_and_quats_get_recurse(&bone->childbase, elem + 1);
117   }
118   return elem;
119 }
120
121 static void armature_coords_and_quats_get(const bArmature *arm,
122                                           struct ElemData_Armature *elem_array)
123 {
124   armature_coords_and_quats_get_recurse(&arm->bonebase, elem_array);
125 }
126
127 static const struct ElemData_Armature *armature_coords_and_quats_apply_with_mat4_recurse(
128     ListBase *bone_base, const struct ElemData_Armature *elem_array, const float mat[4][4])
129 {
130   const struct ElemData_Armature *elem = elem_array;
131   LISTBASE_FOREACH (Bone *, bone, bone_base) {
132
133 #define COPY_PTR(member) memcpy(bone->member, elem->member, sizeof(bone->member))
134 #define COPY_VAL(member) memcpy(&bone->member, &elem->member, sizeof(bone->member))
135     COPY_PTR(head);
136     COPY_PTR(tail);
137     COPY_VAL(roll);
138     COPY_PTR(arm_head);
139     COPY_PTR(arm_tail);
140     COPY_VAL(arm_roll);
141     COPY_VAL(rad_tail);
142     COPY_VAL(rad_head);
143     COPY_VAL(dist);
144     COPY_VAL(xwidth);
145     COPY_VAL(zwidth);
146 #undef COPY_PTR
147 #undef COPY_VAL
148
149     elem = armature_coords_and_quats_apply_with_mat4_recurse(&bone->childbase, elem + 1, mat);
150   }
151   return elem;
152 }
153
154 static void armature_coords_and_quats_apply_with_mat4(bArmature *arm,
155                                                       const struct ElemData_Armature *elem_array,
156                                                       const float mat[4][4])
157 {
158   armature_coords_and_quats_apply_with_mat4_recurse(&arm->bonebase, elem_array, mat);
159   BKE_armature_transform(arm, mat, true);
160 }
161
162 static void armature_coords_and_quats_apply(bArmature *arm,
163                                             const struct ElemData_Armature *elem_array)
164 {
165   /* Avoid code duplication by using a unit matrix. */
166   float mat[4][4];
167   unit_m4(mat);
168   armature_coords_and_quats_apply_with_mat4(arm, elem_array, mat);
169 }
170
171 /* Edit Armature */
172 static void edit_armature_coords_and_quats_get(const bArmature *arm,
173                                                struct ElemData_Armature *elem_array)
174 {
175   struct ElemData_Armature *elem = elem_array;
176   for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next, elem++) {
177
178 #define COPY_PTR(member) memcpy(elem->member, ebone->member, sizeof(ebone->member))
179 #define COPY_VAL(member) memcpy(&elem->member, &ebone->member, sizeof(ebone->member))
180     /* Unused for edit bones: arm_head, arm_tail, arm_roll */
181     COPY_PTR(head);
182     COPY_PTR(tail);
183     COPY_VAL(roll);
184     COPY_VAL(rad_tail);
185     COPY_VAL(rad_head);
186     COPY_VAL(dist);
187     COPY_VAL(xwidth);
188     COPY_VAL(zwidth);
189 #undef COPY_PTR
190 #undef COPY_VAL
191   }
192 }
193
194 static void edit_armature_coords_and_quats_apply_with_mat4(
195     bArmature *arm, const struct ElemData_Armature *elem_array, const float mat[4][4])
196 {
197   const struct ElemData_Armature *elem = elem_array;
198   for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next, elem++) {
199
200 #define COPY_PTR(member) memcpy(ebone->member, elem->member, sizeof(ebone->member))
201 #define COPY_VAL(member) memcpy(&ebone->member, &elem->member, sizeof(ebone->member))
202     /* Unused for edit bones: arm_head, arm_tail, arm_roll */
203     COPY_PTR(head);
204     COPY_PTR(tail);
205     COPY_VAL(roll);
206     COPY_VAL(rad_tail);
207     COPY_VAL(rad_head);
208     COPY_VAL(dist);
209     COPY_VAL(xwidth);
210     COPY_VAL(zwidth);
211 #undef COPY_PTR
212 #undef COPY_VAL
213   }
214   ED_armature_edit_transform(arm, mat, true);
215 }
216
217 static void edit_armature_coords_and_quats_apply(bArmature *arm,
218                                                  const struct ElemData_Armature *elem_array)
219 {
220   /* Avoid code duplication by using a unit matrix. */
221   float mat[4][4];
222   unit_m4(mat);
223   edit_armature_coords_and_quats_apply_with_mat4(arm, elem_array, mat);
224 }
225
226 /* MetaBall */
227
228 struct ElemData_MetaBall {
229   float co[3];
230   float quat[4];
231   float exp[3];
232   float rad;
233 };
234
235 static void metaball_coords_and_quats_get(const MetaBall *mb, struct ElemData_MetaBall *elem_array)
236 {
237   struct ElemData_MetaBall *elem = elem_array;
238   for (const MetaElem *ml = mb->elems.first; ml; ml = ml->next, elem++) {
239     copy_v3_v3(elem->co, &ml->x);
240     copy_qt_qt(elem->quat, ml->quat);
241     copy_v3_v3(elem->exp, &ml->expx);
242     elem->rad = ml->rad;
243   }
244 }
245
246 static void metaball_coords_and_quats_apply_with_mat4(MetaBall *mb,
247                                                       const struct ElemData_MetaBall *elem_array,
248                                                       const float mat[4][4])
249 {
250   const struct ElemData_MetaBall *elem = elem_array;
251   for (MetaElem *ml = mb->elems.first; ml; ml = ml->next, elem++) {
252     copy_v3_v3(&ml->x, elem->co);
253     copy_qt_qt(ml->quat, elem->quat);
254     copy_v3_v3(&ml->expx, elem->exp);
255     ml->rad = elem->rad;
256   }
257   BKE_mball_transform(mb, mat, true);
258 }
259
260 static void metaball_coords_and_quats_apply(MetaBall *mb,
261                                             const struct ElemData_MetaBall *elem_array)
262 {
263   /* Avoid code duplication by using a unit matrix. */
264   float mat[4][4];
265   unit_m4(mat);
266   metaball_coords_and_quats_apply_with_mat4(mb, elem_array, mat);
267 }
268
269 /** \} */
270
271 /* -------------------------------------------------------------------- */
272 /** \name Public Object Data Storage API
273  *
274  * Used for interactively transforming object data.
275  *
276  * Store object data transformation in an opaque struct.
277  * \{ */
278
279 struct XFormObjectData {
280   ID *id;
281   bool is_edit_mode;
282 };
283
284 struct XFormObjectData_Mesh {
285   struct XFormObjectData base;
286   /* Optional data for shape keys. */
287   void *key_data;
288   float elem_array[0][3];
289 };
290
291 struct XFormObjectData_Lattice {
292   struct XFormObjectData base;
293   /* Optional data for shape keys. */
294   void *key_data;
295   float elem_array[0][3];
296 };
297
298 struct XFormObjectData_Curve {
299   struct XFormObjectData base;
300   /* Optional data for shape keys. */
301   void *key_data;
302   float elem_array[0][3];
303 };
304
305 struct XFormObjectData_Armature {
306   struct XFormObjectData base;
307   struct ElemData_Armature elem_array[0];
308 };
309
310 struct XFormObjectData_MetaBall {
311   struct XFormObjectData base;
312   struct ElemData_MetaBall elem_array[0];
313 };
314
315 struct XFormObjectData_GPencil {
316   struct XFormObjectData base;
317   struct GPencilPointCoordinates elem_array[0];
318 };
319
320 struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode)
321 {
322   struct XFormObjectData *xod_base = NULL;
323   if (id == NULL) {
324     return xod_base;
325   }
326
327   switch (GS(id->name)) {
328     case ID_ME: {
329       Mesh *me = (Mesh *)id;
330       struct Key *key = me->key;
331       const int key_index = -1;
332
333       if (is_edit_mode) {
334         BMesh *bm = me->edit_mesh->bm;
335         /* Always operate on all keys for the moment. */
336         // key_index = bm->shapenr - 1;
337         const int elem_array_len = bm->totvert;
338         struct XFormObjectData_Mesh *xod = MEM_mallocN(
339             sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
340         memset(xod, 0x0, sizeof(*xod));
341
342         BM_mesh_vert_coords_get(bm, xod->elem_array);
343         xod_base = &xod->base;
344
345         if (key != NULL) {
346           const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
347           if (key_size) {
348             xod->key_data = MEM_mallocN(key_size, __func__);
349             BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
350           }
351         }
352       }
353       else {
354         const int elem_array_len = me->totvert;
355         struct XFormObjectData_Mesh *xod = MEM_mallocN(
356             sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
357         memset(xod, 0x0, sizeof(*xod));
358
359         BKE_mesh_vert_coords_get(me, xod->elem_array);
360         xod_base = &xod->base;
361
362         if (key != NULL) {
363           const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
364           if (key_size) {
365             xod->key_data = MEM_mallocN(key_size, __func__);
366             BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
367           }
368         }
369       }
370       break;
371     }
372     case ID_LT: {
373       Lattice *lt_orig = (Lattice *)id;
374       Lattice *lt = is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
375       struct Key *key = lt->key;
376       const int key_index = -1;
377
378       if (is_edit_mode) {
379         /* Always operate on all keys for the moment. */
380         // key_index = lt_orig->editlatt->shapenr - 1;
381       }
382
383       const int elem_array_len = lt->pntsu * lt->pntsv * lt->pntsw;
384       struct XFormObjectData_Lattice *xod = MEM_mallocN(
385           sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
386       memset(xod, 0x0, sizeof(*xod));
387
388       BKE_lattice_vert_coords_get(lt, xod->elem_array);
389       xod_base = &xod->base;
390
391       if (key != NULL) {
392         const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
393         if (key_size) {
394           xod->key_data = MEM_mallocN(key_size, __func__);
395           BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
396         }
397       }
398
399       break;
400     }
401     case ID_CU: {
402       Curve *cu = (Curve *)id;
403       struct Key *key = cu->key;
404
405       const short ob_type = BKE_curve_type_get(cu);
406       if (ob_type == OB_FONT) {
407         /* We could support translation. */
408         break;
409       }
410
411       const int key_index = -1;
412       ListBase *nurbs;
413       if (is_edit_mode) {
414         EditNurb *editnurb = cu->editnurb;
415         nurbs = &editnurb->nurbs;
416         /* Always operate on all keys for the moment. */
417         // key_index = editnurb->shapenr - 1;
418       }
419       else {
420         nurbs = &cu->nurb;
421       }
422
423       const int elem_array_len = BKE_nurbList_verts_count(nurbs);
424       struct XFormObjectData_Curve *xod = MEM_mallocN(
425           sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
426       memset(xod, 0x0, sizeof(*xod));
427
428       BKE_curve_nurbs_vert_coords_get(nurbs, xod->elem_array, elem_array_len);
429       xod_base = &xod->base;
430
431       if (key != NULL) {
432         const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
433         if (key_size) {
434           xod->key_data = MEM_mallocN(key_size, __func__);
435           BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
436         }
437       }
438
439       break;
440     }
441     case ID_AR: {
442       bArmature *arm = (bArmature *)id;
443       if (is_edit_mode) {
444         const int elem_array_len = BLI_listbase_count(arm->edbo);
445         struct XFormObjectData_Armature *xod = MEM_mallocN(
446             sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
447         memset(xod, 0x0, sizeof(*xod));
448
449         edit_armature_coords_and_quats_get(arm, xod->elem_array);
450         xod_base = &xod->base;
451       }
452       else {
453         const int elem_array_len = BKE_armature_bonelist_count(&arm->bonebase);
454         struct XFormObjectData_Armature *xod = MEM_mallocN(
455             sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
456         memset(xod, 0x0, sizeof(*xod));
457
458         armature_coords_and_quats_get(arm, xod->elem_array);
459         xod_base = &xod->base;
460       }
461       break;
462     }
463     case ID_MB: {
464       /* Edit mode and object mode are shared. */
465       MetaBall *mb = (MetaBall *)id;
466       const int elem_array_len = BLI_listbase_count(&mb->elems);
467       struct XFormObjectData_MetaBall *xod = MEM_mallocN(
468           sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
469       memset(xod, 0x0, sizeof(*xod));
470
471       metaball_coords_and_quats_get(mb, xod->elem_array);
472       xod_base = &xod->base;
473       break;
474     }
475     case ID_GD: {
476       bGPdata *gpd = (bGPdata *)id;
477       const int elem_array_len = BKE_gpencil_stroke_point_count(gpd);
478       struct XFormObjectData_GPencil *xod = MEM_mallocN(
479           sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
480       memset(xod, 0x0, sizeof(*xod));
481
482       BKE_gpencil_point_coords_get(gpd, xod->elem_array);
483       xod_base = &xod->base;
484       break;
485     }
486     default: {
487       break;
488     }
489   }
490   if (xod_base) {
491     xod_base->id = id;
492     xod_base->is_edit_mode = is_edit_mode;
493   }
494   return xod_base;
495 }
496
497 struct XFormObjectData *ED_object_data_xform_create(ID *id)
498 {
499   return ED_object_data_xform_create_ex(id, false);
500 }
501
502 struct XFormObjectData *ED_object_data_xform_create_from_edit_mode(ID *id)
503 {
504   return ED_object_data_xform_create_ex(id, true);
505 }
506
507 void ED_object_data_xform_destroy(struct XFormObjectData *xod_base)
508 {
509   switch (GS(xod_base->id->name)) {
510     case ID_ME: {
511       struct XFormObjectData_Mesh *xod = (struct XFormObjectData_Mesh *)xod_base;
512       if (xod->key_data != NULL) {
513         MEM_freeN(xod->key_data);
514       }
515       break;
516     }
517     case ID_LT: {
518       struct XFormObjectData_Lattice *xod = (struct XFormObjectData_Lattice *)xod_base;
519       if (xod->key_data != NULL) {
520         MEM_freeN(xod->key_data);
521       }
522       break;
523     }
524     case ID_CU: {
525       struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
526       if (xod->key_data != NULL) {
527         MEM_freeN(xod->key_data);
528       }
529       break;
530     }
531     default: {
532       break;
533     }
534   }
535   MEM_freeN(xod_base);
536 }
537
538 void ED_object_data_xform_by_mat4(struct XFormObjectData *xod_base, const float mat[4][4])
539 {
540   switch (GS(xod_base->id->name)) {
541     case ID_ME: {
542       Mesh *me = (Mesh *)xod_base->id;
543
544       struct Key *key = me->key;
545       const int key_index = -1;
546
547       struct XFormObjectData_Mesh *xod = (struct XFormObjectData_Mesh *)xod_base;
548       if (xod_base->is_edit_mode) {
549         BMesh *bm = me->edit_mesh->bm;
550         BM_mesh_vert_coords_apply_with_mat4(bm, xod->elem_array, mat);
551         /* Always operate on all keys for the moment. */
552         // key_index = bm->shapenr - 1;
553       }
554       else {
555         BKE_mesh_vert_coords_apply_with_mat4(me, xod->elem_array, mat);
556       }
557
558       if (key != NULL) {
559         BKE_keyblock_data_set_with_mat4(key, key_index, xod->key_data, mat);
560       }
561
562       break;
563     }
564     case ID_LT: {
565       Lattice *lt_orig = (Lattice *)xod_base->id;
566       Lattice *lt = xod_base->is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
567
568       struct Key *key = lt->key;
569       const int key_index = -1;
570
571       struct XFormObjectData_Lattice *xod = (struct XFormObjectData_Lattice *)xod_base;
572       BKE_lattice_vert_coords_apply_with_mat4(lt, xod->elem_array, mat);
573       if (xod_base->is_edit_mode) {
574         /* Always operate on all keys for the moment. */
575         // key_index = lt_orig->editlatt->shapenr - 1;
576       }
577
578       if ((key != NULL) && (xod->key_data != NULL)) {
579         BKE_keyblock_data_set_with_mat4(key, key_index, xod->key_data, mat);
580       }
581
582       break;
583     }
584     case ID_CU: {
585       BLI_assert(xod_base->is_edit_mode == false); /* Not used currently. */
586       Curve *cu = (Curve *)xod_base->id;
587
588       struct Key *key = cu->key;
589       const int key_index = -1;
590       ListBase *nurb = NULL;
591
592       struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
593       if (xod_base->is_edit_mode) {
594         EditNurb *editnurb = cu->editnurb;
595         nurb = &editnurb->nurbs;
596         BKE_curve_nurbs_vert_coords_apply_with_mat4(&editnurb->nurbs, xod->elem_array, mat, true);
597         /* Always operate on all keys for the moment. */
598         // key_index = editnurb->shapenr - 1;
599       }
600       else {
601         nurb = &cu->nurb;
602         BKE_curve_nurbs_vert_coords_apply_with_mat4(&cu->nurb, xod->elem_array, mat, true);
603       }
604
605       if ((key != NULL) && (xod->key_data != NULL)) {
606         BKE_keyblock_curve_data_set_with_mat4(key, nurb, key_index, xod->key_data, mat);
607       }
608
609       break;
610     }
611     case ID_AR: {
612       BLI_assert(xod_base->is_edit_mode == false); /* Not used currently. */
613       bArmature *arm = (bArmature *)xod_base->id;
614       struct XFormObjectData_Armature *xod = (struct XFormObjectData_Armature *)xod_base;
615       if (xod_base->is_edit_mode) {
616         edit_armature_coords_and_quats_apply_with_mat4(arm, xod->elem_array, mat);
617       }
618       else {
619         armature_coords_and_quats_apply_with_mat4(arm, xod->elem_array, mat);
620       }
621       break;
622     }
623     case ID_MB: {
624       /* Metaballs are a special case, edit-mode and object mode data is shared. */
625       MetaBall *mb = (MetaBall *)xod_base->id;
626       struct XFormObjectData_MetaBall *xod = (struct XFormObjectData_MetaBall *)xod_base;
627       metaball_coords_and_quats_apply_with_mat4(mb, xod->elem_array, mat);
628       break;
629     }
630     case ID_GD: {
631       bGPdata *gpd = (bGPdata *)xod_base->id;
632       struct XFormObjectData_GPencil *xod = (struct XFormObjectData_GPencil *)xod_base;
633       BKE_gpencil_point_coords_apply_with_mat4(gpd, xod->elem_array, mat);
634       break;
635     }
636     default: {
637       break;
638     }
639   }
640 }
641
642 void ED_object_data_xform_restore(struct XFormObjectData *xod_base)
643 {
644   switch (GS(xod_base->id->name)) {
645     case ID_ME: {
646       Mesh *me = (Mesh *)xod_base->id;
647
648       struct Key *key = me->key;
649       const int key_index = -1;
650
651       struct XFormObjectData_Mesh *xod = (struct XFormObjectData_Mesh *)xod_base;
652       if (xod_base->is_edit_mode) {
653         BMesh *bm = me->edit_mesh->bm;
654         BM_mesh_vert_coords_apply(bm, xod->elem_array);
655         /* Always operate on all keys for the moment. */
656         // key_index = bm->shapenr - 1;
657       }
658       else {
659         BKE_mesh_vert_coords_apply(me, xod->elem_array);
660       }
661
662       if ((key != NULL) && (xod->key_data != NULL)) {
663         BKE_keyblock_data_set(key, key_index, xod->key_data);
664       }
665
666       break;
667     }
668     case ID_LT: {
669       Lattice *lt_orig = (Lattice *)xod_base->id;
670       Lattice *lt = xod_base->is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
671
672       struct Key *key = lt->key;
673       const int key_index = -1;
674
675       struct XFormObjectData_Lattice *xod = (struct XFormObjectData_Lattice *)xod_base;
676       BKE_lattice_vert_coords_apply(lt, xod->elem_array);
677       if (xod_base->is_edit_mode) {
678         /* Always operate on all keys for the moment. */
679         // key_index = lt_orig->editlatt->shapenr - 1;
680       }
681
682       if ((key != NULL) && (xod->key_data != NULL)) {
683         BKE_keyblock_data_set(key, key_index, xod->key_data);
684       }
685
686       break;
687     }
688     case ID_CU: {
689       Curve *cu = (Curve *)xod_base->id;
690
691       struct Key *key = cu->key;
692       const int key_index = -1;
693
694       struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
695       if (xod_base->is_edit_mode) {
696         EditNurb *editnurb = cu->editnurb;
697         BKE_curve_nurbs_vert_coords_apply(&editnurb->nurbs, xod->elem_array, true);
698         /* Always operate on all keys for the moment. */
699         // key_index = editnurb->shapenr - 1;
700       }
701       else {
702         BKE_curve_nurbs_vert_coords_apply(&cu->nurb, xod->elem_array, true);
703       }
704
705       if ((key != NULL) && (xod->key_data != NULL)) {
706         BKE_keyblock_data_set(key, key_index, xod->key_data);
707       }
708
709       break;
710     }
711     case ID_AR: {
712       bArmature *arm = (bArmature *)xod_base->id;
713       struct XFormObjectData_Armature *xod = (struct XFormObjectData_Armature *)xod_base;
714       if (xod_base->is_edit_mode) {
715         edit_armature_coords_and_quats_apply(arm, xod->elem_array);
716       }
717       else {
718         armature_coords_and_quats_apply(arm, xod->elem_array);
719       }
720       break;
721     }
722     case ID_MB: {
723       /* Metaballs are a special case, edit-mode and object mode data is shared. */
724       MetaBall *mb = (MetaBall *)xod_base->id;
725       struct XFormObjectData_MetaBall *xod = (struct XFormObjectData_MetaBall *)xod_base;
726       metaball_coords_and_quats_apply(mb, xod->elem_array);
727       break;
728     }
729     case ID_GD: {
730       bGPdata *gpd = (bGPdata *)xod_base->id;
731       struct XFormObjectData_GPencil *xod = (struct XFormObjectData_GPencil *)xod_base;
732       BKE_gpencil_point_coords_apply(gpd, xod->elem_array);
733       break;
734     }
735     default: {
736       break;
737     }
738   }
739 }
740
741 void ED_object_data_xform_tag_update(struct XFormObjectData *xod_base)
742 {
743   switch (GS(xod_base->id->name)) {
744     case ID_ME: {
745       Mesh *me = (Mesh *)xod_base->id;
746       if (xod_base->is_edit_mode) {
747         EDBM_update_generic(me, true, false);
748         EDBM_mesh_normals_update(me->edit_mesh);
749       }
750       DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
751       break;
752     }
753     case ID_LT: {
754       /* Generic update. */
755       Lattice *lt = (Lattice *)xod_base->id;
756       DEG_id_tag_update(&lt->id, ID_RECALC_GEOMETRY);
757       break;
758     }
759     case ID_CU: {
760       /* Generic update. */
761       Curve *cu = (Curve *)xod_base->id;
762       DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
763       break;
764     }
765     case ID_AR: {
766       /* Generic update. */
767       bArmature *arm = (bArmature *)xod_base->id;
768       /* XXX, zero is needed, no other flags properly update this. */
769       DEG_id_tag_update(&arm->id, 0);
770       break;
771     }
772     case ID_MB: {
773       /* Generic update. */
774       MetaBall *mb = (MetaBall *)xod_base->id;
775       DEG_id_tag_update(&mb->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
776       break;
777     }
778     case ID_GD: {
779       /* Generic update. */
780       bGPdata *gpd = (bGPdata *)xod_base->id;
781       DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
782       break;
783     }
784
785     default: {
786       break;
787     }
788   }
789 }
790
791 /** \} */