Fix some inconsistencies in object visibility/selectability tests.
[blender.git] / source / blender / editors / object / object_transform.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  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2002-2008 full recode
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/object/object_transform.c
27  *  \ingroup edobj
28  */
29
30
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "DNA_anim_types.h"
35 #include "DNA_armature_types.h"
36 #include "DNA_mesh_types.h"
37 #include "DNA_meta_types.h"
38 #include "DNA_lamp_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_gpencil_types.h"
42 #include "DNA_collection_types.h"
43 #include "DNA_lattice_types.h"
44
45 #include "BLI_math.h"
46 #include "BLI_listbase.h"
47 #include "BLI_utildefines.h"
48 #include "BLI_array.h"
49
50 #include "BKE_context.h"
51 #include "BKE_curve.h"
52 #include "BKE_main.h"
53 #include "BKE_idcode.h"
54 #include "BKE_mball.h"
55 #include "BKE_mesh.h"
56 #include "BKE_object.h"
57 #include "BKE_report.h"
58 #include "BKE_editmesh.h"
59 #include "BKE_multires.h"
60 #include "BKE_armature.h"
61 #include "BKE_lattice.h"
62 #include "BKE_tracking.h"
63 #include "BKE_gpencil.h"
64
65 #include "DEG_depsgraph.h"
66
67 #include "RNA_define.h"
68 #include "RNA_access.h"
69
70 #include "WM_api.h"
71 #include "WM_types.h"
72
73 #include "ED_armature.h"
74 #include "ED_keyframing.h"
75 #include "ED_mesh.h"
76 #include "ED_screen.h"
77 #include "ED_view3d.h"
78 #include "ED_gpencil.h"
79
80 #include "MEM_guardedalloc.h"
81
82 #include "object_intern.h"
83
84 /*************************** Clear Transformation ****************************/
85
86 /* clear location of object */
87 static void object_clear_loc(Object *ob, const bool clear_delta)
88 {
89         /* clear location if not locked */
90         if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
91                 ob->loc[0] = 0.0f;
92                 if (clear_delta) ob->dloc[0] = 0.0f;
93         }
94         if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
95                 ob->loc[1] = 0.0f;
96                 if (clear_delta) ob->dloc[1] = 0.0f;
97         }
98         if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
99                 ob->loc[2] = 0.0f;
100                 if (clear_delta) ob->dloc[2] = 0.0f;
101         }
102 }
103
104 /* clear rotation of object */
105 static void object_clear_rot(Object *ob, const bool clear_delta)
106 {
107         /* clear rotations that aren't locked */
108         if (ob->protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) {
109                 if (ob->protectflag & OB_LOCK_ROT4D) {
110                         /* perform clamping on a component by component basis */
111                         if (ob->rotmode == ROT_MODE_AXISANGLE) {
112                                 if ((ob->protectflag & OB_LOCK_ROTW) == 0) {
113                                         ob->rotAngle = 0.0f;
114                                         if (clear_delta) ob->drotAngle = 0.0f;
115                                 }
116                                 if ((ob->protectflag & OB_LOCK_ROTX) == 0) {
117                                         ob->rotAxis[0] = 0.0f;
118                                         if (clear_delta) ob->drotAxis[0] = 0.0f;
119                                 }
120                                 if ((ob->protectflag & OB_LOCK_ROTY) == 0) {
121                                         ob->rotAxis[1] = 0.0f;
122                                         if (clear_delta) ob->drotAxis[1] = 0.0f;
123                                 }
124                                 if ((ob->protectflag & OB_LOCK_ROTZ) == 0) {
125                                         ob->rotAxis[2] = 0.0f;
126                                         if (clear_delta) ob->drotAxis[2] = 0.0f;
127                                 }
128
129                                 /* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */
130                                 if (IS_EQF(ob->rotAxis[0], ob->rotAxis[1]) && IS_EQF(ob->rotAxis[1], ob->rotAxis[2]))
131                                         ob->rotAxis[1] = 1.0f;
132                                 if (IS_EQF(ob->drotAxis[0], ob->drotAxis[1]) && IS_EQF(ob->drotAxis[1], ob->drotAxis[2]) && clear_delta)
133                                         ob->drotAxis[1] = 1.0f;
134                         }
135                         else if (ob->rotmode == ROT_MODE_QUAT) {
136                                 if ((ob->protectflag & OB_LOCK_ROTW) == 0) {
137                                         ob->quat[0] = 1.0f;
138                                         if (clear_delta) ob->dquat[0] = 1.0f;
139                                 }
140                                 if ((ob->protectflag & OB_LOCK_ROTX) == 0) {
141                                         ob->quat[1] = 0.0f;
142                                         if (clear_delta) ob->dquat[1] = 0.0f;
143                                 }
144                                 if ((ob->protectflag & OB_LOCK_ROTY) == 0) {
145                                         ob->quat[2] = 0.0f;
146                                         if (clear_delta) ob->dquat[2] = 0.0f;
147                                 }
148                                 if ((ob->protectflag & OB_LOCK_ROTZ) == 0) {
149                                         ob->quat[3] = 0.0f;
150                                         if (clear_delta) ob->dquat[3] = 0.0f;
151                                 }
152                                 /* TODO: does this quat need normalizing now? */
153                         }
154                         else {
155                                 /* the flag may have been set for the other modes, so just ignore the extra flag... */
156                                 if ((ob->protectflag & OB_LOCK_ROTX) == 0) {
157                                         ob->rot[0] = 0.0f;
158                                         if (clear_delta) ob->drot[0] = 0.0f;
159                                 }
160                                 if ((ob->protectflag & OB_LOCK_ROTY) == 0) {
161                                         ob->rot[1] = 0.0f;
162                                         if (clear_delta) ob->drot[1] = 0.0f;
163                                 }
164                                 if ((ob->protectflag & OB_LOCK_ROTZ) == 0) {
165                                         ob->rot[2] = 0.0f;
166                                         if (clear_delta) ob->drot[2] = 0.0f;
167                                 }
168                         }
169                 }
170                 else {
171                         /* perform clamping using euler form (3-components) */
172                         /* FIXME: deltas are not handled for these cases yet... */
173                         float eul[3], oldeul[3], quat1[4] = {0};
174
175                         if (ob->rotmode == ROT_MODE_QUAT) {
176                                 copy_qt_qt(quat1, ob->quat);
177                                 quat_to_eul(oldeul, ob->quat);
178                         }
179                         else if (ob->rotmode == ROT_MODE_AXISANGLE) {
180                                 axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, ob->rotAxis, ob->rotAngle);
181                         }
182                         else {
183                                 copy_v3_v3(oldeul, ob->rot);
184                         }
185
186                         eul[0] = eul[1] = eul[2] = 0.0f;
187
188                         if (ob->protectflag & OB_LOCK_ROTX)
189                                 eul[0] = oldeul[0];
190                         if (ob->protectflag & OB_LOCK_ROTY)
191                                 eul[1] = oldeul[1];
192                         if (ob->protectflag & OB_LOCK_ROTZ)
193                                 eul[2] = oldeul[2];
194
195                         if (ob->rotmode == ROT_MODE_QUAT) {
196                                 eul_to_quat(ob->quat, eul);
197                                 /* quaternions flip w sign to accumulate rotations correctly */
198                                 if ((quat1[0] < 0.0f && ob->quat[0] > 0.0f) || (quat1[0] > 0.0f && ob->quat[0] < 0.0f)) {
199                                         mul_qt_fl(ob->quat, -1.0f);
200                                 }
201                         }
202                         else if (ob->rotmode == ROT_MODE_AXISANGLE) {
203                                 eulO_to_axis_angle(ob->rotAxis, &ob->rotAngle, eul, EULER_ORDER_DEFAULT);
204                         }
205                         else {
206                                 copy_v3_v3(ob->rot, eul);
207                         }
208                 }
209         }                        // Duplicated in source/blender/editors/armature/editarmature.c
210         else {
211                 if (ob->rotmode == ROT_MODE_QUAT) {
212                         unit_qt(ob->quat);
213                         if (clear_delta) unit_qt(ob->dquat);
214                 }
215                 else if (ob->rotmode == ROT_MODE_AXISANGLE) {
216                         unit_axis_angle(ob->rotAxis, &ob->rotAngle);
217                         if (clear_delta) unit_axis_angle(ob->drotAxis, &ob->drotAngle);
218                 }
219                 else {
220                         zero_v3(ob->rot);
221                         if (clear_delta) zero_v3(ob->drot);
222                 }
223         }
224 }
225
226 /* clear scale of object */
227 static void object_clear_scale(Object *ob, const bool clear_delta)
228 {
229         /* clear scale factors which are not locked */
230         if ((ob->protectflag & OB_LOCK_SCALEX) == 0) {
231                 ob->size[0] = 1.0f;
232                 if (clear_delta) ob->dscale[0] = 1.0f;
233         }
234         if ((ob->protectflag & OB_LOCK_SCALEY) == 0) {
235                 ob->size[1] = 1.0f;
236                 if (clear_delta) ob->dscale[1] = 1.0f;
237         }
238         if ((ob->protectflag & OB_LOCK_SCALEZ) == 0) {
239                 ob->size[2] = 1.0f;
240                 if (clear_delta) ob->dscale[2] = 1.0f;
241         }
242 }
243
244 /* --------------- */
245
246 /* generic exec for clear-transform operators */
247 static int object_clear_transform_generic_exec(bContext *C, wmOperator *op,
248                                                void (*clear_func)(Object *, const bool),
249                                                const char default_ksName[])
250 {
251         Scene *scene = CTX_data_scene(C);
252         KeyingSet *ks;
253         const bool clear_delta = RNA_boolean_get(op->ptr, "clear_delta");
254
255         /* sanity checks */
256         if (ELEM(NULL, clear_func, default_ksName)) {
257                 BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or keying set name");
258                 return OPERATOR_CANCELLED;
259         }
260
261         /* get KeyingSet to use */
262         ks = ANIM_get_keyingset_for_autokeying(scene, default_ksName);
263
264         /* operate on selected objects only if they aren't in weight-paint mode
265          * (so that object-transform clearing won't be applied at same time as bone-clearing)
266          */
267         CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
268         {
269                 if (!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
270                         /* run provided clearing function */
271                         clear_func(ob, clear_delta);
272
273                         ED_autokeyframe_object(C, scene, ob, ks);
274
275                         /* tag for updates */
276                         DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
277                 }
278         }
279         CTX_DATA_END;
280
281         /* this is needed so children are also updated */
282         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
283
284         return OPERATOR_FINISHED;
285 }
286
287 /* --------------- */
288
289
290 static int object_location_clear_exec(bContext *C, wmOperator *op)
291 {
292         return object_clear_transform_generic_exec(C, op, object_clear_loc, ANIM_KS_LOCATION_ID);
293 }
294
295 void OBJECT_OT_location_clear(wmOperatorType *ot)
296 {
297         /* identifiers */
298         ot->name = "Clear Location";
299         ot->description = "Clear the object's location";
300         ot->idname = "OBJECT_OT_location_clear";
301
302         /* api callbacks */
303         ot->exec = object_location_clear_exec;
304         ot->poll = ED_operator_scene_editable;
305
306         /* flags */
307         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
308
309
310         /* properties */
311         ot->prop = RNA_def_boolean(ot->srna, "clear_delta", false, "Clear Delta",
312                                    "Clear delta location in addition to clearing the normal location transform");
313 }
314
315 static int object_rotation_clear_exec(bContext *C, wmOperator *op)
316 {
317         return object_clear_transform_generic_exec(C, op, object_clear_rot, ANIM_KS_ROTATION_ID);
318 }
319
320 void OBJECT_OT_rotation_clear(wmOperatorType *ot)
321 {
322         /* identifiers */
323         ot->name = "Clear Rotation";
324         ot->description = "Clear the object's rotation";
325         ot->idname = "OBJECT_OT_rotation_clear";
326
327         /* api callbacks */
328         ot->exec = object_rotation_clear_exec;
329         ot->poll = ED_operator_scene_editable;
330
331         /* flags */
332         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
333
334         /* properties */
335         ot->prop = RNA_def_boolean(ot->srna, "clear_delta", false, "Clear Delta",
336                                    "Clear delta rotation in addition to clearing the normal rotation transform");
337 }
338
339 static int object_scale_clear_exec(bContext *C, wmOperator *op)
340 {
341         return object_clear_transform_generic_exec(C, op, object_clear_scale, ANIM_KS_SCALING_ID);
342 }
343
344 void OBJECT_OT_scale_clear(wmOperatorType *ot)
345 {
346         /* identifiers */
347         ot->name = "Clear Scale";
348         ot->description = "Clear the object's scale";
349         ot->idname = "OBJECT_OT_scale_clear";
350
351         /* api callbacks */
352         ot->exec = object_scale_clear_exec;
353         ot->poll = ED_operator_scene_editable;
354
355         /* flags */
356         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
357
358         /* properties */
359         ot->prop = RNA_def_boolean(ot->srna, "clear_delta", false, "Clear Delta",
360                                    "Clear delta scale in addition to clearing the normal scale transform");
361 }
362
363 /* --------------- */
364
365 static int object_origin_clear_exec(bContext *C, wmOperator *UNUSED(op))
366 {
367         float *v1, *v3;
368         float mat[3][3];
369
370         CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
371         {
372                 if (ob->parent) {
373                         /* vectors pointed to by v1 and v3 will get modified */
374                         v1 = ob->loc;
375                         v3 = ob->parentinv[3];
376
377                         copy_m3_m4(mat, ob->parentinv);
378                         negate_v3_v3(v3, v1);
379                         mul_m3_v3(mat, v3);
380                 }
381
382                 DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
383         }
384         CTX_DATA_END;
385
386         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
387
388         return OPERATOR_FINISHED;
389 }
390
391 void OBJECT_OT_origin_clear(wmOperatorType *ot)
392 {
393         /* identifiers */
394         ot->name = "Clear Origin";
395         ot->description = "Clear the object's origin";
396         ot->idname = "OBJECT_OT_origin_clear";
397
398         /* api callbacks */
399         ot->exec = object_origin_clear_exec;
400         ot->poll = ED_operator_scene_editable;
401
402         /* flags */
403         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
404 }
405
406 /*************************** Apply Transformation ****************************/
407
408 /* use this when the loc/size/rot of the parent has changed but the children
409  * should stay in the same place, e.g. for apply-size-rot or object center */
410 static void ignore_parent_tx(const bContext *C, Main *bmain, Scene *scene, Object *ob)
411 {
412         Object workob;
413         Object *ob_child;
414         Depsgraph *depsgraph = CTX_data_depsgraph(C);
415
416         /* a change was made, adjust the children to compensate */
417         for (ob_child = bmain->object.first; ob_child; ob_child = ob_child->id.next) {
418                 if (ob_child->parent == ob) {
419                         BKE_object_apply_mat4(ob_child, ob_child->obmat, true, false);
420                         BKE_object_workob_calc_parent(depsgraph, scene, ob_child, &workob);
421                         invert_m4_m4(ob_child->parentinv, workob.obmat);
422                 }
423         }
424 }
425
426 static int apply_objects_internal(
427         bContext *C, ReportList *reports,
428         bool apply_loc, bool apply_rot, bool apply_scale,
429         bool do_props)
430 {
431         Main *bmain = CTX_data_main(C);
432         Scene *scene = CTX_data_scene(C);
433         Depsgraph *depsgraph = CTX_data_depsgraph(C);
434         float rsmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale;
435         bool changed = true;
436
437         /* first check if we can execute */
438         CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
439         {
440                 if (ELEM(ob->type, OB_MESH, OB_ARMATURE, OB_LATTICE, OB_MBALL, OB_CURVE, OB_SURF, OB_FONT, OB_GPENCIL)) {
441                         ID *obdata = ob->data;
442                         if (ID_REAL_USERS(obdata) > 1) {
443                                 BKE_reportf(reports, RPT_ERROR,
444                                             "Cannot apply to a multi user: Object \"%s\", %s \"%s\", aborting",
445                                             ob->id.name + 2, BKE_idcode_to_name(GS(obdata->name)), obdata->name + 2);
446                                 changed = false;
447                         }
448
449                         if (ID_IS_LINKED(obdata)) {
450                                 BKE_reportf(reports, RPT_ERROR,
451                                             "Cannot apply to library data: Object \"%s\", %s \"%s\", aborting",
452                                             ob->id.name + 2, BKE_idcode_to_name(GS(obdata->name)), obdata->name + 2);
453                                 changed = false;
454                         }
455                 }
456
457                 if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
458                         ID *obdata = ob->data;
459                         Curve *cu;
460
461                         cu = ob->data;
462
463                         if (((ob->type == OB_CURVE) && !(cu->flag & CU_3D)) && (apply_rot || apply_loc)) {
464                                 BKE_reportf(reports, RPT_ERROR,
465                                             "Rotation/Location can't apply to a 2D curve: Object \"%s\", %s \"%s\", aborting",
466                                             ob->id.name + 2, BKE_idcode_to_name(GS(obdata->name)), obdata->name + 2);
467                                 changed = false;
468                         }
469                         if (cu->key) {
470                                 BKE_reportf(reports, RPT_ERROR,
471                                             "Can't apply to a curve with shape-keys: Object \"%s\", %s \"%s\", aborting",
472                                             ob->id.name + 2, BKE_idcode_to_name(GS(obdata->name)), obdata->name + 2);
473                                 changed = false;
474                         }
475                 }
476
477                 if (ob->type == OB_FONT) {
478                         if (apply_rot || apply_loc) {
479                                 BKE_reportf(reports, RPT_ERROR,
480                                             "Font's can only have scale applied: \"%s\"",
481                                             ob->id.name + 2);
482                                 changed = false;
483                         }
484                 }
485
486                 if (ob->type == OB_GPENCIL) {
487                         bGPdata *gpd = ob->data;
488                         if (gpd) {
489                                 if (gpd->layers.first) {
490                                         /* Unsupported configuration */
491                                         bool has_unparented_layers = false;
492
493                                         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
494                                                 /* Parented layers aren't supported as we can't easily re-evaluate the scene to sample parent movement */
495                                                 if (gpl->parent == NULL) {
496                                                         has_unparented_layers = true;
497                                                         break;
498                                                 }
499                                         }
500
501                                         if (has_unparented_layers == false) {
502                                                 BKE_reportf(reports, RPT_ERROR,
503                                                             "Can't apply to a GP datablock where all layers are parented: Object \"%s\", %s \"%s\", aborting",
504                                                             ob->id.name + 2, BKE_idcode_to_name(ID_GD), gpd->id.name + 2);
505                                                 changed = false;
506                                         }
507                                 }
508                                 else {
509                                         /* No layers/data */
510                                         BKE_reportf(reports, RPT_ERROR,
511                                                     "Can't apply to GP datablock with no layers: Object \"%s\", %s \"%s\", aborting",
512                                                     ob->id.name + 2, BKE_idcode_to_name(ID_GD), gpd->id.name + 2);
513                                 }
514                         }
515                 }
516
517                 if (ob->type == OB_LAMP) {
518                         Lamp *la = ob->data;
519                         if (la->type == LA_AREA) {
520                                 if (apply_rot || apply_loc) {
521                                         BKE_reportf(reports, RPT_ERROR,
522                                                     "Area Lights can only have scale applied: \"%s\"",
523                                                     ob->id.name + 2);
524                                         changed = false;
525                                 }
526                         }
527                 }
528         }
529         CTX_DATA_END;
530
531         if (!changed)
532                 return OPERATOR_CANCELLED;
533
534         changed = false;
535
536         /* now execute */
537         CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
538         {
539
540                 /* calculate rotation/scale matrix */
541                 if (apply_scale && apply_rot)
542                         BKE_object_to_mat3(ob, rsmat);
543                 else if (apply_scale)
544                         BKE_object_scale_to_mat3(ob, rsmat);
545                 else if (apply_rot) {
546                         float tmat[3][3], timat[3][3];
547
548                         /* simple rotation matrix */
549                         BKE_object_rot_to_mat3(ob, rsmat, true);
550
551                         /* correct for scale, note mul_m3_m3m3 has swapped args! */
552                         BKE_object_scale_to_mat3(ob, tmat);
553                         invert_m3_m3(timat, tmat);
554                         mul_m3_m3m3(rsmat, timat, rsmat);
555                         mul_m3_m3m3(rsmat, rsmat, tmat);
556                 }
557                 else
558                         unit_m3(rsmat);
559
560                 copy_m4_m3(mat, rsmat);
561
562                 /* calculate translation */
563                 if (apply_loc) {
564                         copy_v3_v3(mat[3], ob->loc);
565
566                         if (!(apply_scale && apply_rot)) {
567                                 float tmat[3][3];
568                                 /* correct for scale and rotation that is still applied */
569                                 BKE_object_to_mat3(ob, obmat);
570                                 invert_m3_m3(iobmat, obmat);
571                                 mul_m3_m3m3(tmat, rsmat, iobmat);
572                                 mul_m3_v3(tmat, mat[3]);
573                         }
574                 }
575
576                 /* apply to object data */
577                 if (ob->type == OB_MESH) {
578                         Mesh *me = ob->data;
579
580                         if (apply_scale)
581                                 multiresModifier_scale_disp(depsgraph, scene, ob);
582
583                         /* adjust data */
584                         BKE_mesh_transform(me, mat, true);
585
586                         /* update normals */
587                         BKE_mesh_calc_normals(me);
588                 }
589                 else if (ob->type == OB_ARMATURE) {
590                         ED_armature_transform_apply(bmain, ob, mat, do_props);
591                 }
592                 else if (ob->type == OB_LATTICE) {
593                         Lattice *lt = ob->data;
594
595                         BKE_lattice_transform(lt, mat, true);
596                 }
597                 else if (ob->type == OB_MBALL) {
598                         MetaBall *mb = ob->data;
599                         BKE_mball_transform(mb, mat, do_props);
600                 }
601                 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
602                         Curve *cu = ob->data;
603                         scale = mat3_to_scale(rsmat);
604                         BKE_curve_transform_ex(cu, mat, true, do_props, scale);
605                 }
606                 else if (ob->type == OB_FONT) {
607                         Curve *cu = ob->data;
608                         int i;
609
610                         scale = mat3_to_scale(rsmat);
611
612                         for (i = 0; i < cu->totbox; i++) {
613                                 TextBox *tb = &cu->tb[i];
614                                 tb->x *= scale;
615                                 tb->y *= scale;
616                                 tb->w *= scale;
617                                 tb->h *= scale;
618                         }
619
620                         if (do_props) {
621                                 cu->fsize *= scale;
622                         }
623                 }
624                 else if (ob->type == OB_GPENCIL) {
625                         bGPdata *gpd = ob->data;
626                         BKE_gpencil_transform(gpd, mat);
627                 }
628                 else if (ob->type == OB_CAMERA) {
629                         MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
630
631                         /* applying scale on camera actually scales clip's reconstruction.
632                          * of there's clip assigned to camera nothing to do actually.
633                          */
634                         if (!clip)
635                                 continue;
636
637                         if (apply_scale)
638                                 BKE_tracking_reconstruction_scale(&clip->tracking, ob->size);
639                 }
640                 else if (ob->type == OB_EMPTY) {
641                         /* It's possible for empties too, even though they don't
642                          * really have obdata, since we can simply apply the maximum
643                          * scaling to the empty's drawsize.
644                          *
645                          * Core Assumptions:
646                          * 1) Most scaled empties have uniform scaling
647                          *    (i.e. for visibility reasons), AND/OR
648                          * 2) Preserving non-uniform scaling is not that important,
649                          *    and is something that many users would be willing to
650                          *    sacrifice for having an easy way to do this.
651                          */
652
653                         if ((apply_loc == false) &&
654                             (apply_rot == false) &&
655                             (apply_scale == true))
656                         {
657                                 float max_scale = max_fff(fabsf(ob->size[0]), fabsf(ob->size[1]), fabsf(ob->size[2]));
658                                 ob->empty_drawsize *= max_scale;
659                         }
660                 }
661                 else if (ob->type == OB_LAMP) {
662                         Lamp *la = ob->data;
663                         if (la->type != LA_AREA) {
664                                 continue;
665                         }
666
667                         bool keeps_aspect_ratio = compare_ff_relative(rsmat[0][0], rsmat[1][1], FLT_EPSILON, 64);
668                         if ((la->area_shape == LA_AREA_SQUARE) && !keeps_aspect_ratio) {
669                                 la->area_shape = LA_AREA_RECT;
670                                 la->area_sizey = la->area_size;
671                         }
672                         else if ((la->area_shape == LA_AREA_DISK) && !keeps_aspect_ratio) {
673                                 la->area_shape = LA_AREA_ELLIPSE;
674                                 la->area_sizey = la->area_size;
675                         }
676
677                         la->area_size *= rsmat[0][0];
678                         la->area_sizey *= rsmat[1][1];
679                         la->area_sizez *= rsmat[2][2];
680                 }
681                 else {
682                         continue;
683                 }
684
685                 if (apply_loc)
686                         zero_v3(ob->loc);
687                 if (apply_scale)
688                         ob->size[0] = ob->size[1] = ob->size[2] = 1.0f;
689                 if (apply_rot) {
690                         zero_v3(ob->rot);
691                         unit_qt(ob->quat);
692                         unit_axis_angle(ob->rotAxis, &ob->rotAngle);
693                 }
694
695                 BKE_object_where_is_calc(depsgraph, scene, ob);
696                 if (ob->type == OB_ARMATURE) {
697                         BKE_pose_where_is(depsgraph, scene, ob); /* needed for bone parents */
698                 }
699
700                 ignore_parent_tx(C, bmain, scene, ob);
701
702                 DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
703
704                 changed = true;
705         }
706         CTX_DATA_END;
707
708         if (!changed) {
709                 BKE_report(reports, RPT_WARNING, "Objects have no data to transform");
710                 return OPERATOR_CANCELLED;
711         }
712
713         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
714         return OPERATOR_FINISHED;
715 }
716
717 static int visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
718 {
719         Scene *scene = CTX_data_scene(C);
720         Depsgraph *depsgraph = CTX_data_depsgraph(C);
721         bool changed = false;
722
723         CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
724         {
725                 BKE_object_where_is_calc(depsgraph, scene, ob);
726                 BKE_object_apply_mat4(ob, ob->obmat, true, true);
727                 BKE_object_where_is_calc(depsgraph, scene, ob);
728
729                 /* update for any children that may get moved */
730                 DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
731
732                 changed = true;
733         }
734         CTX_DATA_END;
735
736         if (!changed)
737                 return OPERATOR_CANCELLED;
738
739         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
740         return OPERATOR_FINISHED;
741 }
742
743 void OBJECT_OT_visual_transform_apply(wmOperatorType *ot)
744 {
745         /* identifiers */
746         ot->name = "Apply Visual Transform";
747         ot->description = "Apply the object's visual transformation to its data";
748         ot->idname = "OBJECT_OT_visual_transform_apply";
749
750         /* api callbacks */
751         ot->exec = visual_transform_apply_exec;
752         ot->poll = ED_operator_scene_editable;
753
754         /* flags */
755         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
756 }
757
758 static int object_transform_apply_exec(bContext *C, wmOperator *op)
759 {
760         const bool loc = RNA_boolean_get(op->ptr, "location");
761         const bool rot = RNA_boolean_get(op->ptr, "rotation");
762         const bool sca = RNA_boolean_get(op->ptr, "scale");
763         const bool do_props = RNA_boolean_get(op->ptr, "properties");
764
765         if (loc || rot || sca) {
766                 return apply_objects_internal(C, op->reports, loc, rot, sca, do_props);
767         }
768         else {
769                 /* allow for redo */
770                 return OPERATOR_FINISHED;
771         }
772 }
773
774 void OBJECT_OT_transform_apply(wmOperatorType *ot)
775 {
776         /* identifiers */
777         ot->name = "Apply Object Transform";
778         ot->description = "Apply the object's transformation to its data";
779         ot->idname = "OBJECT_OT_transform_apply";
780
781         /* api callbacks */
782         ot->exec = object_transform_apply_exec;
783         ot->poll = ED_operator_objectmode;
784
785         /* flags */
786         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
787
788         RNA_def_boolean(ot->srna, "location", 0, "Location", "");
789         RNA_def_boolean(ot->srna, "rotation", 0, "Rotation", "");
790         RNA_def_boolean(ot->srna, "scale", 0, "Scale", "");
791         RNA_def_boolean(ot->srna, "properties", true, "Apply Properties",
792                         "Modify properties such as curve vertex radius, font size and bone envelope");
793 }
794
795 /********************* Set Object Center ************************/
796
797 enum {
798         GEOMETRY_TO_ORIGIN = 0,
799         ORIGIN_TO_GEOMETRY,
800         ORIGIN_TO_CURSOR,
801         ORIGIN_TO_CENTER_OF_MASS_SURFACE,
802         ORIGIN_TO_CENTER_OF_MASS_VOLUME,
803 };
804
805 static int object_origin_set_exec(bContext *C, wmOperator *op)
806 {
807         Main *bmain = CTX_data_main(C);
808         Scene *scene = CTX_data_scene(C);
809         Object *obact = CTX_data_active_object(C);
810         Object *obedit = CTX_data_edit_object(C);
811         Depsgraph *depsgraph = CTX_data_depsgraph(C);
812         Object *tob;
813         float cursor[3], cent[3], cent_neg[3], centn[3];
814         int centermode = RNA_enum_get(op->ptr, "type");
815         int around = RNA_enum_get(op->ptr, "center"); /* initialized from v3d->around */
816
817         ListBase ctx_data_list;
818         CollectionPointerLink *ctx_ob;
819         CollectionPointerLink *ctx_ob_act = NULL;
820
821         /* keep track of what is changed */
822         int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0;
823
824         if (obedit && centermode != GEOMETRY_TO_ORIGIN) {
825                 BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in edit mode");
826                 return OPERATOR_CANCELLED;
827         }
828         else {
829                 /* get the view settings if 'around' isn't set and the view is available */
830                 View3D *v3d = CTX_wm_view3d(C);
831                 copy_v3_v3(cursor, scene->cursor.location);
832                 if (v3d && !RNA_struct_property_is_set(op->ptr, "center"))
833                         around = scene->toolsettings->transform_pivot_point;
834         }
835
836         zero_v3(cent);
837
838         if (obedit) {
839                 if (obedit->type == OB_MESH) {
840                         Mesh *me = obedit->data;
841                         BMEditMesh *em = me->edit_btmesh;
842                         BMVert *eve;
843                         BMIter iter;
844
845                         if (centermode == ORIGIN_TO_CURSOR) {
846                                 copy_v3_v3(cent, cursor);
847                                 invert_m4_m4(obedit->imat, obedit->obmat);
848                                 mul_m4_v3(obedit->imat, cent);
849                         }
850                         else {
851                                 if (around == V3D_AROUND_CENTER_MEDIAN) {
852                                         if (em->bm->totvert) {
853                                                 const float total_div = 1.0f / (float)em->bm->totvert;
854                                                 BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
855                                                         madd_v3_v3fl(cent, eve->co, total_div);
856                                                 }
857                                         }
858                                 }
859                                 else {
860                                         float min[3], max[3];
861                                         INIT_MINMAX(min, max);
862                                         BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
863                                                 minmax_v3v3_v3(min, max, eve->co);
864                                         }
865                                         mid_v3_v3v3(cent, min, max);
866                                 }
867                         }
868
869                         BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
870                                 sub_v3_v3(eve->co, cent);
871                         }
872
873                         EDBM_mesh_normals_update(em);
874                         tot_change++;
875                         DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
876                 }
877         }
878
879         CTX_data_selected_editable_objects(C, &ctx_data_list);
880
881         /* reset flags */
882         for (ctx_ob = ctx_data_list.first;
883              ctx_ob;
884              ctx_ob = ctx_ob->next)
885         {
886                 Object *ob = ctx_ob->ptr.data;
887                 ob->flag &= ~OB_DONE;
888
889                 /* move active first */
890                 if (ob == obact) {
891                         ctx_ob_act = ctx_ob;
892                 }
893         }
894
895         if (ctx_ob_act) {
896                 BLI_listbase_rotate_first(&ctx_data_list, (LinkData *)ctx_ob_act);
897         }
898
899         for (tob = bmain->object.first; tob; tob = tob->id.next) {
900                 if (tob->data)
901                         ((ID *)tob->data)->tag &= ~LIB_TAG_DOIT;
902                 if (tob->dup_group)
903                         ((ID *)tob->dup_group)->tag &= ~LIB_TAG_DOIT;
904         }
905
906         for (ctx_ob = ctx_data_list.first;
907              ctx_ob;
908              ctx_ob = ctx_ob->next)
909         {
910                 Object *ob = ctx_ob->ptr.data;
911
912                 if ((ob->flag & OB_DONE) == 0) {
913                         bool do_inverse_offset = false;
914                         ob->flag |= OB_DONE;
915
916                         if (centermode == ORIGIN_TO_CURSOR) {
917                                 copy_v3_v3(cent, cursor);
918                                 invert_m4_m4(ob->imat, ob->obmat);
919                                 mul_m4_v3(ob->imat, cent);
920                         }
921
922                         if (ob->data == NULL) {
923                                 /* special support for dupligroups */
924                                 if ((ob->transflag & OB_DUPLICOLLECTION) && ob->dup_group && (ob->dup_group->id.tag & LIB_TAG_DOIT) == 0) {
925                                         if (ID_IS_LINKED(ob->dup_group)) {
926                                                 tot_lib_error++;
927                                         }
928                                         else {
929                                                 if (centermode == ORIGIN_TO_CURSOR) {
930                                                         /* done */
931                                                 }
932                                                 else {
933                                                         float min[3], max[3];
934                                                         /* only bounds support */
935                                                         INIT_MINMAX(min, max);
936                                                         BKE_object_minmax_dupli(depsgraph, scene, ob, min, max, true);
937                                                         mid_v3_v3v3(cent, min, max);
938                                                         invert_m4_m4(ob->imat, ob->obmat);
939                                                         mul_m4_v3(ob->imat, cent);
940                                                 }
941
942                                                 add_v3_v3(ob->dup_group->dupli_ofs, cent);
943
944                                                 tot_change++;
945                                                 ob->dup_group->id.tag |= LIB_TAG_DOIT;
946                                                 do_inverse_offset = true;
947                                         }
948                                 }
949                         }
950                         else if (ID_IS_LINKED(ob->data)) {
951                                 tot_lib_error++;
952                         }
953
954                         if (obedit == NULL && ob->type == OB_MESH) {
955                                 Mesh *me = ob->data;
956
957                                 if (centermode == ORIGIN_TO_CURSOR) {
958                                         /* done */
959                                 }
960                                 else if (centermode == ORIGIN_TO_CENTER_OF_MASS_SURFACE) {
961                                         BKE_mesh_center_of_surface(me, cent);
962                                 }
963                                 else if (centermode == ORIGIN_TO_CENTER_OF_MASS_VOLUME) {
964                                         BKE_mesh_center_of_volume(me, cent);
965                                 }
966                                 else if (around == V3D_AROUND_CENTER_MEDIAN) {
967                                         BKE_mesh_center_median(me, cent);
968                                 }
969                                 else {
970                                         BKE_mesh_center_bounds(me, cent);
971                                 }
972
973                                 negate_v3_v3(cent_neg, cent);
974                                 BKE_mesh_translate(me, cent_neg, 1);
975
976                                 tot_change++;
977                                 me->id.tag |= LIB_TAG_DOIT;
978                                 do_inverse_offset = true;
979                         }
980                         else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
981                                 Curve *cu = ob->data;
982
983                                 if      (centermode == ORIGIN_TO_CURSOR)     { /* done */ }
984                                 else if (around == V3D_AROUND_CENTER_MEDIAN) { BKE_curve_center_median(cu, cent); }
985                                 else                                         { BKE_curve_center_bounds(cu, cent); }
986
987                                 /* don't allow Z change if curve is 2D */
988                                 if ((ob->type == OB_CURVE) && !(cu->flag & CU_3D))
989                                         cent[2] = 0.0;
990
991                                 negate_v3_v3(cent_neg, cent);
992                                 BKE_curve_translate(cu, cent_neg, 1);
993
994                                 tot_change++;
995                                 cu->id.tag |= LIB_TAG_DOIT;
996                                 do_inverse_offset = true;
997
998                                 if (obedit) {
999                                         if (centermode == GEOMETRY_TO_ORIGIN) {
1000                                                 DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
1001                                         }
1002                                         break;
1003                                 }
1004                         }
1005                         else if (ob->type == OB_FONT) {
1006                                 /* get from bb */
1007
1008                                 Curve *cu = ob->data;
1009
1010                                 if (ob->bb == NULL && (centermode != ORIGIN_TO_CURSOR)) {
1011                                         /* do nothing*/
1012                                 }
1013                                 else {
1014                                         if (centermode == ORIGIN_TO_CURSOR) {
1015                                                 /* done */
1016                                         }
1017                                         else {
1018                                                 /* extra 0.5 is the height o above line */
1019                                                 cent[0] = 0.5f * (ob->bb->vec[4][0] + ob->bb->vec[0][0]);
1020                                                 cent[1] = 0.5f * (ob->bb->vec[0][1] + ob->bb->vec[2][1]);
1021                                         }
1022
1023                                         cent[2] = 0.0f;
1024
1025                                         cu->xof = cu->xof - cent[0];
1026                                         cu->yof = cu->yof - cent[1];
1027
1028                                         tot_change++;
1029                                         cu->id.tag |= LIB_TAG_DOIT;
1030                                         do_inverse_offset = true;
1031                                 }
1032                         }
1033                         else if (ob->type == OB_ARMATURE) {
1034                                 bArmature *arm = ob->data;
1035
1036                                 if (ID_REAL_USERS(arm) > 1) {
1037 #if 0
1038                                         BKE_report(op->reports, RPT_ERROR, "Cannot apply to a multi user armature");
1039                                         return;
1040 #endif
1041                                         tot_multiuser_arm_error++;
1042                                 }
1043                                 else {
1044                                         /* Function to recenter armatures in editarmature.c
1045                                          * Bone + object locations are handled there.
1046                                          */
1047                                         ED_armature_origin_set(bmain, ob, cursor, centermode, around);
1048
1049                                         tot_change++;
1050                                         arm->id.tag |= LIB_TAG_DOIT;
1051                                         /* do_inverse_offset = true; */ /* docenter_armature() handles this */
1052
1053                                         BKE_object_where_is_calc(depsgraph, scene, ob);
1054                                         BKE_pose_where_is(depsgraph, scene, ob); /* needed for bone parents */
1055
1056                                         ignore_parent_tx(C, bmain, scene, ob);
1057
1058                                         if (obedit)
1059                                                 break;
1060                                 }
1061                         }
1062                         else if (ob->type == OB_MBALL) {
1063                                 MetaBall *mb = ob->data;
1064
1065                                 if      (centermode == ORIGIN_TO_CURSOR)     { /* done */ }
1066                                 else if (around == V3D_AROUND_CENTER_MEDIAN) { BKE_mball_center_median(mb, cent); }
1067                                 else                                         { BKE_mball_center_bounds(mb, cent); }
1068
1069                                 negate_v3_v3(cent_neg, cent);
1070                                 BKE_mball_translate(mb, cent_neg);
1071
1072                                 tot_change++;
1073                                 mb->id.tag |= LIB_TAG_DOIT;
1074                                 do_inverse_offset = true;
1075
1076                                 if (obedit) {
1077                                         if (centermode == GEOMETRY_TO_ORIGIN) {
1078                                                 DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
1079                                         }
1080                                         break;
1081                                 }
1082                         }
1083                         else if (ob->type == OB_LATTICE) {
1084                                 Lattice *lt = ob->data;
1085
1086                                 if      (centermode == ORIGIN_TO_CURSOR)     { /* done */ }
1087                                 else if (around == V3D_AROUND_CENTER_MEDIAN) { BKE_lattice_center_median(lt, cent); }
1088                                 else                                         { BKE_lattice_center_bounds(lt, cent); }
1089
1090                                 negate_v3_v3(cent_neg, cent);
1091                                 BKE_lattice_translate(lt, cent_neg, 1);
1092
1093                                 tot_change++;
1094                                 lt->id.tag |= LIB_TAG_DOIT;
1095                                 do_inverse_offset = true;
1096                         }
1097                         else if (ob->type == OB_GPENCIL) {
1098                                 bGPdata *gpd = ob->data;
1099                                 float gpcenter[3];
1100                                 if (gpd) {
1101                                         if (centermode == ORIGIN_TO_GEOMETRY) {
1102                                                 zero_v3(gpcenter);
1103                                                 BKE_gpencil_centroid_3d(gpd, gpcenter);
1104                                                 add_v3_v3(gpcenter, ob->obmat[3]);
1105                                         }
1106                                         if (centermode == ORIGIN_TO_CURSOR) {
1107                                                 copy_v3_v3(gpcenter, cursor);
1108                                         }
1109                                         if ((centermode == ORIGIN_TO_GEOMETRY) || (centermode == ORIGIN_TO_CURSOR)) {
1110                                                 bGPDspoint *pt;
1111                                                 float imat[3][3], bmat[3][3];
1112                                                 float offset_global[3];
1113                                                 float offset_local[3];
1114                                                 int i;
1115
1116                                                 sub_v3_v3v3(offset_global, gpcenter, ob->obmat[3]);
1117                                                 copy_m3_m4(bmat, obact->obmat);
1118                                                 invert_m3_m3(imat, bmat);
1119                                                 mul_m3_v3(imat, offset_global);
1120                                                 mul_v3_m3v3(offset_local, imat, offset_global);
1121
1122                                                 float diff_mat[4][4];
1123                                                 float inverse_diff_mat[4][4];
1124
1125                                                 /* recalculate all strokes (all layers are considered without evaluating lock attributtes) */
1126                                                 for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1127                                                         /* calculate difference matrix */
1128                                                         ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat);
1129                                                         /* undo matrix */
1130                                                         invert_m4_m4(inverse_diff_mat, diff_mat);
1131                                                         for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1132                                                                 for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
1133                                                                         /* skip strokes that are invalid for current view */
1134                                                                         if (ED_gpencil_stroke_can_use(C, gps) == false)
1135                                                                                 continue;
1136
1137                                                                         for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
1138                                                                                 float mpt[3];
1139                                                                                 mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x);
1140                                                                                 sub_v3_v3(mpt, offset_local);
1141                                                                                 mul_v3_m4v3(&pt->x, diff_mat, mpt);
1142                                                                         }
1143                                                                 }
1144                                                         }
1145                                                 }
1146                                                 DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
1147
1148                                                 tot_change++;
1149                                                 if (centermode == ORIGIN_TO_GEOMETRY) {
1150                                                         copy_v3_v3(ob->loc, gpcenter);
1151                                                 }
1152                                                 ob->id.tag |= LIB_TAG_DOIT;
1153                                                 do_inverse_offset = true;
1154                                         }
1155                                         else {
1156                                                 BKE_report(op->reports, RPT_WARNING, "Grease Pencil Object does not support this set origin option");
1157                                         }
1158                                 }
1159                         }
1160
1161                         /* offset other selected objects */
1162                         if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) {
1163                                 CollectionPointerLink *ctx_link_other;
1164                                 float obmat[4][4];
1165
1166                                 /* was the object data modified
1167                                  * note: the functions above must set 'cent' */
1168
1169                                 /* convert the offset to parent space */
1170                                 BKE_object_to_mat4(ob, obmat);
1171                                 mul_v3_mat3_m4v3(centn, obmat, cent); /* omit translation part */
1172
1173                                 add_v3_v3(ob->loc, centn);
1174
1175                                 BKE_object_where_is_calc(depsgraph, scene, ob);
1176                                 if (ob->type == OB_ARMATURE) {
1177                                         BKE_pose_where_is(depsgraph, scene, ob); /* needed for bone parents */
1178                                 }
1179
1180                                 ignore_parent_tx(C, bmain, scene, ob);
1181
1182                                 /* other users? */
1183                                 //CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects)
1184                                 //{
1185
1186                                 /* use existing context looper */
1187                                 for (ctx_link_other = ctx_data_list.first;
1188                                      ctx_link_other;
1189                                      ctx_link_other = ctx_link_other->next)
1190                                 {
1191                                         Object *ob_other = ctx_link_other->ptr.data;
1192
1193                                         if ((ob_other->flag & OB_DONE) == 0 &&
1194                                             ((ob->data && (ob->data == ob_other->data)) ||
1195                                              (ob->dup_group == ob_other->dup_group &&
1196                                               (ob->transflag | ob_other->transflag) & OB_DUPLICOLLECTION)))
1197                                         {
1198                                                 ob_other->flag |= OB_DONE;
1199                                                 DEG_id_tag_update(&ob_other->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
1200
1201                                                 mul_v3_mat3_m4v3(centn, ob_other->obmat, cent); /* omit translation part */
1202                                                 add_v3_v3(ob_other->loc, centn);
1203
1204                                                 BKE_object_where_is_calc(depsgraph, scene, ob_other);
1205                                                 if (ob_other->type == OB_ARMATURE) {
1206                                                         BKE_pose_where_is(depsgraph, scene, ob_other); /* needed for bone parents */
1207                                                 }
1208                                                 ignore_parent_tx(C, bmain, scene, ob_other);
1209                                         }
1210                                 }
1211                                 //CTX_DATA_END;
1212                         }
1213                 }
1214         }
1215         BLI_freelistN(&ctx_data_list);
1216
1217         for (tob = bmain->object.first; tob; tob = tob->id.next) {
1218                 if (tob->data && (((ID *)tob->data)->tag & LIB_TAG_DOIT)) {
1219                         BKE_object_batch_cache_dirty_tag(tob);
1220                         DEG_id_tag_update(&tob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
1221                 }
1222         }
1223
1224         if (tot_change) {
1225                 WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
1226         }
1227
1228         /* Warn if any errors occurred */
1229         if (tot_lib_error + tot_multiuser_arm_error) {
1230                 BKE_reportf(op->reports, RPT_WARNING, "%i object(s) not centered, %i changed:", tot_lib_error + tot_multiuser_arm_error, tot_change);
1231                 if (tot_lib_error)
1232                         BKE_reportf(op->reports, RPT_WARNING, "|%i linked library object(s)", tot_lib_error);
1233                 if (tot_multiuser_arm_error)
1234                         BKE_reportf(op->reports, RPT_WARNING, "|%i multiuser armature object(s)", tot_multiuser_arm_error);
1235         }
1236
1237         return OPERATOR_FINISHED;
1238 }
1239
1240 void OBJECT_OT_origin_set(wmOperatorType *ot)
1241 {
1242         static const EnumPropertyItem prop_set_center_types[] = {
1243                 {GEOMETRY_TO_ORIGIN, "GEOMETRY_ORIGIN", 0, "Geometry to Origin", "Move object geometry to object origin"},
1244                 {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry",
1245                  "Calculate the center of geometry based on the current pivot point (median, otherwise bounding-box)"},
1246                 {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor",
1247                  "Move object origin to position of the 3D cursor"},
1248                 /* Intentional naming mismatch since some scripts refer to this. */
1249                 {ORIGIN_TO_CENTER_OF_MASS_SURFACE, "ORIGIN_CENTER_OF_MASS", 0, "Origin to Center of Mass (Surface)",
1250                  "Calculate the center of mass from the surface area"},
1251                 {ORIGIN_TO_CENTER_OF_MASS_VOLUME, "ORIGIN_CENTER_OF_VOLUME", 0, "Origin to Center of Mass (Volume)",
1252                  "Calculate the center of mass from the volume (must be manifold geometry with consistent normals)"},
1253                 {0, NULL, 0, NULL, NULL}
1254         };
1255
1256         static const EnumPropertyItem prop_set_bounds_types[] = {
1257                 {V3D_AROUND_CENTER_MEDIAN, "MEDIAN", 0, "Median Center", ""},
1258                 {V3D_AROUND_CENTER_BOUNDS, "BOUNDS", 0, "Bounds Center", ""},
1259                 {0, NULL, 0, NULL, NULL}
1260         };
1261
1262         /* identifiers */
1263         ot->name = "Set Origin";
1264         ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3D cursor";
1265         ot->idname = "OBJECT_OT_origin_set";
1266
1267         /* api callbacks */
1268         ot->invoke = WM_menu_invoke;
1269         ot->exec = object_origin_set_exec;
1270
1271         ot->poll = ED_operator_scene_editable;
1272
1273         /* flags */
1274         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1275
1276         ot->prop = RNA_def_enum(ot->srna, "type", prop_set_center_types, 0, "Type", "");
1277         RNA_def_enum(ot->srna, "center", prop_set_bounds_types, V3D_AROUND_CENTER_MEDIAN, "Center", "");
1278 }
1279
1280 /* -------------------------------------------------------------------- */
1281
1282 /** \name Transform Axis Target
1283  *
1284  * Note this is an experemental operator to point lamps/cameras at objects.
1285  * We may re-work how this behaves based on user feedback.
1286  * - campbell.
1287  * \{ */
1288
1289 /* When using multiple objects, apply their relative rotational offset to the active object. */
1290 #define USE_RELATIVE_ROTATION
1291 /* Disable overlays, ignoring user setting (lamp wire gets in the way). */
1292 #define USE_RENDER_OVERRIDE
1293 /* Calculate a depth if the cursor isn't already over a depth (not essential but feels buggy without). */
1294 #define USE_FAKE_DEPTH_INIT
1295
1296 struct XFormAxisItem {
1297         Object *ob;
1298         float rot_mat[3][3];
1299         void *obtfm;
1300         float xform_dist;
1301
1302 #ifdef USE_RELATIVE_ROTATION
1303         /* use when translating multiple */
1304         float xform_rot_offset[3][3];
1305 #endif
1306 };
1307
1308 struct XFormAxisData {
1309         ViewContext vc;
1310         struct {
1311                 float depth;
1312                 float normal[3];
1313                 bool is_depth_valid;
1314                 bool is_normal_valid;
1315         } prev;
1316
1317         struct XFormAxisItem *object_data;
1318         uint object_data_len;
1319         bool is_translate;
1320
1321         int init_event;
1322 };
1323
1324 #ifdef USE_FAKE_DEPTH_INIT
1325 static void object_transform_axis_target_calc_depth_init(struct XFormAxisData *xfd, const int mval[2])
1326 {
1327         struct XFormAxisItem *item = xfd->object_data;
1328         float view_co_a[3], view_co_b[3];
1329         const float mval_fl[2] = {UNPACK2(mval)};
1330         ED_view3d_win_to_ray(xfd->vc.ar, mval_fl, view_co_a, view_co_b);
1331         add_v3_v3(view_co_b, view_co_a);
1332         float center[3] = {0.0f};
1333         int   center_tot = 0;
1334         for (int i = 0; i < xfd->object_data_len; i++, item++) {
1335                 const Object *ob = item->ob;
1336                 const float *ob_co_a = ob->obmat[3];
1337                 float        ob_co_b[3];
1338                 add_v3_v3v3(ob_co_b, ob->obmat[3], ob->obmat[2]);
1339                 float view_isect[3], ob_isect[3];
1340                 if (isect_line_line_v3(view_co_a, view_co_b, ob_co_a, ob_co_b, view_isect, ob_isect)) {
1341                         add_v3_v3(center, view_isect);
1342                         center_tot += 1;
1343                 }
1344         }
1345         if (center_tot) {
1346                 mul_v3_fl(center, 1.0f / center_tot);
1347                 float center_proj[3];
1348                 ED_view3d_project(xfd->vc.ar, center, center_proj);
1349                 xfd->prev.depth = center_proj[2];
1350                 xfd->prev.is_depth_valid = true;
1351         }
1352 }
1353 #endif  /* USE_FAKE_DEPTH_INIT */
1354
1355 static bool object_is_target_compat(const Object *ob)
1356 {
1357         if (ob->type == OB_LAMP) {
1358                 const Lamp *la = ob->data;
1359                 if (ELEM(la->type, LA_SUN, LA_SPOT, LA_AREA)) {
1360                         return true;
1361                 }
1362         }
1363         /* We might want to enable this later, for now just lamps */
1364 #if 0
1365         else if (ob->type == OB_CAMERA) {
1366                 return true;
1367         }
1368 #endif
1369         return false;
1370 }
1371
1372 static void object_transform_axis_target_free_data(wmOperator *op)
1373 {
1374         struct XFormAxisData *xfd = op->customdata;
1375         struct XFormAxisItem *item = xfd->object_data;
1376
1377 #ifdef USE_RENDER_OVERRIDE
1378         if (xfd->vc.rv3d->depths) {
1379                 xfd->vc.rv3d->depths->damaged = true;
1380         }
1381 #endif
1382
1383         for (int i = 0; i < xfd->object_data_len; i++, item++) {
1384                 MEM_freeN(item->obtfm);
1385         }
1386         MEM_freeN(xfd->object_data);
1387         MEM_freeN(xfd);
1388         op->customdata = NULL;
1389 }
1390
1391 /* We may want to expose as alternative to: BKE_object_apply_rotation */
1392 static void object_apply_rotation(Object *ob, const float rmat[3][3])
1393 {
1394         float size[3];
1395         float loc[3];
1396         float rmat4[4][4];
1397         copy_m4_m3(rmat4, rmat);
1398
1399         copy_v3_v3(size, ob->size);
1400         copy_v3_v3(loc, ob->loc);
1401         BKE_object_apply_mat4(ob, rmat4, true, true);
1402         copy_v3_v3(ob->size, size);
1403         copy_v3_v3(ob->loc, loc);
1404 }
1405 /* We may want to extract this to: BKE_object_apply_location */
1406 static void object_apply_location(Object *ob, const float loc[3])
1407 {
1408         /* quick but weak */
1409         Object ob_prev = *ob;
1410         float mat[4][4];
1411         copy_m4_m4(mat, ob->obmat);
1412         copy_v3_v3(mat[3], loc);
1413         BKE_object_apply_mat4(ob, mat, true, true);
1414         copy_v3_v3(mat[3], ob->loc);
1415         *ob = ob_prev;
1416         copy_v3_v3(ob->loc, mat[3]);
1417 }
1418
1419 static void object_orient_to_location(
1420         Object *ob, float rot_orig[3][3], const float axis[3], const float location[3])
1421 {
1422         float delta[3];
1423         sub_v3_v3v3(delta, ob->obmat[3], location);
1424         if (normalize_v3(delta) != 0.0f) {
1425                 if (len_squared_v3v3(delta, axis) > FLT_EPSILON) {
1426                         float delta_rot[3][3];
1427                         float final_rot[3][3];
1428                         rotation_between_vecs_to_mat3(delta_rot, axis, delta);
1429
1430                         mul_m3_m3m3(final_rot, delta_rot, rot_orig);
1431
1432                         object_apply_rotation(ob, final_rot);
1433
1434                         DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
1435                 }
1436         }
1437 }
1438
1439 static void object_transform_axis_target_cancel(bContext *C, wmOperator *op)
1440 {
1441         struct XFormAxisData *xfd = op->customdata;
1442         struct XFormAxisItem *item = xfd->object_data;
1443         for (int i = 0; i < xfd->object_data_len; i++, item++) {
1444                 BKE_object_tfm_restore(item->ob, item->obtfm);
1445                 DEG_id_tag_update(&item->ob->id, ID_RECALC_TRANSFORM);
1446                 WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob);
1447         }
1448
1449         object_transform_axis_target_free_data(op);
1450 }
1451
1452 static int object_transform_axis_target_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1453 {
1454         ViewContext vc;
1455         ED_view3d_viewcontext_init(C, &vc);
1456
1457         if (vc.obact == NULL || !object_is_target_compat(vc.obact)) {
1458                 /* Falls back to texture space transform. */
1459                 return OPERATOR_PASS_THROUGH;
1460         }
1461
1462
1463 #ifdef USE_RENDER_OVERRIDE
1464         int flag2_prev = vc.v3d->flag2;
1465         vc.v3d->flag2 |= V3D_RENDER_OVERRIDE;
1466 #endif
1467
1468         ED_view3d_autodist_init(vc.depsgraph, vc.ar, vc.v3d, 0);
1469
1470         if (vc.rv3d->depths != NULL) {
1471                 vc.rv3d->depths->damaged = true;
1472         }
1473         ED_view3d_depth_update(vc.ar);
1474
1475 #ifdef USE_RENDER_OVERRIDE
1476         vc.v3d->flag2 = flag2_prev;
1477 #endif
1478
1479         if (vc.rv3d->depths == NULL) {
1480                 BKE_report(op->reports, RPT_WARNING, "Unable to access depth buffer, using view plane");
1481                 return OPERATOR_CANCELLED;
1482         }
1483
1484         ED_region_tag_redraw(vc.ar);
1485
1486         struct XFormAxisData *xfd;
1487         xfd = op->customdata = MEM_callocN(sizeof(struct XFormAxisData), __func__);
1488
1489         /* Don't change this at runtime. */
1490         xfd->vc = vc;
1491         xfd->vc.mval[0] = event->mval[0];
1492         xfd->vc.mval[1] = event->mval[1];
1493
1494         xfd->prev.depth = 1.0f;
1495         xfd->prev.is_depth_valid = false;
1496         xfd->prev.is_normal_valid = false;
1497         xfd->is_translate = false;
1498
1499         xfd->init_event = WM_userdef_event_type_from_keymap_type(event->type);
1500
1501         {
1502                 struct XFormAxisItem *object_data = NULL;
1503                 BLI_array_declare(object_data);
1504
1505                 struct XFormAxisItem *item = BLI_array_append_ret(object_data);
1506                 item->ob = xfd->vc.obact;
1507
1508                 CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
1509                 {
1510                         if ((ob != xfd->vc.obact) && object_is_target_compat(ob)) {
1511                                 item = BLI_array_append_ret(object_data);
1512                                 item->ob = ob;
1513                         }
1514                 }
1515                 CTX_DATA_END;
1516
1517                 xfd->object_data = object_data;
1518                 xfd->object_data_len = BLI_array_len(object_data);
1519
1520                 if (xfd->object_data_len != BLI_array_len(object_data)) {
1521                         xfd->object_data = MEM_reallocN(xfd->object_data, xfd->object_data_len * sizeof(*xfd->object_data));
1522                 }
1523         }
1524
1525         {
1526                 struct XFormAxisItem *item = xfd->object_data;
1527                 for (int i = 0; i < xfd->object_data_len; i++, item++) {
1528                         item->obtfm = BKE_object_tfm_backup(item->ob);
1529                         BKE_object_rot_to_mat3(item->ob, item->rot_mat, true);
1530                 }
1531         }
1532
1533         WM_event_add_modal_handler(C, op);
1534
1535         return OPERATOR_RUNNING_MODAL;
1536 }
1537
1538 static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const wmEvent *event)
1539 {
1540         struct XFormAxisData *xfd = op->customdata;
1541         ARegion *ar = xfd->vc.ar;
1542
1543         view3d_operator_needs_opengl(C);
1544
1545         const bool is_translate = (event->ctrl != 0);
1546         const bool is_translate_init = is_translate && (xfd->is_translate != is_translate);
1547
1548         if (event->type == MOUSEMOVE || is_translate_init) {
1549                 const ViewDepths *depths = xfd->vc.rv3d->depths;
1550                 if (depths &&
1551                     ((unsigned int)event->mval[0] < depths->w) &&
1552                     ((unsigned int)event->mval[1] < depths->h))
1553                 {
1554                         double depth = (double)ED_view3d_depth_read_cached(&xfd->vc, event->mval);
1555                         float location_world[3];
1556                         if (depth == 1.0f) {
1557                                 if (xfd->prev.is_depth_valid) {
1558                                         depth = (double)xfd->prev.depth;
1559                                 }
1560                         }
1561
1562 #ifdef USE_FAKE_DEPTH_INIT
1563                         /* First time only. */
1564                         if (depth == 1.0f) {
1565                                 if (xfd->prev.is_depth_valid == false) {
1566                                         object_transform_axis_target_calc_depth_init(xfd, event->mval);
1567                                         if (xfd->prev.is_depth_valid) {
1568                                                 depth = (double)xfd->prev.depth;
1569                                         }
1570                                 }
1571                         }
1572 #endif
1573
1574                         if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
1575                                 xfd->prev.depth = depth;
1576                                 xfd->prev.is_depth_valid = true;
1577                                 if (ED_view3d_depth_unproject(ar, event->mval, depth, location_world)) {
1578                                         if (is_translate) {
1579
1580                                                 float normal[3];
1581                                                 bool normal_found = false;
1582                                                 if (ED_view3d_depth_read_cached_normal(&xfd->vc, event->mval, normal)) {
1583                                                         normal_found = true;
1584
1585                                                         /* cheap attempt to smooth normals out a bit! */
1586                                                         const uint ofs = 2;
1587                                                         for (uint x = -ofs; x <= ofs; x += ofs / 2) {
1588                                                                 for (uint y = -ofs; y <= ofs; y += ofs / 2) {
1589                                                                         if (x != 0 && y != 0) {
1590                                                                                 int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y};
1591                                                                                 float n[3];
1592                                                                                 if (ED_view3d_depth_read_cached_normal(
1593                                                                                         &xfd->vc, mval_ofs, n))
1594                                                                                 {
1595                                                                                         add_v3_v3(normal, n);
1596                                                                                 }
1597                                                                         }
1598                                                                 }
1599                                                         }
1600                                                         normalize_v3(normal);
1601                                                 }
1602                                                 else if (xfd->prev.is_normal_valid) {
1603                                                         copy_v3_v3(normal, xfd->prev.normal);
1604                                                         normal_found = true;
1605                                                 }
1606
1607                                                 if (normal_found) {
1608 #ifdef USE_RELATIVE_ROTATION
1609                                                         if (is_translate_init && xfd->object_data_len > 1) {
1610                                                                 float xform_rot_offset_inv_first[3][3];
1611                                                                 struct XFormAxisItem *item = xfd->object_data;
1612                                                                 for (int i = 0; i < xfd->object_data_len; i++, item++) {
1613                                                                         copy_m3_m4(item->xform_rot_offset, item->ob->obmat);
1614                                                                         normalize_m3(item->xform_rot_offset);
1615
1616                                                                         if (i == 0) {
1617                                                                                 invert_m3_m3(xform_rot_offset_inv_first, xfd->object_data[0].xform_rot_offset);
1618                                                                         }
1619                                                                         else {
1620                                                                                 mul_m3_m3m3(item->xform_rot_offset,
1621                                                                                             item->xform_rot_offset,
1622                                                                                             xform_rot_offset_inv_first);
1623                                                                         }
1624                                                                 }
1625                                                         }
1626
1627 #endif
1628
1629                                                         struct XFormAxisItem *item = xfd->object_data;
1630                                                         for (int i = 0; i < xfd->object_data_len; i++, item++) {
1631                                                                 if (is_translate_init) {
1632                                                                         float ob_axis[3];
1633                                                                         item->xform_dist = len_v3v3(item->ob->obmat[3], location_world);
1634                                                                         normalize_v3_v3(ob_axis, item->ob->obmat[2]);
1635                                                                         /* Scale to avoid adding distance when moving between surfaces. */
1636                                                                         float scale = fabsf(dot_v3v3(ob_axis, normal));
1637                                                                         item->xform_dist *= scale;
1638                                                                 }
1639
1640                                                                 float target_normal[3];
1641                                                                 copy_v3_v3(target_normal, normal);
1642
1643 #ifdef USE_RELATIVE_ROTATION
1644                                                                 if (i != 0) {
1645                                                                         mul_m3_v3(item->xform_rot_offset, target_normal);
1646                                                                 }
1647 #endif
1648                                                                 {
1649                                                                         float loc[3];
1650
1651                                                                         copy_v3_v3(loc, location_world);
1652                                                                         madd_v3_v3fl(loc, target_normal, item->xform_dist);
1653                                                                         object_apply_location(item->ob, loc);
1654                                                                         copy_v3_v3(item->ob->obmat[3], loc);  /* so orient behaves as expected */
1655                                                                 }
1656
1657                                                                 object_orient_to_location(item->ob, item->rot_mat, item->rot_mat[2], location_world);
1658                                                                 WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob);
1659                                                         }
1660                                                         copy_v3_v3(xfd->prev.normal, normal);
1661                                                         xfd->prev.is_normal_valid = true;
1662                                                 }
1663                                         }
1664                                         else {
1665                                                 struct XFormAxisItem *item = xfd->object_data;
1666                                                 for (int i = 0; i < xfd->object_data_len; i++, item++) {
1667                                                         object_orient_to_location(item->ob, item->rot_mat, item->rot_mat[2], location_world);
1668                                                         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob);
1669                                                 }
1670                                                 xfd->prev.is_normal_valid = false;
1671                                         }
1672                                 }
1673                         }
1674                 }
1675                 xfd->is_translate = is_translate;
1676
1677                 ED_region_tag_redraw(xfd->vc.ar);
1678         }
1679
1680         bool is_finished = false;
1681
1682         if (ISMOUSE(xfd->init_event)) {
1683                 if ((event->type == xfd->init_event) && (event->val == KM_RELEASE)) {
1684                         is_finished = true;
1685                 }
1686         }
1687         else {
1688                 if (ELEM(event->type, LEFTMOUSE, RETKEY, PADENTER)) {
1689                         is_finished = true;
1690                 }
1691         }
1692
1693         if (is_finished) {
1694                 object_transform_axis_target_free_data(op);
1695                 return OPERATOR_FINISHED;
1696         }
1697         else if (ELEM(event->type, ESCKEY, RIGHTMOUSE)) {
1698                 object_transform_axis_target_cancel(C, op);
1699                 return OPERATOR_CANCELLED;
1700         }
1701
1702
1703         return OPERATOR_RUNNING_MODAL;
1704 }
1705
1706 void OBJECT_OT_transform_axis_target(wmOperatorType *ot)
1707 {
1708         /* identifiers */
1709         ot->name = "Interactive Light Track to Cursor";
1710         ot->description = "Interactively point cameras and lights to a location (Ctrl translates)";
1711         ot->idname = "OBJECT_OT_transform_axis_target";
1712
1713         /* api callbacks */
1714         ot->invoke = object_transform_axis_target_invoke;
1715         ot->cancel = object_transform_axis_target_cancel;
1716         ot->modal = object_transform_axis_target_modal;
1717         ot->poll = ED_operator_region_view3d_active;
1718
1719         /* flags */
1720         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
1721 }
1722
1723 #undef USE_RELATIVE_ROTATION
1724
1725 /** \} */