added boolean type for bmesh operators, will make python wrapping clearer and also...
[blender.git] / source / blender / editors / mesh / editmesh_add.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2004 by Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Joseph Eagar
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/mesh/editmesh_add.c
29  *  \ingroup edmesh
30  */
31
32 #include "DNA_mesh_types.h"
33 #include "DNA_object_types.h"
34 #include "DNA_scene_types.h"
35
36 #include "RNA_define.h"
37 #include "RNA_access.h"
38
39 #include "BLI_math.h"
40
41 #include "BKE_context.h"
42 #include "BKE_depsgraph.h"
43 #include "BKE_library.h"
44 #include "BKE_tessmesh.h"
45
46
47 #include "WM_api.h"
48 #include "WM_types.h"
49
50 #include "ED_mesh.h"
51 #include "ED_screen.h"
52 #include "ED_object.h"
53
54 /* uses context to figure out transform for primitive */
55 /* returns standard diameter */
56 static float new_primitive_matrix(bContext *C, float *loc, float *rot, float primmat[][4])
57 {
58         Object *obedit= CTX_data_edit_object(C);
59         View3D *v3d =CTX_wm_view3d(C);
60         float mat[3][3], rmat[3][3], cmat[3][3], imat[3][3];
61         
62         unit_m4(primmat);
63
64         eul_to_mat3(rmat, rot);
65         invert_m3(rmat);
66         
67         /* inverse transform for initial rotation and object */
68         copy_m3_m4(mat, obedit->obmat);
69         mul_m3_m3m3(cmat, rmat, mat);
70         invert_m3_m3(imat, cmat);
71         copy_m4_m3(primmat, imat);
72
73         /* center */
74         copy_v3_v3(primmat[3], loc);
75         sub_v3_v3(primmat[3], obedit->obmat[3]);
76         invert_m3_m3(imat, mat);
77         mul_m3_v3(imat, primmat[3]);
78
79         return v3d ? v3d->grid : 1.0f;
80 }
81
82 /* ********* add primitive operators ************* */
83
84 static void make_prim_init(bContext *C, const char *idname,
85                            float *dia, float mat[][4],
86                            int *state, float *loc, float *rot, unsigned int layer)
87 {
88         Object *obedit= CTX_data_edit_object(C);
89
90         *state = 0;
91         if(obedit==NULL || obedit->type!=OB_MESH) {
92                 obedit= ED_object_add_type(C, OB_MESH, loc, rot, FALSE, layer);
93                 
94                 rename_id((ID *)obedit, idname);
95                 rename_id((ID *)obedit->data, idname);
96
97                 /* create editmode */
98                 ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); /* rare cases the active layer is messed up */
99                 *state = 1;
100         }
101         else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
102
103         *dia *= new_primitive_matrix(C, loc, rot, mat);
104 }
105
106 static void make_prim_finish(bContext *C, int *state, int enter_editmode)
107 {
108         Object *obedit;
109         Mesh *me;
110         BMEditMesh *em;
111
112         obedit = CTX_data_edit_object(C);
113         me = obedit->data;
114         em = me->edit_btmesh;
115
116         /* Primitive has all verts selected, use vert select flush
117          * to push this up to edges & faces. */
118         EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
119
120         DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
121         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
122
123         /* userdef */
124         if (*state && !enter_editmode) {
125                 ED_object_exit_editmode(C, EM_FREEDATA); /* adding EM_DO_UNDO messes up operator redo */
126         }
127         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit);
128 }
129
130 static int add_primitive_plane_exec(bContext *C, wmOperator *op)
131 {
132         Object *obedit;
133         Mesh *me;
134         BMEditMesh *em;
135         float loc[3], rot[3], mat[4][4], dia = 1.0f;
136         int enter_editmode;
137         int state;
138         unsigned int layer;
139         
140         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
141         make_prim_init(C, "Plane", &dia, mat, &state, loc, rot, layer);
142
143         obedit = CTX_data_edit_object(C);
144         me = obedit->data;
145         em = me->edit_btmesh;
146
147         if (!EDBM_CallAndSelectOpf(em, op, "vertout", 
148                                    "create_grid xsegments=%i ysegments=%i size=%f mat=%m4", 1, 1, dia, mat))
149         {
150                 return OPERATOR_CANCELLED;
151         }
152
153         make_prim_finish(C, &state, enter_editmode);
154
155         return OPERATOR_FINISHED;       
156 }
157
158 void MESH_OT_primitive_plane_add(wmOperatorType *ot)
159 {
160         /* identifiers */
161         ot->name= "Add Plane";
162         ot->description= "Construct a filled planar mesh with 4 vertices";
163         ot->idname= "MESH_OT_primitive_plane_add";
164         
165         /* api callbacks */
166         ot->invoke= ED_object_add_generic_invoke;
167         ot->exec= add_primitive_plane_exec;
168         ot->poll= ED_operator_scene_editable;
169         
170         /* flags */
171         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
172
173         ED_object_add_generic_props(ot, TRUE);
174 }
175
176 static int add_primitive_cube_exec(bContext *C, wmOperator *op)
177 {
178         Object *obedit;
179         Mesh *me;
180         BMEditMesh *em;
181         float loc[3], rot[3], mat[4][4], dia;
182         int enter_editmode;
183         int state;
184         unsigned int layer;
185         
186         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
187         make_prim_init(C, "Cube", &dia, mat, &state, loc, rot, layer);
188
189         obedit= CTX_data_edit_object(C);
190         me = obedit->data;
191         em = me->edit_btmesh;
192
193         if (!EDBM_CallAndSelectOpf(em, op, "vertout", "create_cube mat=%m4 size=%f", mat, 2.0f)) {
194                 return OPERATOR_CANCELLED;
195         }
196         
197         /* BMESH_TODO make plane side this: M_SQRT2 - plane (diameter of 1.41 makes it unit size) */
198         make_prim_finish(C, &state, enter_editmode);
199
200         return OPERATOR_FINISHED;
201 }
202
203 void MESH_OT_primitive_cube_add(wmOperatorType *ot)
204 {
205         /* identifiers */
206         ot->name= "Add Cube";
207         ot->description= "Construct a cube mesh";
208         ot->idname= "MESH_OT_primitive_cube_add";
209         
210         /* api callbacks */
211         ot->invoke= ED_object_add_generic_invoke;
212         ot->exec= add_primitive_cube_exec;
213         ot->poll= ED_operator_scene_editable;
214         
215         /* flags */
216         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
217
218         ED_object_add_generic_props(ot, TRUE);
219 }
220
221 static const EnumPropertyItem fill_type_items[]= {
222         {0, "NOTHING", 0, "Nothing", "Don't fill at all"},
223         {1, "NGON", 0, "Ngon", "Use ngons"},
224         {2, "TRIFAN", 0, "Triangle Fan", "Use triangle fans"},
225         {0, NULL, 0, NULL, NULL}};
226
227 static int add_primitive_circle_exec(bContext *C, wmOperator *op)
228 {
229         Object *obedit;
230         Mesh *me;
231         BMEditMesh *em;
232         float loc[3], rot[3], mat[4][4], dia;
233         int enter_editmode;
234         int state, cap_end, cap_tri;
235         unsigned int layer;
236         
237         cap_end = RNA_enum_get(op->ptr, "fill_type");
238         cap_tri = cap_end==2;
239         
240         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
241         make_prim_init(C, "Circle", &dia, mat, &state, loc, rot, layer);
242
243         obedit = CTX_data_edit_object(C);
244         me = obedit->data;
245         em = me->edit_btmesh;
246
247         if (!EDBM_CallAndSelectOpf(em, op, "vertout",
248                                    "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b mat=%m4",
249                                    RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"),
250                                    cap_end, cap_tri, mat))
251         {
252                 return OPERATOR_CANCELLED;
253         }
254         
255         make_prim_finish(C, &state, enter_editmode);
256         
257         return OPERATOR_FINISHED;
258 }
259
260 void MESH_OT_primitive_circle_add(wmOperatorType *ot)
261 {
262         PropertyRNA *prop;
263
264         /* identifiers */
265         ot->name= "Add Circle";
266         ot->description= "Construct a circle mesh";
267         ot->idname= "MESH_OT_primitive_circle_add";
268         
269         /* api callbacks */
270         ot->invoke= ED_object_add_generic_invoke;
271         ot->exec= add_primitive_circle_exec;
272         ot->poll= ED_operator_scene_editable;
273         
274         /* flags */
275         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
276         
277         /* props */
278         RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500);
279         prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00);
280         RNA_def_property_subtype(prop, PROP_DISTANCE);
281         RNA_def_enum(ot->srna, "fill_type", fill_type_items, 0, "Fill Type", "");
282
283         ED_object_add_generic_props(ot, TRUE);
284 }
285
286 static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
287 {
288         Object *obedit;
289         Mesh *me;
290         BMEditMesh *em;
291         float loc[3], rot[3], mat[4][4], dia;
292         int enter_editmode;
293         int state, cap_end, cap_tri;
294         unsigned int layer;
295         
296         cap_end = RNA_enum_get(op->ptr, "end_fill_type");
297         cap_tri = cap_end==2;
298         
299         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
300         make_prim_init(C, "Cylinder", &dia, mat, &state, loc, rot, layer);
301
302         obedit = CTX_data_edit_object(C);
303         me = obedit->data;
304         em = me->edit_btmesh;
305
306         if (!EDBM_CallAndSelectOpf(
307                 em, op, "vertout",
308                 "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4",
309                 RNA_int_get(op->ptr, "vertices"),
310                 RNA_float_get(op->ptr, "radius"),
311                 RNA_float_get(op->ptr, "radius"),
312                 cap_end, cap_tri,
313                 RNA_float_get(op->ptr, "depth"), mat))
314         {
315                 return OPERATOR_CANCELLED;
316         }
317         
318         make_prim_finish(C, &state, enter_editmode);
319         
320         return OPERATOR_FINISHED;
321 }
322
323 void MESH_OT_primitive_cylinder_add(wmOperatorType *ot)
324 {
325         PropertyRNA *prop;
326
327         /* identifiers */
328         ot->name= "Add Cylinder";
329         ot->description= "Construct a cylinder mesh";
330         ot->idname= "MESH_OT_primitive_cylinder_add";
331         
332         /* api callbacks */
333         ot->invoke= ED_object_add_generic_invoke;
334         ot->exec= add_primitive_cylinder_exec;
335         ot->poll= ED_operator_scene_editable;
336         
337         /* flags */
338         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
339         
340         /* props */
341         RNA_def_int(ot->srna, "vertices", 32, 2, INT_MAX, "Vertices", "", 2, 500);
342         prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00);
343         RNA_def_property_subtype(prop, PROP_DISTANCE);
344         prop = RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00);
345         RNA_def_property_subtype(prop, PROP_DISTANCE);
346         RNA_def_enum(ot->srna, "end_fill_type", fill_type_items, 1, "Cap Fill Type", "");
347
348         ED_object_add_generic_props(ot, TRUE);
349 }
350
351 static int add_primitive_cone_exec(bContext *C, wmOperator *op)
352 {
353         Object *obedit;
354         Mesh *me;
355         BMEditMesh *em;
356         float loc[3], rot[3], mat[4][4], dia;
357         int enter_editmode;
358         int state, cap_end, cap_tri;
359         unsigned int layer;
360         
361         cap_end = RNA_enum_get(op->ptr, "end_fill_type");
362         cap_tri = cap_end==2;
363         
364         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
365         make_prim_init(C, "Cone", &dia, mat, &state, loc, rot, layer);
366
367         obedit = CTX_data_edit_object(C);
368         me = obedit->data;
369         em = me->edit_btmesh;
370
371         if (!EDBM_CallAndSelectOpf(
372                 em, op, "vertout",
373                 "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4",
374                 RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"),
375                 RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat))
376         {
377                 return OPERATOR_CANCELLED;
378         }
379         
380         make_prim_finish(C, &state, enter_editmode);
381
382         return OPERATOR_FINISHED;       
383 }
384
385 void MESH_OT_primitive_cone_add(wmOperatorType *ot)
386 {
387         PropertyRNA *prop;
388
389         /* identifiers */
390         ot->name= "Add Cone";
391         ot->description= "Construct a conic mesh (ends filled)";
392         ot->idname= "MESH_OT_primitive_cone_add";
393         
394         /* api callbacks */
395         ot->invoke= ED_object_add_generic_invoke;
396         ot->exec= add_primitive_cone_exec;
397         ot->poll= ED_operator_scene_editable;
398         
399         /* flags */
400         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
401         
402         /* props */
403         RNA_def_int(ot->srna, "vertices", 32, 2, INT_MAX, "Vertices", "", 2, 500);
404         prop = RNA_def_float(ot->srna, "radius1", 1.0f, 0.0, FLT_MAX, "Radius 1", "", 0.001, 100.00);
405         RNA_def_property_subtype(prop, PROP_DISTANCE);
406         prop = RNA_def_float(ot->srna, "radius2", 0.0f, 0.0, FLT_MAX, "Radius 2", "", 0.001, 100.00);
407         RNA_def_property_subtype(prop, PROP_DISTANCE);
408         prop = RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00);
409         RNA_def_property_subtype(prop, PROP_DISTANCE);
410         RNA_def_enum(ot->srna, "end_fill_type", fill_type_items, 1, "Base Fill Type", "");
411
412         ED_object_add_generic_props(ot, TRUE);
413 }
414
415 static int add_primitive_grid_exec(bContext *C, wmOperator *op)
416 {
417         Object *obedit;
418         Mesh *me;
419         BMEditMesh *em;
420         float loc[3], rot[3], mat[4][4], dia = 1.0f;
421         int enter_editmode;
422         int state;
423         unsigned int layer;
424         
425         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
426         make_prim_init(C, "Grid", &dia, mat, &state, loc, rot, layer);
427
428         obedit = CTX_data_edit_object(C);
429         me = obedit->data;
430         em = me->edit_btmesh;
431
432         if (!EDBM_CallAndSelectOpf(em, op, "vertout",
433                                    "create_grid xsegments=%i ysegments=%i size=%f mat=%m4",
434                                    RNA_int_get(op->ptr, "x_subdivisions"),
435                                    RNA_int_get(op->ptr, "y_subdivisions"),
436                                    RNA_float_get(op->ptr, "size") * dia, mat))
437         {
438                 return OPERATOR_CANCELLED;
439         }
440         
441         make_prim_finish(C, &state, enter_editmode);
442         return OPERATOR_FINISHED;
443 }
444
445 void MESH_OT_primitive_grid_add(wmOperatorType *ot)
446 {
447         PropertyRNA *prop;
448
449         /* identifiers */
450         ot->name= "Add Grid";
451         ot->description= "Construct a grid mesh";
452         ot->idname= "MESH_OT_primitive_grid_add";
453         
454         /* api callbacks */
455         ot->invoke= ED_object_add_generic_invoke;
456         ot->exec= add_primitive_grid_exec;
457         ot->poll= ED_operator_scene_editable;
458         
459         /* flags */
460         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
461         
462         /* props */
463         RNA_def_int(ot->srna, "x_subdivisions", 10, 3, INT_MAX, "X Subdivisions", "", 3, 1000);
464         RNA_def_int(ot->srna, "y_subdivisions", 10, 3, INT_MAX, "Y Subdivisions", "", 3, 1000);
465         prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, FLT_MAX);
466         RNA_def_property_subtype(prop, PROP_DISTANCE);
467
468         ED_object_add_generic_props(ot, TRUE);
469 }
470
471 static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
472 {
473         Object *obedit;
474         Mesh *me;
475         BMEditMesh *em;
476         float loc[3], rot[3], mat[4][4], dia;
477         int enter_editmode;
478         int state, view_aligned;
479         unsigned int layer;
480         
481         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, &view_aligned);
482         if (!view_aligned)
483                 rot[0] += M_PI/2.0f;
484         
485         make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer);
486
487         obedit = CTX_data_edit_object(C);
488         me = obedit->data;
489         em = me->edit_btmesh;
490
491         if (!EDBM_CallAndSelectOpf(em, op, "vertout", "create_monkey mat=%m4", mat)) {
492                 return OPERATOR_CANCELLED;
493         }
494         
495         make_prim_finish(C, &state, enter_editmode);
496         return OPERATOR_FINISHED;
497 }
498
499 void MESH_OT_primitive_monkey_add(wmOperatorType *ot)
500 {
501         /* identifiers */
502         ot->name= "Add Monkey";
503         ot->description= "Construct a Suzanne mesh";
504         ot->idname= "MESH_OT_primitive_monkey_add";
505         
506         /* api callbacks */
507         ot->invoke= ED_object_add_generic_invoke;
508         ot->exec= add_primitive_monkey_exec;
509         ot->poll= ED_operator_scene_editable;
510         
511         /* flags */
512         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
513
514         ED_object_add_generic_props(ot, TRUE);
515 }
516
517 static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
518 {
519         Object *obedit;
520         Mesh *me;
521         BMEditMesh *em;
522         float loc[3], rot[3], mat[4][4], dia;
523         int enter_editmode;
524         int state;
525         unsigned int layer;
526         
527         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
528         make_prim_init(C, "Sphere", &dia, mat, &state, loc, rot, layer);
529
530         obedit = CTX_data_edit_object(C);
531         me = obedit->data;
532         em = me->edit_btmesh;
533
534         if (!EDBM_CallAndSelectOpf(em, op, "vertout",
535                                    "create_uvsphere segments=%i revolutions=%i diameter=%f mat=%m4",
536                                    RNA_int_get(op->ptr, "ring_count"), RNA_int_get(op->ptr, "segments"),
537                                    RNA_float_get(op->ptr,"size"), mat))
538         {
539                 return OPERATOR_CANCELLED;
540         }
541         
542         make_prim_finish(C, &state, enter_editmode);
543
544         return OPERATOR_FINISHED;       
545 }
546
547 void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot)
548 {
549         PropertyRNA *prop;
550
551         /* identifiers */
552         ot->name= "Add UV Sphere";
553         ot->description= "Construct a UV sphere mesh";
554         ot->idname= "MESH_OT_primitive_uv_sphere_add";
555         
556         /* api callbacks */
557         ot->invoke= ED_object_add_generic_invoke;
558         ot->exec= add_primitive_uvsphere_exec;
559         ot->poll= ED_operator_scene_editable;
560         
561         /* flags */
562         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
563         
564         /* props */
565         RNA_def_int(ot->srna, "segments", 32, 3, INT_MAX, "Segments", "", 3, 500);
566         RNA_def_int(ot->srna, "ring_count", 16, 3, INT_MAX, "Rings", "", 3, 500);
567         prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, 100.00);
568         RNA_def_property_subtype(prop, PROP_DISTANCE);
569
570         ED_object_add_generic_props(ot, TRUE);
571 }
572
573 static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
574 {
575         Object *obedit;
576         Mesh *me;
577         BMEditMesh *em;
578         float loc[3], rot[3], mat[4][4], dia;
579         int enter_editmode;
580         int state;
581         unsigned int layer;
582         
583         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
584         make_prim_init(C, "Icosphere", &dia, mat, &state, loc, rot, layer);
585
586         obedit = CTX_data_edit_object(C);
587         me = obedit->data;
588         em = me->edit_btmesh;
589
590         if (!EDBM_CallAndSelectOpf(
591                 em, op, "vertout",
592                 "create_icosphere subdivisions=%i diameter=%f mat=%m4",
593                 RNA_int_get(op->ptr, "subdivisions"),
594                 RNA_float_get(op->ptr, "size"), mat))
595         {
596                 return OPERATOR_CANCELLED;
597         }
598         
599         make_prim_finish(C, &state, enter_editmode);
600
601         return OPERATOR_FINISHED;       
602 }
603
604 void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot)
605 {
606         PropertyRNA *prop;
607
608         /* identifiers */
609         ot->name= "Add Ico Sphere";
610         ot->description= "Construct an Icosphere mesh";
611         ot->idname= "MESH_OT_primitive_ico_sphere_add";
612         
613         /* api callbacks */
614         ot->invoke= ED_object_add_generic_invoke;
615         ot->exec= add_primitive_icosphere_exec;
616         ot->poll= ED_operator_scene_editable;
617         
618         /* flags */
619         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
620         
621         /* props */
622         RNA_def_int(ot->srna, "subdivisions", 2, 1, INT_MAX, "Subdivisions", "", 1, 8);
623         prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00);
624         RNA_def_property_subtype(prop, PROP_DISTANCE);
625
626         ED_object_add_generic_props(ot, TRUE);
627 }