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