94af243eb0eadd89581579d78c9f350f620fd52c
[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
29 #include "RNA_access.h"
30 #include "RNA_define.h"
31 #include "RNA_enum_types.h"
32
33 #include "BLI_math.h"
34
35 #include "BKE_context.h"
36 #include "BKE_global.h"
37
38 #include "WM_api.h"
39 #include "WM_types.h"
40
41 #include "UI_interface.h"
42
43 #include "ED_screen.h"
44
45 #include "transform.h"
46
47 typedef struct TransformModeItem
48 {
49         char *idname;
50         int             mode;
51         void (*opfunc)(wmOperatorType*);
52 } TransformModeItem;
53
54 static float VecOne[3] = {1, 1, 1};
55
56 char OP_TRANSLATION[] = "TRANSFORM_OT_translate";
57 char OP_ROTATION[] = "TRANSFORM_OT_rotate";
58 char OP_TOSPHERE[] = "TRANSFORM_OT_tosphere";
59 char OP_RESIZE[] = "TRANSFORM_OT_resize";
60 char OP_SHEAR[] = "TRANSFORM_OT_shear";
61 char OP_WARP[] = "TRANSFORM_OT_warp";
62 char OP_SHRINK_FATTEN[] = "TRANSFORM_OT_shrink_fatten";
63 char OP_PUSH_PULL[] = "TRANSFORM_OT_push_pull";
64 char OP_TILT[] = "TRANSFORM_OT_tilt";
65 char OP_TRACKBALL[] = "TRANSFORM_OT_trackball";
66 char OP_MIRROR[] = "TRANSFORM_OT_mirror";
67 char OP_EDGE_SLIDE[] = "TRANSFORM_OT_edge_slide";
68 char OP_EDGE_CREASE[] = "TRANSFORM_OT_edge_crease";
69 char OP_SEQ_SLIDE[] = "TRANSFORM_OT_seq_slide";
70
71 void TRANSFORM_OT_translate(struct wmOperatorType *ot);
72 void TRANSFORM_OT_rotate(struct wmOperatorType *ot);
73 void TRANSFORM_OT_tosphere(struct wmOperatorType *ot);
74 void TRANSFORM_OT_resize(struct wmOperatorType *ot);
75 void TRANSFORM_OT_shear(struct wmOperatorType *ot);
76 void TRANSFORM_OT_warp(struct wmOperatorType *ot);
77 void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot);
78 void TRANSFORM_OT_push_pull(struct wmOperatorType *ot);
79 void TRANSFORM_OT_tilt(struct wmOperatorType *ot);
80 void TRANSFORM_OT_trackball(struct wmOperatorType *ot);
81 void TRANSFORM_OT_mirror(struct wmOperatorType *ot);
82 void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot);
83 void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot);
84 void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot);
85
86 TransformModeItem transform_modes[] =
87 {
88         {OP_TRANSLATION, TFM_TRANSLATION, TRANSFORM_OT_translate},
89         {OP_ROTATION, TFM_ROTATION, TRANSFORM_OT_rotate},
90         {OP_TOSPHERE, TFM_TOSPHERE, TRANSFORM_OT_tosphere},
91         {OP_RESIZE, TFM_RESIZE, TRANSFORM_OT_resize},
92         {OP_SHEAR, TFM_SHEAR, TRANSFORM_OT_shear},
93         {OP_WARP, TFM_WARP, TRANSFORM_OT_warp},
94         {OP_SHRINK_FATTEN, TFM_SHRINKFATTEN, TRANSFORM_OT_shrink_fatten},
95         {OP_PUSH_PULL, TFM_PUSHPULL, TRANSFORM_OT_push_pull},
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 *UNUSED(op), wmEvent *UNUSED(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_view3d_active;
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 *UNUSED(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 *UNUSED(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 *UNUSED(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 data2");
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                 if(retval) {
306                         op->customdata = t;
307                 }
308                 else {
309                         MEM_freeN(t);
310                 }
311         }
312
313         return retval; /* return 0 on error */
314 }
315
316 static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
317 {
318         int exit_code;
319
320         TransInfo *t = op->customdata;
321
322         exit_code = transformEvent(t, event);
323
324         transformApply(C, t);
325
326         exit_code |= transformEnd(C, t);
327
328         if ((exit_code & OPERATOR_RUNNING_MODAL) == 0)
329         {
330                 transformops_exit(C, op);
331                 exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
332         }
333
334         return exit_code;
335 }
336
337 static int transform_cancel(bContext *C, wmOperator *op)
338 {
339         TransInfo *t = op->customdata;
340
341         t->state = TRANS_CANCEL;
342         transformEnd(C, t);
343         transformops_exit(C, op);
344
345         return OPERATOR_CANCELLED;
346 }
347
348 static int transform_exec(bContext *C, wmOperator *op)
349 {
350         TransInfo *t;
351
352         if (!transformops_data(C, op, NULL))
353         {
354                 G.moving = 0;
355                 return OPERATOR_CANCELLED;
356         }
357
358         t = op->customdata;
359
360         t->options |= CTX_AUTOCONFIRM;
361
362         transformApply(C, t);
363
364         transformEnd(C, t);
365
366         transformops_exit(C, op);
367
368         return OPERATOR_FINISHED;
369 }
370
371 static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
372 {
373         if (!transformops_data(C, op, event))
374         {
375                 G.moving = 0;
376                 return OPERATOR_CANCELLED;
377         }
378
379         if(RNA_property_is_set(op->ptr, "value")) {
380                 return transform_exec(C, op);
381         }
382         else {
383                 /* add temp handler */
384                 WM_event_add_modal_handler(C, op);
385
386                 op->flag |= OP_GRAB_POINTER; // XXX maybe we want this with the manipulator only?
387                 return OPERATOR_RUNNING_MODAL;
388         }
389 }
390
391 void Transform_Properties(struct wmOperatorType *ot, int flags)
392 {
393         PropertyRNA *prop;
394
395         if (flags & P_AXIS)
396         {
397                 prop= RNA_def_property(ot->srna, "axis", PROP_FLOAT, PROP_DIRECTION);
398                 RNA_def_property_array(prop, 3);
399                 /* Make this not hidden when there's a nice axis selection widget */
400                 RNA_def_property_flag(prop, PROP_HIDDEN);
401                 RNA_def_property_ui_text(prop, "Axis", "The axis around which the transformation occurs");
402
403         }
404
405         if (flags & P_CONSTRAINT)
406         {
407                 prop= RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
408                 prop= RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE);
409                 RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation");
410                 RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
411
412                 
413         }
414
415         if (flags & P_MIRROR)
416         {
417                 RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
418         }
419
420
421         if (flags & P_PROPORTIONAL)
422         {
423                 RNA_def_enum(ot->srna, "proportional", proportional_editing_items, 0, "Proportional Editing", "");
424                 RNA_def_enum(ot->srna, "proportional_edit_falloff", proportional_falloff_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
425                 RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100);
426         }
427
428         if (flags & P_SNAP)
429         {
430                 prop= RNA_def_boolean(ot->srna, "snap", 0, "Use Snapping Options", "");
431                 RNA_def_property_flag(prop, PROP_HIDDEN);
432
433                 if (flags & P_GEO_SNAP) {
434                         prop= RNA_def_enum(ot->srna, "snap_target", snap_target_items, 0, "Target", "");
435                         RNA_def_property_flag(prop, PROP_HIDDEN);
436                         prop= RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
437                         RNA_def_property_flag(prop, PROP_HIDDEN);
438                         
439                         if (flags & P_ALIGN_SNAP) {
440                                 prop= RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", "");
441                                 RNA_def_property_flag(prop, PROP_HIDDEN);
442                                 prop= RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX);
443                                 RNA_def_property_flag(prop, PROP_HIDDEN);
444                         }
445                 }
446         }
447
448         // 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
449         prop = RNA_def_boolean(ot->srna, "release_confirm", 0, "Confirm on Release", "Always confirm operation when releasing button");
450         //RNA_def_property_flag(prop, PROP_HIDDEN);
451 }
452
453 void TRANSFORM_OT_translate(struct wmOperatorType *ot)
454 {
455         /* identifiers */
456         ot->name   = "Translate";
457         ot->description= "Translate selected items";
458         ot->idname = OP_TRANSLATION;
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_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
469
470         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_ALIGN_SNAP);
471 }
472
473 void TRANSFORM_OT_resize(struct wmOperatorType *ot)
474 {
475         /* identifiers */
476         ot->name   = "Resize";
477         ot->description= "Resize selected items"; 
478         ot->idname = OP_RESIZE;
479         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
480
481         /* api callbacks */
482         ot->invoke = transform_invoke;
483         ot->exec   = transform_exec;
484         ot->modal  = transform_modal;
485         ot->cancel  = transform_cancel;
486         ot->poll   = ED_operator_areaactive;
487
488         RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
489
490         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP);
491 }
492
493
494 void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
495 {
496         /* identifiers */
497         ot->name   = "Trackball";
498         ot->description= "Trackball style rotation of selected items";
499         ot->idname = OP_TRACKBALL;
500         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
501
502         /* api callbacks */
503         ot->invoke = transform_invoke;
504         ot->exec   = transform_exec;
505         ot->modal  = transform_modal;
506         ot->cancel  = transform_cancel;
507         ot->poll   = ED_operator_areaactive;
508
509         RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "angle", "", -FLT_MAX, FLT_MAX);
510
511         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
512 }
513
514 void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
515 {
516         /* identifiers */
517         ot->name   = "Rotate";
518         ot->description= "Rotate selected items";
519         ot->idname = OP_ROTATION;
520         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
521
522         /* api callbacks */
523         ot->invoke = transform_invoke;
524         ot->exec   = transform_exec;
525         ot->modal  = transform_modal;
526         ot->cancel  = transform_cancel;
527         ot->poll   = ED_operator_areaactive;
528
529         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
530
531         Transform_Properties(ot, P_AXIS|P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP);
532 }
533
534 void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
535 {
536         /* identifiers */
537         ot->name   = "Tilt";
538         /*optionals - 
539                 "Tilt selected vertices."
540                 "Specify an extra axis rotation for selected vertices of 3d curve." */
541         ot->description= "Tilt selected control vertices of 3d curve"; 
542         ot->idname = OP_TILT;
543         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
544
545         /* api callbacks */
546         ot->invoke = transform_invoke;
547         ot->exec   = transform_exec;
548         ot->modal  = transform_modal;
549         ot->cancel  = transform_cancel;
550         ot->poll   = ED_operator_editcurve;
551
552         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
553
554         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_SNAP);
555 }
556
557 void TRANSFORM_OT_warp(struct wmOperatorType *ot)
558 {
559         /* identifiers */
560         ot->name   = "Warp";
561         ot->description= "Warp selected items around the cursor";
562         ot->idname = OP_WARP;
563         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
564
565         /* api callbacks */
566         ot->invoke = transform_invoke;
567         ot->exec   = transform_exec;
568         ot->modal  = transform_modal;
569         ot->cancel  = transform_cancel;
570         ot->poll   = ED_operator_areaactive;
571
572         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", 0, 1);
573
574         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
575         // XXX Warp axis?
576 }
577
578 void TRANSFORM_OT_shear(struct wmOperatorType *ot)
579 {
580         /* identifiers */
581         ot->name   = "Shear";
582         ot->description= "Shear selected items along the horizontal screen axis";
583         ot->idname = OP_SHEAR;
584         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
585
586         /* api callbacks */
587         ot->invoke = transform_invoke;
588         ot->exec   = transform_exec;
589         ot->modal  = transform_modal;
590         ot->cancel  = transform_cancel;
591         ot->poll   = ED_operator_areaactive;
592
593         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
594
595         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
596         // XXX Shear axis?
597 }
598
599 void TRANSFORM_OT_push_pull(struct wmOperatorType *ot)
600 {
601         /* identifiers */
602         ot->name   = "Push/Pull";
603         ot->description= "Push/Pull selected items";
604         ot->idname = OP_PUSH_PULL;
605         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
606
607         /* api callbacks */
608         ot->invoke = transform_invoke;
609         ot->exec   = transform_exec;
610         ot->modal  = transform_modal;
611         ot->cancel  = transform_cancel;
612         ot->poll   = ED_operator_areaactive;
613
614         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Distance", "", -FLT_MAX, FLT_MAX);
615
616         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
617 }
618
619 void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot)
620 {
621         /* identifiers */
622         ot->name   = "Shrink/Fatten";
623         ot->description= "Shrink/fatten selected vertices along normals";
624         ot->idname = OP_SHRINK_FATTEN;
625         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
626
627         /* api callbacks */
628         ot->invoke = transform_invoke;
629         ot->exec   = transform_exec;
630         ot->modal  = transform_modal;
631         ot->cancel  = transform_cancel;
632         ot->poll   = ED_operator_editmesh;
633
634         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
635
636         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
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         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
658 }
659
660 void TRANSFORM_OT_mirror(struct wmOperatorType *ot)
661 {
662         /* identifiers */
663         ot->name   = "Mirror";
664         ot->description= "Mirror selected vertices around one or more axes";
665         ot->idname = OP_MIRROR;
666         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
667
668         /* api callbacks */
669         ot->invoke = transform_invoke;
670         ot->exec   = transform_exec;
671         ot->modal  = transform_modal;
672         ot->cancel  = transform_cancel;
673         ot->poll   = ED_operator_areaactive;
674
675         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL);
676 }
677
678 void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
679 {
680         /* identifiers */
681         ot->name   = "Edge Slide";
682         ot->description= "Slide an edge loop along a mesh"; 
683         ot->idname = OP_EDGE_SLIDE;
684         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
685
686         /* api callbacks */
687         ot->invoke = transform_invoke;
688         ot->exec   = transform_exec;
689         ot->modal  = transform_modal;
690         ot->cancel  = transform_cancel;
691         ot->poll   = ED_operator_editmesh;
692
693         RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
694
695         Transform_Properties(ot, P_MIRROR|P_SNAP);
696 }
697
698 void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
699 {
700         /* identifiers */
701         ot->name   = "Edge Crease";
702         ot->description= "Change the crease of edges";
703         ot->idname = OP_EDGE_CREASE;
704         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
705
706         /* api callbacks */
707         ot->invoke = transform_invoke;
708         ot->exec   = transform_exec;
709         ot->modal  = transform_modal;
710         ot->cancel  = transform_cancel;
711         ot->poll   = ED_operator_editmesh;
712
713         RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
714
715         Transform_Properties(ot, P_SNAP);
716 }
717
718 void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
719 {
720         /* identifiers */
721         ot->name   = "Sequence Slide";
722         ot->description= "Slide a sequence strip in time";
723         ot->idname = OP_SEQ_SLIDE;
724         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
725
726         /* api callbacks */
727         ot->invoke = transform_invoke;
728         ot->exec   = transform_exec;
729         ot->modal  = transform_modal;
730         ot->cancel  = transform_cancel;
731         ot->poll   = ED_operator_sequencer_active;
732
733         RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "angle", "", -FLT_MAX, FLT_MAX);
734
735         Transform_Properties(ot, P_SNAP);
736 }
737
738 void TRANSFORM_OT_transform(struct wmOperatorType *ot)
739 {
740         static EnumPropertyItem transform_mode_types[] = {
741                         {TFM_INIT, "INIT", 0, "Init", ""},
742                         {TFM_DUMMY, "DUMMY", 0, "Dummy", ""},
743                         {TFM_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
744                         {TFM_ROTATION, "ROTATION", 0, "Rotation", ""},
745                         {TFM_RESIZE, "RESIZE", 0, "Resize", ""},
746                         {TFM_TOSPHERE, "TOSPHERE", 0, "Tosphere", ""},
747                         {TFM_SHEAR, "SHEAR", 0, "Shear", ""},
748                         {TFM_WARP, "WARP", 0, "Warp", ""},
749                         {TFM_SHRINKFATTEN, "SHRINKFATTEN", 0, "Shrinkfatten", ""},
750                         {TFM_TILT, "TILT", 0, "Tilt", ""},
751                         {TFM_TRACKBALL, "TRACKBALL", 0, "Trackball", ""},
752                         {TFM_PUSHPULL, "PUSHPULL", 0, "Pushpull", ""},
753                         {TFM_CREASE, "CREASE", 0, "Crease", ""},
754                         {TFM_MIRROR, "MIRROR", 0, "Mirror", ""},
755                         {TFM_BONESIZE, "BONE_SIZE", 0, "Bonesize", ""},
756                         {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""},
757                         {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""},
758                         {TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""},
759                         {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""},
760                         {TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""},
761                         {TFM_TIME_SCALE, "TIME_SCALE", 0, "Time_Scale", ""},
762                         {TFM_TIME_EXTEND, "TIME_EXTEND", 0, "Time_Extend", ""},
763                         {TFM_BAKE_TIME, "BAKE_TIME", 0, "Bake_Time", ""},
764                         {TFM_BEVEL, "BEVEL", 0, "Bevel", ""},
765                         {TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""},
766                         {TFM_ALIGN, "ALIGN", 0, "Align", ""},
767                         {TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""},
768                         {TFM_SEQ_SLIDE, "SEQSLIDE", 0, "Sequence Slide", ""},
769                         {0, NULL, 0, NULL, NULL}
770         };
771
772         /* identifiers */
773         ot->name   = "Transform";
774         ot->description= "Transform selected items by mode type";
775         ot->idname = "TRANSFORM_OT_transform";
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_areaactive;
784
785         RNA_def_enum(ot->srna, "mode", transform_mode_types, 0, "Mode", "");
786
787         RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
788
789         Transform_Properties(ot, P_AXIS|P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_ALIGN_SNAP);
790 }
791
792 void transform_operatortypes(void)
793 {
794         TransformModeItem *tmode;
795
796         for (tmode = transform_modes; tmode->idname; tmode++)
797         {
798                 WM_operatortype_append(tmode->opfunc);
799         }
800
801         WM_operatortype_append(TRANSFORM_OT_transform);
802
803         WM_operatortype_append(TRANSFORM_OT_select_orientation);
804         WM_operatortype_append(TRANSFORM_OT_create_orientation);
805         WM_operatortype_append(TRANSFORM_OT_delete_orientation);
806
807         WM_operatortype_append(TRANSFORM_OT_snap_type);
808 }
809
810 void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spaceid)
811 {
812         wmKeyMapItem *km;
813         wmKeyMap *modalmap;
814         
815         /* transform.c, only adds modal map once, checks if it's there */
816         modalmap = transform_modal_keymap(keyconf);
817
818         /* assign map to operators only the first time */
819         if (modalmap) {
820                 TransformModeItem *tmode;
821
822                 for (tmode = transform_modes; tmode->idname; tmode++)
823                 {
824                         WM_modalkeymap_assign(modalmap, tmode->idname);
825                 }
826                 WM_modalkeymap_assign(modalmap, "TRANSFORM_OT_transform");
827         }
828         
829         switch(spaceid)
830         {
831                 case SPACE_VIEW3D:
832                         km = WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
833
834                         km= WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
835
836                         km = WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
837
838                         km = WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
839
840                         km = WM_keymap_add_item(keymap, OP_WARP, WKEY, KM_PRESS, KM_SHIFT, 0);
841
842                         km = WM_keymap_add_item(keymap, OP_TOSPHERE, SKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
843
844                         km = WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
845
846                         km = WM_keymap_add_item(keymap, "TRANSFORM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
847
848                         km = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
849                         RNA_boolean_set(km->ptr, "use", 1);
850
851                         km = WM_keymap_add_item(keymap, OP_MIRROR, MKEY, KM_PRESS, KM_CTRL, 0);
852
853                         km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
854                         RNA_string_set(km->ptr, "data_path", "tool_settings.use_snap");
855
856                         km = WM_keymap_add_item(keymap, "TRANSFORM_OT_snap_type", TABKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
857
858                         break;
859                 case SPACE_ACTION:
860                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0);
861                         RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
862                         
863                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
864                         RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
865                         
866                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
867                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
868                         
869                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0);
870                         RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE);
871                         
872                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, 0, 0);
873                         RNA_int_set(km->ptr, "mode", TFM_TIME_SLIDE);
874                         break;
875                 case SPACE_IPO:
876                         km= WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
877                         
878                         km= WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
879                         
880                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
881                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
882                         
883                         km = WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
884                         
885                         km = WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
886                         break;
887                 case SPACE_NLA:
888                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0);
889                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
890                         
891                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
892                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
893                         
894                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
895                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
896                         
897                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0);
898                         RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE);
899                         break;
900                 case SPACE_NODE:
901                         km= WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
902
903                         km= WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_A, KM_ANY, 0, 0);
904                         RNA_enum_set(km->ptr, "release_confirm", 1);
905                         km= WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
906                         RNA_enum_set(km->ptr, "release_confirm", 1);
907
908                         km = WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
909
910                         km = WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
911                         break;
912                 case SPACE_SEQ:
913                         km= WM_keymap_add_item(keymap, OP_SEQ_SLIDE, GKEY, KM_PRESS, 0, 0);
914
915                         km= WM_keymap_add_item(keymap, OP_SEQ_SLIDE, EVT_TWEAK_S, KM_ANY, 0, 0);
916
917                         km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
918                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
919                         break;
920                 case SPACE_IMAGE:
921                         km = WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
922
923                         km= WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
924
925                         km = WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
926
927                         km = WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
928
929                         km = WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
930
931                         km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
932                         RNA_string_set(km->ptr, "data_path", "tool_settings.use_snap");
933                         break;
934                 default:
935                         break;
936         }
937 }
938