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