svn merge ^/trunk/blender -r46714:46724 --- before tile branch merge
[blender.git] / source / blender / editors / transform / transform_ops.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  * Contributor(s): none yet.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/editors/transform/transform_ops.c
24  *  \ingroup edtransform
25  */
26
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_scene_types.h"
31
32 #include "RNA_access.h"
33 #include "RNA_define.h"
34 #include "RNA_enum_types.h"
35
36 #include "BLI_math.h"
37 #include "BLI_utildefines.h"
38
39 #include "BKE_context.h"
40 #include "BKE_global.h"
41 #include "BKE_armature.h"
42
43 #include "WM_api.h"
44 #include "WM_types.h"
45
46 #include "UI_interface.h"
47 #include "UI_resources.h"
48
49 #include "ED_screen.h"
50
51 #include "transform.h"
52
53 typedef struct TransformModeItem
54 {
55         char *idname;
56         int             mode;
57         void (*opfunc)(wmOperatorType*);
58 } TransformModeItem;
59
60 static float VecOne[3] = {1, 1, 1};
61
62 static char OP_TRANSLATION[] = "TRANSFORM_OT_translate";
63 static char OP_ROTATION[] = "TRANSFORM_OT_rotate";
64 static char OP_TOSPHERE[] = "TRANSFORM_OT_tosphere";
65 static char OP_RESIZE[] = "TRANSFORM_OT_resize";
66 static char OP_SHEAR[] = "TRANSFORM_OT_shear";
67 static char OP_WARP[] = "TRANSFORM_OT_warp";
68 static char OP_SHRINK_FATTEN[] = "TRANSFORM_OT_shrink_fatten";
69 static char OP_PUSH_PULL[] = "TRANSFORM_OT_push_pull";
70 static char OP_TILT[] = "TRANSFORM_OT_tilt";
71 static char OP_TRACKBALL[] = "TRANSFORM_OT_trackball";
72 static char OP_MIRROR[] = "TRANSFORM_OT_mirror";
73 static char OP_EDGE_SLIDE[] = "TRANSFORM_OT_edge_slide";
74 static char OP_EDGE_CREASE[] = "TRANSFORM_OT_edge_crease";
75 static char OP_EDGE_BWEIGHT[] = "TRANSFORM_OT_edge_bevelweight";
76 static char OP_SEQ_SLIDE[] = "TRANSFORM_OT_seq_slide";
77
78 static void TRANSFORM_OT_translate(struct wmOperatorType *ot);
79 static void TRANSFORM_OT_rotate(struct wmOperatorType *ot);
80 static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot);
81 static void TRANSFORM_OT_resize(struct wmOperatorType *ot);
82 static void TRANSFORM_OT_shear(struct wmOperatorType *ot);
83 static void TRANSFORM_OT_warp(struct wmOperatorType *ot);
84 static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot);
85 static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot);
86 static void TRANSFORM_OT_tilt(struct wmOperatorType *ot);
87 static void TRANSFORM_OT_trackball(struct wmOperatorType *ot);
88 static void TRANSFORM_OT_mirror(struct wmOperatorType *ot);
89 static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot);
90 static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot);
91 static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot);
92 static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot);
93
94 static TransformModeItem transform_modes[] =
95 {
96         {OP_TRANSLATION, TFM_TRANSLATION, TRANSFORM_OT_translate},
97         {OP_ROTATION, TFM_ROTATION, TRANSFORM_OT_rotate},
98         {OP_TOSPHERE, TFM_TOSPHERE, TRANSFORM_OT_tosphere},
99         {OP_RESIZE, TFM_RESIZE, TRANSFORM_OT_resize},
100         {OP_SHEAR, TFM_SHEAR, TRANSFORM_OT_shear},
101         {OP_WARP, TFM_WARP, TRANSFORM_OT_warp},
102         {OP_SHRINK_FATTEN, TFM_SHRINKFATTEN, TRANSFORM_OT_shrink_fatten},
103         {OP_PUSH_PULL, TFM_PUSHPULL, TRANSFORM_OT_push_pull},
104         {OP_TILT, TFM_TILT, TRANSFORM_OT_tilt},
105         {OP_TRACKBALL, TFM_TRACKBALL, TRANSFORM_OT_trackball},
106         {OP_MIRROR, TFM_MIRROR, TRANSFORM_OT_mirror},
107         {OP_EDGE_SLIDE, TFM_EDGE_SLIDE, TRANSFORM_OT_edge_slide},
108         {OP_EDGE_CREASE, TFM_CREASE, TRANSFORM_OT_edge_crease},
109         {OP_EDGE_BWEIGHT, TFM_BWEIGHT, TRANSFORM_OT_edge_bevelweight},
110         {OP_SEQ_SLIDE, TFM_SEQ_SLIDE, TRANSFORM_OT_seq_slide},
111         {NULL, 0}
112 };
113
114 EnumPropertyItem transform_mode_types[] =
115 {
116         {TFM_INIT, "INIT", 0, "Init", ""},
117         {TFM_DUMMY, "DUMMY", 0, "Dummy", ""},
118         {TFM_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
119         {TFM_ROTATION, "ROTATION", 0, "Rotation", ""},
120         {TFM_RESIZE, "RESIZE", 0, "Resize", ""},
121         {TFM_TOSPHERE, "TOSPHERE", 0, "Tosphere", ""},
122         {TFM_SHEAR, "SHEAR", 0, "Shear", ""},
123         {TFM_WARP, "WARP", 0, "Warp", ""},
124         {TFM_SHRINKFATTEN, "SHRINKFATTEN", 0, "Shrinkfatten", ""},
125         {TFM_TILT, "TILT", 0, "Tilt", ""},
126         {TFM_TRACKBALL, "TRACKBALL", 0, "Trackball", ""},
127         {TFM_PUSHPULL, "PUSHPULL", 0, "Pushpull", ""},
128         {TFM_CREASE, "CREASE", 0, "Crease", ""},
129         {TFM_MIRROR, "MIRROR", 0, "Mirror", ""},
130         {TFM_BONESIZE, "BONE_SIZE", 0, "Bonesize", ""},
131         {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""},
132         {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""},
133         {TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""},
134         {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""},
135         {TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""},
136         {TFM_TIME_SCALE, "TIME_SCALE", 0, "Time_Scale", ""},
137         {TFM_TIME_EXTEND, "TIME_EXTEND", 0, "Time_Extend", ""},
138         {TFM_BAKE_TIME, "BAKE_TIME", 0, "Bake_Time", ""},
139         {TFM_BEVEL, "BEVEL", 0, "Bevel", ""},
140         {TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""},
141         {TFM_ALIGN, "ALIGN", 0, "Align", ""},
142         {TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""},
143         {TFM_SEQ_SLIDE, "SEQSLIDE", 0, "Sequence Slide", ""},
144         {0, NULL, 0, NULL, NULL}
145 };
146
147 static int snap_type_exec(bContext *C, wmOperator *op)
148 {
149         ToolSettings *ts= CTX_data_tool_settings(C);
150
151         ts->snap_mode = RNA_enum_get(op->ptr, "type");
152
153         WM_event_add_notifier(C, NC_SCENE|ND_TOOLSETTINGS, NULL); /* header redraw */
154
155         return OPERATOR_FINISHED;
156 }
157
158 static void TRANSFORM_OT_snap_type(wmOperatorType *ot)
159 {
160         /* identifiers */
161         ot->name = "Snap Type";
162         ot->description = "Set the snap element type";
163         ot->idname = "TRANSFORM_OT_snap_type";
164
165         /* api callbacks */
166         ot->invoke = WM_menu_invoke;
167         ot->exec = snap_type_exec;
168
169         ot->poll = ED_operator_areaactive;
170
171         /* flags */
172         ot->flag = OPTYPE_UNDO;
173
174         /* props */
175         ot->prop = RNA_def_enum(ot->srna, "type", snap_element_items, 0, "Type", "Set the snap element type");
176
177 }
178
179 static int select_orientation_exec(bContext *C, wmOperator *op)
180 {
181         int orientation = RNA_enum_get(op->ptr, "orientation");
182
183         BIF_selectTransformOrientationValue(C, orientation);
184         
185         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
186
187         return OPERATOR_FINISHED;
188 }
189
190 static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
191 {
192         uiPopupMenu *pup;
193         uiLayout *layout;
194
195         pup= uiPupMenuBegin(C, "Orientation", ICON_NONE);
196         layout= uiPupMenuLayout(pup);
197         uiItemsEnumO(layout, "TRANSFORM_OT_select_orientation", "orientation");
198         uiPupMenuEnd(C, pup);
199
200         return OPERATOR_CANCELLED;
201 }
202
203 static void TRANSFORM_OT_select_orientation(struct wmOperatorType *ot)
204 {
205         PropertyRNA *prop;
206
207         /* identifiers */
208         ot->name   = "Select Orientation";
209         ot->description = "Select transformation orientation";
210         ot->idname = "TRANSFORM_OT_select_orientation";
211         ot->flag   = OPTYPE_UNDO;
212
213         /* api callbacks */
214         ot->invoke = select_orientation_invoke;
215         ot->exec   = select_orientation_exec;
216         ot->poll   = ED_operator_view3d_active;
217
218         prop= RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE);
219         RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation");
220         RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
221 }
222
223
224 static int delete_orientation_exec(bContext *C, wmOperator *UNUSED(op))
225 {
226         View3D *v3d = CTX_wm_view3d(C);
227         int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
228
229         BIF_removeTransformOrientationIndex(C, selected_index);
230         
231         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
232         WM_event_add_notifier(C, NC_SCENE|NA_EDITED, CTX_data_scene(C));
233
234         return OPERATOR_FINISHED;
235 }
236
237 static int delete_orientation_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
238 {
239         return delete_orientation_exec(C, op);
240 }
241
242 static int delete_orientation_poll(bContext *C)
243 {
244         int selected_index = -1;
245         View3D *v3d = CTX_wm_view3d(C);
246         
247         if (ED_operator_areaactive(C) == 0)
248                 return 0;
249         
250         
251         if (v3d) {
252                 selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
253         }
254         
255         return selected_index >= 0;
256 }
257
258 static void TRANSFORM_OT_delete_orientation(struct wmOperatorType *ot)
259 {
260         /* identifiers */
261         ot->name   = "Delete Orientation";
262         ot->description = "Delete transformation orientation";
263         ot->idname = "TRANSFORM_OT_delete_orientation";
264         ot->flag   = OPTYPE_UNDO;
265
266         /* api callbacks */
267         ot->invoke = delete_orientation_invoke;
268         ot->exec   = delete_orientation_exec;
269         ot->poll   = delete_orientation_poll;
270 }
271
272 static int create_orientation_exec(bContext *C, wmOperator *op)
273 {
274         char name[MAX_NAME];
275         int use = RNA_boolean_get(op->ptr, "use");
276         int overwrite = RNA_boolean_get(op->ptr, "overwrite");
277         
278         RNA_string_get(op->ptr, "name", name);
279
280         BIF_createTransformOrientation(C, op->reports, name, use, overwrite);
281
282         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
283         WM_event_add_notifier(C, NC_SCENE|NA_EDITED, CTX_data_scene(C));
284         
285         return OPERATOR_FINISHED;
286 }
287
288 static int create_orientation_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
289 {
290         return create_orientation_exec(C, op);
291 }
292
293 static void TRANSFORM_OT_create_orientation(struct wmOperatorType *ot)
294 {
295         /* identifiers */
296         ot->name   = "Create Orientation";
297         ot->description = "Create transformation orientation from selection";
298         ot->idname = "TRANSFORM_OT_create_orientation";
299         ot->flag   = OPTYPE_REGISTER|OPTYPE_UNDO;
300
301         /* api callbacks */
302         ot->invoke = create_orientation_invoke;
303         ot->exec   = create_orientation_exec;
304         ot->poll   = ED_operator_areaactive;
305         ot->flag   = OPTYPE_REGISTER|OPTYPE_UNDO;
306
307         RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Text to insert at the cursor position");
308         RNA_def_boolean(ot->srna, "use", 0, "Use after creation", "Select orientation after its creation");
309         RNA_def_boolean(ot->srna, "overwrite", 0, "Overwrite previous", "Overwrite previously created orientation with same name");
310 }
311
312 static void transformops_exit(bContext *C, wmOperator *op)
313 {
314         saveTransform(C, op->customdata, op);
315         MEM_freeN(op->customdata);
316         op->customdata = NULL;
317         G.moving = 0;
318 }
319
320 static int transformops_data(bContext *C, wmOperator *op, wmEvent *event)
321 {
322         int retval = 1;
323         if (op->customdata == NULL) {
324                 TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data2");
325                 TransformModeItem *tmode;
326                 int mode = -1;
327
328                 for (tmode = transform_modes; tmode->idname; tmode++) {
329                         if (op->type->idname == tmode->idname) {
330                                 mode = tmode->mode;
331                                 break;
332                         }
333                 }
334
335                 if (mode == -1) {
336                         mode = RNA_enum_get(op->ptr, "mode");
337                 }
338
339                 retval = initTransform(C, t, op, event, mode);
340                 G.moving = 1;
341
342                 /* store data */
343                 if (retval) {
344                         op->customdata = t;
345                 }
346                 else {
347                         MEM_freeN(t);
348                 }
349         }
350
351         return retval; /* return 0 on error */
352 }
353
354 static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
355 {
356         int exit_code;
357
358         TransInfo *t = op->customdata;
359
360 #if 0
361         // stable 2D mouse coords map to different 3D coords while the 3D mouse is active
362         // in other words, 2D deltas are no longer good enough!
363         // disable until individual 'transformers' behave better
364
365         if (event->type == NDOF_MOTION)
366                 return OPERATOR_PASS_THROUGH;
367 #endif
368
369         /* XXX insert keys are called here, and require context */
370         t->context= C;
371         exit_code = transformEvent(t, event);
372         t->context= NULL;
373
374         transformApply(C, t);
375
376         exit_code |= transformEnd(C, t);
377
378         if ((exit_code & OPERATOR_RUNNING_MODAL) == 0) {
379                 transformops_exit(C, op);
380                 exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
381         }
382
383         return exit_code;
384 }
385
386 static int transform_cancel(bContext *C, wmOperator *op)
387 {
388         TransInfo *t = op->customdata;
389
390         t->state = TRANS_CANCEL;
391         transformEnd(C, t);
392         transformops_exit(C, op);
393
394         return OPERATOR_CANCELLED;
395 }
396
397 static int transform_exec(bContext *C, wmOperator *op)
398 {
399         TransInfo *t;
400
401         if (!transformops_data(C, op, NULL)) {
402                 G.moving = 0;
403                 return OPERATOR_CANCELLED;
404         }
405
406         t = op->customdata;
407
408         t->options |= CTX_AUTOCONFIRM;
409
410         transformApply(C, t);
411
412         transformEnd(C, t);
413
414         transformops_exit(C, op);
415         
416         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
417
418         return OPERATOR_FINISHED;
419 }
420
421 static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
422 {
423         if (!transformops_data(C, op, event)) {
424                 G.moving = 0;
425                 return OPERATOR_CANCELLED;
426         }
427
428         if (RNA_struct_property_is_set(op->ptr, "value")) {
429                 return transform_exec(C, op);
430         }
431         else {
432                 /* add temp handler */
433                 WM_event_add_modal_handler(C, op);
434
435                 op->flag |= OP_GRAB_POINTER; // XXX maybe we want this with the manipulator only?
436                 return OPERATOR_RUNNING_MODAL;
437         }
438 }
439
440 void Transform_Properties(struct wmOperatorType *ot, int flags)
441 {
442         PropertyRNA *prop;
443
444         if (flags & P_AXIS) {
445                 prop= RNA_def_property(ot->srna, "axis", PROP_FLOAT, PROP_DIRECTION);
446                 RNA_def_property_array(prop, 3);
447                 /* Make this not hidden when there's a nice axis selection widget */
448                 RNA_def_property_flag(prop, PROP_HIDDEN);
449                 RNA_def_property_ui_text(prop, "Axis", "The axis around which the transformation occurs");
450
451         }
452
453         if (flags & P_CONSTRAINT) {
454                 RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
455                 prop= RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE);
456                 RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation");
457                 RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
458
459                 
460         }
461
462         if (flags & P_MIRROR) {
463                 RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
464         }
465
466
467         if (flags & P_PROPORTIONAL) {
468                 RNA_def_enum(ot->srna, "proportional", proportional_editing_items, 0, "Proportional Editing", "");
469                 RNA_def_enum(ot->srna, "proportional_edit_falloff", proportional_falloff_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode");
470                 RNA_def_float(ot->srna, "proportional_size", 1, 0.00001f, FLT_MAX, "Proportional Size", "", 0.001, 100);
471         }
472
473         if (flags & P_SNAP) {
474                 prop= RNA_def_boolean(ot->srna, "snap", 0, "Use Snapping Options", "");
475                 RNA_def_property_flag(prop, PROP_HIDDEN);
476
477                 if (flags & P_GEO_SNAP) {
478                         prop= RNA_def_enum(ot->srna, "snap_target", snap_target_items, 0, "Target", "");
479                         RNA_def_property_flag(prop, PROP_HIDDEN);
480                         prop= RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
481                         RNA_def_property_flag(prop, PROP_HIDDEN);
482                         
483                         if (flags & P_ALIGN_SNAP) {
484                                 prop= RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", "");
485                                 RNA_def_property_flag(prop, PROP_HIDDEN);
486                                 prop= RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX);
487                                 RNA_def_property_flag(prop, PROP_HIDDEN);
488                         }
489                 }
490         }
491
492         if (flags & P_OPTIONS) {
493                 RNA_def_boolean(ot->srna, "texture_space", 0, "Edit Texture Space", "Edit Object data texture space");
494         }
495
496         if (flags & P_CORRECT_UV) {
497                 RNA_def_boolean(ot->srna, "correct_uv", 0, "Correct UVs", "Correct UV coordinates when transforming");
498         }
499
500         // Add confirm method all the time. At the end because it's not really that important and should be hidden only in log, not in keymap edit
501         /*prop =*/ RNA_def_boolean(ot->srna, "release_confirm", 0, "Confirm on Release", "Always confirm operation when releasing button");
502         //RNA_def_property_flag(prop, PROP_HIDDEN);
503 }
504
505 static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
506 {
507         /* identifiers */
508         ot->name   = "Translate";
509         ot->description = "Translate (move) selected items";
510         ot->idname = OP_TRANSLATION;
511         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
512
513         /* api callbacks */
514         ot->invoke = transform_invoke;
515         ot->exec   = transform_exec;
516         ot->modal  = transform_modal;
517         ot->cancel = transform_cancel;
518         ot->poll   = ED_operator_screenactive;
519
520         RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
521
522         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_ALIGN_SNAP|P_OPTIONS);
523 }
524
525 static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
526 {
527         /* identifiers */
528         ot->name   = "Resize";
529         ot->description = "Scale (resize) selected items"; 
530         ot->idname = OP_RESIZE;
531         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
532
533         /* api callbacks */
534         ot->invoke = transform_invoke;
535         ot->exec   = transform_exec;
536         ot->modal  = transform_modal;
537         ot->cancel = transform_cancel;
538         ot->poll   = ED_operator_screenactive;
539
540         RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
541
542         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP|P_OPTIONS);
543 }
544
545
546 static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
547 {
548         /* identifiers */
549         ot->name   = "Trackball";
550         ot->description = "Trackball style rotation of selected items";
551         ot->idname = OP_TRACKBALL;
552         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
553
554         /* api callbacks */
555         ot->invoke = transform_invoke;
556         ot->exec   = transform_exec;
557         ot->modal  = transform_modal;
558         ot->cancel = transform_cancel;
559         ot->poll   = ED_operator_screenactive;
560
561         RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
562
563         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
564 }
565
566 static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
567 {
568         /* identifiers */
569         ot->name   = "Rotate";
570         ot->description = "Rotate selected items";
571         ot->idname = OP_ROTATION;
572         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
573
574         /* api callbacks */
575         ot->invoke = transform_invoke;
576         ot->exec   = transform_exec;
577         ot->modal  = transform_modal;
578         ot->cancel = transform_cancel;
579         ot->poll   = ED_operator_screenactive;
580
581         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
582
583         Transform_Properties(ot, P_AXIS|P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP);
584 }
585
586 static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
587 {
588         /* identifiers */
589         ot->name   = "Tilt";
590         /* optionals - 
591          * "Tilt selected vertices"
592          * "Specify an extra axis rotation for selected vertices of 3d curve" */
593         ot->description = "Tilt selected control vertices of 3d curve"; 
594         ot->idname = OP_TILT;
595         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
596
597         /* api callbacks */
598         ot->invoke = transform_invoke;
599         ot->exec   = transform_exec;
600         ot->modal  = transform_modal;
601         ot->cancel = transform_cancel;
602         ot->poll   = ED_operator_editcurve_3d;
603
604         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
605
606         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_SNAP);
607 }
608
609 static void TRANSFORM_OT_warp(struct wmOperatorType *ot)
610 {
611         /* identifiers */
612         ot->name   = "Warp";
613         ot->description = "Warp selected items around the cursor";
614         ot->idname = OP_WARP;
615         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
616
617         /* api callbacks */
618         ot->invoke = transform_invoke;
619         ot->exec   = transform_exec;
620         ot->modal  = transform_modal;
621         ot->cancel = transform_cancel;
622         ot->poll   = ED_operator_screenactive;
623
624         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
625
626         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
627         // XXX Warp axis?
628 }
629
630 static void TRANSFORM_OT_shear(struct wmOperatorType *ot)
631 {
632         /* identifiers */
633         ot->name   = "Shear";
634         ot->description = "Shear selected items along the horizontal screen axis";
635         ot->idname = OP_SHEAR;
636         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
637
638         /* api callbacks */
639         ot->invoke = transform_invoke;
640         ot->exec   = transform_exec;
641         ot->modal  = transform_modal;
642         ot->cancel = transform_cancel;
643         ot->poll   = ED_operator_screenactive;
644
645         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
646
647         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
648         // XXX Shear axis?
649 }
650
651 static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot)
652 {
653         /* identifiers */
654         ot->name   = "Push/Pull";
655         ot->description = "Push/Pull selected items";
656         ot->idname = OP_PUSH_PULL;
657         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
658
659         /* api callbacks */
660         ot->invoke = transform_invoke;
661         ot->exec   = transform_exec;
662         ot->modal  = transform_modal;
663         ot->cancel = transform_cancel;
664         ot->poll   = ED_operator_screenactive;
665
666         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Distance", "", -FLT_MAX, FLT_MAX);
667
668         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
669 }
670
671 static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot)
672 {
673         /* identifiers */
674         ot->name   = "Shrink/Fatten";
675         ot->description = "Shrink/fatten selected vertices along normals";
676         ot->idname = OP_SHRINK_FATTEN;
677         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
678
679         /* api callbacks */
680         ot->invoke = transform_invoke;
681         ot->exec   = transform_exec;
682         ot->modal  = transform_modal;
683         ot->cancel = transform_cancel;
684         ot->poll   = ED_operator_editmesh;
685
686         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
687
688         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
689 }
690
691 static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot)
692 {
693         /* identifiers */
694         ot->name   = "To Sphere";
695         //added "around mesh center" to differentiate between "MESH_OT_vertices_to_sphere()" 
696         ot->description = "Move selected vertices outward in a spherical shape around mesh center";
697         ot->idname = OP_TOSPHERE;
698         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
699
700         /* api callbacks */
701         ot->invoke = transform_invoke;
702         ot->exec   = transform_exec;
703         ot->modal  = transform_modal;
704         ot->cancel = transform_cancel;
705         ot->poll   = ED_operator_screenactive;
706
707         RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
708
709         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
710 }
711
712 static void TRANSFORM_OT_mirror(struct wmOperatorType *ot)
713 {
714         /* identifiers */
715         ot->name   = "Mirror";
716         ot->description = "Mirror selected vertices around one or more axes";
717         ot->idname = OP_MIRROR;
718         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
719
720         /* api callbacks */
721         ot->invoke = transform_invoke;
722         ot->exec   = transform_exec;
723         ot->modal  = transform_modal;
724         ot->cancel = transform_cancel;
725         ot->poll   = ED_operator_screenactive;
726
727         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL);
728 }
729
730 static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
731 {
732         /* identifiers */
733         ot->name   = "Edge Slide";
734         ot->description = "Slide an edge loop along a mesh"; 
735         ot->idname = OP_EDGE_SLIDE;
736         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
737
738         /* api callbacks */
739         ot->invoke = transform_invoke;
740         ot->exec   = transform_exec;
741         ot->modal  = transform_modal;
742         ot->cancel = transform_cancel;
743         ot->poll   = ED_operator_editmesh;
744
745         RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
746
747         Transform_Properties(ot, P_MIRROR|P_SNAP|P_CORRECT_UV);
748 }
749
750 static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
751 {
752         /* identifiers */
753         ot->name   = "Edge Crease";
754         ot->description = "Change the crease of edges";
755         ot->idname = OP_EDGE_CREASE;
756         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
757
758         /* api callbacks */
759         ot->invoke = transform_invoke;
760         ot->exec   = transform_exec;
761         ot->modal  = transform_modal;
762         ot->cancel = transform_cancel;
763         ot->poll   = ED_operator_editmesh;
764
765         RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
766
767         Transform_Properties(ot, P_SNAP);
768 }
769
770 static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot)
771 {
772         /* identifiers */
773         ot->name   = "Edge Bevel Weight";
774         ot->description = "Change the bevel weight of edges";
775         ot->idname = OP_EDGE_BWEIGHT;
776         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
777
778         /* api callbacks */
779         ot->invoke = transform_invoke;
780         ot->exec   = transform_exec;
781         ot->modal  = transform_modal;
782         ot->cancel = transform_cancel;
783         ot->poll   = ED_operator_editmesh;
784
785         RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
786
787         Transform_Properties(ot, P_SNAP);
788 }
789
790 static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
791 {
792         /* identifiers */
793         ot->name   = "Sequence Slide";
794         ot->description = "Slide a sequence strip in time";
795         ot->idname = OP_SEQ_SLIDE;
796         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
797
798         /* api callbacks */
799         ot->invoke = transform_invoke;
800         ot->exec   = transform_exec;
801         ot->modal  = transform_modal;
802         ot->cancel = transform_cancel;
803         ot->poll   = ED_operator_sequencer_active;
804
805         RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
806
807         Transform_Properties(ot, P_SNAP);
808 }
809
810 static void TRANSFORM_OT_transform(struct wmOperatorType *ot)
811 {
812         PropertyRNA *prop;
813
814         /* identifiers */
815         ot->name   = "Transform";
816         ot->description = "Transform selected items by mode type";
817         ot->idname = "TRANSFORM_OT_transform";
818         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
819
820         /* api callbacks */
821         ot->invoke = transform_invoke;
822         ot->exec   = transform_exec;
823         ot->modal  = transform_modal;
824         ot->cancel = transform_cancel;
825         ot->poll   = ED_operator_screenactive;
826
827         prop= RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", "");
828         RNA_def_property_flag(prop, PROP_HIDDEN);
829
830         RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
831
832         Transform_Properties(ot, P_AXIS|P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_ALIGN_SNAP);
833 }
834
835 void transform_operatortypes(void)
836 {
837         TransformModeItem *tmode;
838
839         for (tmode = transform_modes; tmode->idname; tmode++) {
840                 WM_operatortype_append(tmode->opfunc);
841         }
842
843         WM_operatortype_append(TRANSFORM_OT_transform);
844
845         WM_operatortype_append(TRANSFORM_OT_select_orientation);
846         WM_operatortype_append(TRANSFORM_OT_create_orientation);
847         WM_operatortype_append(TRANSFORM_OT_delete_orientation);
848
849         WM_operatortype_append(TRANSFORM_OT_snap_type);
850 }
851
852 void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spaceid)
853 {
854         wmKeyMapItem *kmi;
855         wmKeyMap *modalmap;
856         
857         /* transform.c, only adds modal map once, checks if it's there */
858         modalmap = transform_modal_keymap(keyconf);
859
860         /* assign map to operators only the first time */
861         if (modalmap) {
862                 TransformModeItem *tmode;
863
864                 for (tmode = transform_modes; tmode->idname; tmode++) {
865                         WM_modalkeymap_assign(modalmap, tmode->idname);
866                 }
867                 WM_modalkeymap_assign(modalmap, "TRANSFORM_OT_transform");
868         }
869         
870         switch (spaceid) {
871                 case SPACE_VIEW3D:
872                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
873
874                         WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
875
876                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
877
878                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
879
880                         WM_keymap_add_item(keymap, OP_WARP, WKEY, KM_PRESS, KM_SHIFT, 0);
881
882                         WM_keymap_add_item(keymap, OP_TOSPHERE, SKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
883
884                         WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
885
886                         WM_keymap_add_item(keymap, "TRANSFORM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
887
888                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
889                         RNA_boolean_set(kmi->ptr, "use", TRUE);
890
891                         WM_keymap_add_item(keymap, OP_MIRROR, MKEY, KM_PRESS, KM_CTRL, 0);
892
893                         kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
894                         RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap");
895
896                         WM_keymap_add_item(keymap, "TRANSFORM_OT_snap_type", TABKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
897
898                         kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, TKEY, KM_PRESS, KM_SHIFT, 0);
899                         RNA_boolean_set(kmi->ptr, "texture_space", TRUE);
900
901                         kmi = WM_keymap_add_item(keymap, OP_RESIZE, TKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
902                         RNA_boolean_set(kmi->ptr, "texture_space", TRUE);
903
904                         break;
905                 case SPACE_ACTION:
906                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0);
907                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_TRANSLATE);
908                         
909                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
910                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_TRANSLATE);
911                         
912                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
913                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
914                         
915                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0);
916                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SCALE);
917                         
918                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, KM_SHIFT, 0);
919                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SLIDE);
920                         break;
921                 case SPACE_IPO:
922                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
923                         
924                         WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
925                         
926                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
927                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
928                         
929                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
930                         
931                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
932                         break;
933                 case SPACE_NLA:
934                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0);
935                         RNA_enum_set(kmi->ptr, "mode", TFM_TRANSLATION);
936                         
937                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
938                         RNA_enum_set(kmi->ptr, "mode", TFM_TRANSLATION);
939                         
940                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
941                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
942                         
943                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0);
944                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SCALE);
945                         break;
946                 case SPACE_NODE:
947                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
948
949                         kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_A, KM_ANY, 0, 0);
950                         RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
951                         kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
952
953                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
954
955                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
956
957                         /* detach and translate */
958                         WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", DKEY, KM_PRESS, KM_ALT, 0);
959
960                         /* XXX release_confirm is set in the macro operator definition */
961                         WM_keymap_add_item(keymap, "NODE_OT_move_detach_links_release", EVT_TWEAK_A, KM_ANY, KM_ALT, 0);
962                         WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", EVT_TWEAK_S, KM_ANY, KM_ALT, 0);
963                         break;
964                 case SPACE_SEQ:
965                         WM_keymap_add_item(keymap, OP_SEQ_SLIDE, GKEY, KM_PRESS, 0, 0);
966
967                         WM_keymap_add_item(keymap, OP_SEQ_SLIDE, EVT_TWEAK_S, KM_ANY, 0, 0);
968
969                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
970                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
971                         break;
972                 case SPACE_IMAGE:
973                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
974
975                         WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
976
977                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
978
979                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
980
981                         WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
982
983                         WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
984
985                         kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
986                         RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap");
987                         break;
988                 case SPACE_CLIP:
989                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
990                         WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
991                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
992                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
993                         break;
994                 default:
995                         break;
996         }
997 }
998