sync some changes with trunk and rename bmeshutils.c
[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                 return OPERATOR_CANCELLED;
150
151         make_prim_finish(C, &state, enter_editmode);
152
153         return OPERATOR_FINISHED;       
154 }
155
156 void MESH_OT_primitive_plane_add(wmOperatorType *ot)
157 {
158         /* identifiers */
159         ot->name= "Add Plane";
160         ot->description= "Construct a filled planar mesh with 4 vertices";
161         ot->idname= "MESH_OT_primitive_plane_add";
162         
163         /* api callbacks */
164         ot->invoke= ED_object_add_generic_invoke;
165         ot->exec= add_primitive_plane_exec;
166         ot->poll= ED_operator_scene_editable;
167         
168         /* flags */
169         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
170
171         ED_object_add_generic_props(ot, TRUE);
172 }
173
174 static int add_primitive_cube_exec(bContext *C, wmOperator *op)
175 {
176         Object *obedit;
177         Mesh *me;
178         BMEditMesh *em;
179         float loc[3], rot[3], mat[4][4], dia;
180         int enter_editmode;
181         int state;
182         unsigned int layer;
183         
184         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
185         make_prim_init(C, "Cube", &dia, mat, &state, loc, rot, layer);
186
187         obedit= CTX_data_edit_object(C);
188         me = obedit->data;
189         em = me->edit_btmesh;
190
191         if (!EDBM_CallAndSelectOpf(em, op, "vertout", "create_cube mat=%m4 size=%f", mat, 2.0f)) 
192                 return OPERATOR_CANCELLED;
193         
194         /* BMESH_TODO make plane side this: M_SQRT2 - plane (diameter of 1.41 makes it unit size) */
195         make_prim_finish(C, &state, enter_editmode);
196
197         return OPERATOR_FINISHED;
198 }
199
200 void MESH_OT_primitive_cube_add(wmOperatorType *ot)
201 {
202         /* identifiers */
203         ot->name= "Add Cube";
204         ot->description= "Construct a cube mesh";
205         ot->idname= "MESH_OT_primitive_cube_add";
206         
207         /* api callbacks */
208         ot->invoke= ED_object_add_generic_invoke;
209         ot->exec= add_primitive_cube_exec;
210         ot->poll= ED_operator_scene_editable;
211         
212         /* flags */
213         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
214
215         ED_object_add_generic_props(ot, TRUE);
216 }
217
218 static const EnumPropertyItem fill_type_items[]= {
219         {0, "NOTHING", 0, "Nothing", "Don't fill at all"},
220         {1, "NGON", 0, "Ngon", "Use ngons"},
221         {2, "TRIFAN", 0, "Triangle Fan", "Use triangle fans"},
222         {0, NULL, 0, NULL, NULL}};
223
224 static int add_primitive_circle_exec(bContext *C, wmOperator *op)
225 {
226         Object *obedit;
227         Mesh *me;
228         BMEditMesh *em;
229         float loc[3], rot[3], mat[4][4], dia;
230         int enter_editmode;
231         int state, cap_end, cap_tri;
232         unsigned int layer;
233         
234         cap_end = RNA_enum_get(op->ptr, "fill_type");
235         cap_tri = cap_end==2;
236         
237         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
238         make_prim_init(C, "Circle", &dia, mat, &state, loc, rot, layer);
239
240         obedit = CTX_data_edit_object(C);
241         me = obedit->data;
242         em = me->edit_btmesh;
243
244         if (!EDBM_CallAndSelectOpf(em, op, "vertout", 
245                         "create_circle segments=%i diameter=%f cap_ends=%i cap_tris=%i mat=%m4", 
246                         RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), 
247                         cap_end, cap_tri, mat))
248                 return OPERATOR_CANCELLED;
249         
250         make_prim_finish(C, &state, enter_editmode);
251         
252         return OPERATOR_FINISHED;
253 }
254
255 void MESH_OT_primitive_circle_add(wmOperatorType *ot)
256 {
257         PropertyRNA *prop;
258
259         /* identifiers */
260         ot->name= "Add Circle";
261         ot->description= "Construct a circle mesh";
262         ot->idname= "MESH_OT_primitive_circle_add";
263         
264         /* api callbacks */
265         ot->invoke= ED_object_add_generic_invoke;
266         ot->exec= add_primitive_circle_exec;
267         ot->poll= ED_operator_scene_editable;
268         
269         /* flags */
270         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
271         
272         /* props */
273         RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500);
274         prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00);
275         RNA_def_property_subtype(prop, PROP_DISTANCE);
276         RNA_def_enum(ot->srna, "fill_type", fill_type_items, 0, "Fill Type", "");
277
278         ED_object_add_generic_props(ot, TRUE);
279 }
280
281 static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
282 {
283         Object *obedit;
284         Mesh *me;
285         BMEditMesh *em;
286         float loc[3], rot[3], mat[4][4], dia;
287         int enter_editmode;
288         int state, cap_end, cap_tri;
289         unsigned int layer;
290         
291         cap_end = RNA_enum_get(op->ptr, "end_fill_type");
292         cap_tri = cap_end==2;
293         
294         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
295         make_prim_init(C, "Cylinder", &dia, mat, &state, loc, rot, layer);
296
297         obedit = CTX_data_edit_object(C);
298         me = obedit->data;
299         em = me->edit_btmesh;
300
301         if (!EDBM_CallAndSelectOpf(em, op, "vertout", 
302                         "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%i cap_tris=%i depth=%f mat=%m4", 
303                         RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), 
304                         RNA_float_get(op->ptr, "radius"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat))
305                 return OPERATOR_CANCELLED;
306         
307         make_prim_finish(C, &state, enter_editmode);
308         
309         return OPERATOR_FINISHED;
310 }
311
312 void MESH_OT_primitive_cylinder_add(wmOperatorType *ot)
313 {
314         PropertyRNA *prop;
315
316         /* identifiers */
317         ot->name= "Add Cylinder";
318         ot->description= "Construct a cylinder mesh";
319         ot->idname= "MESH_OT_primitive_cylinder_add";
320         
321         /* api callbacks */
322         ot->invoke= ED_object_add_generic_invoke;
323         ot->exec= add_primitive_cylinder_exec;
324         ot->poll= ED_operator_scene_editable;
325         
326         /* flags */
327         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
328         
329         /* props */
330         RNA_def_int(ot->srna, "vertices", 32, 2, INT_MAX, "Vertices", "", 2, 500);
331         prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00);
332         RNA_def_property_subtype(prop, PROP_DISTANCE);
333         prop = RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00);
334         RNA_def_property_subtype(prop, PROP_DISTANCE);
335         RNA_def_enum(ot->srna, "end_fill_type", fill_type_items, 1, "Cap Fill Type", "");
336
337         ED_object_add_generic_props(ot, TRUE);
338 }
339
340 static int add_primitive_cone_exec(bContext *C, wmOperator *op)
341 {
342         Object *obedit;
343         Mesh *me;
344         BMEditMesh *em;
345         float loc[3], rot[3], mat[4][4], dia;
346         int enter_editmode;
347         int state, cap_end, cap_tri;
348         unsigned int layer;
349         
350         cap_end = RNA_enum_get(op->ptr, "end_fill_type");
351         cap_tri = cap_end==2;
352         
353         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
354         make_prim_init(C, "Cone", &dia, mat, &state, loc, rot, layer);
355
356         obedit = CTX_data_edit_object(C);
357         me = obedit->data;
358         em = me->edit_btmesh;
359
360         if (!EDBM_CallAndSelectOpf(em, op, "vertout", 
361                         "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%i cap_tris=%i depth=%f mat=%m4", 
362                         RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"), 
363                         RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat))
364                 return OPERATOR_CANCELLED;
365         
366         make_prim_finish(C, &state, enter_editmode);
367
368         return OPERATOR_FINISHED;       
369 }
370
371 void MESH_OT_primitive_cone_add(wmOperatorType *ot)
372 {
373         PropertyRNA *prop;
374
375         /* identifiers */
376         ot->name= "Add Cone";
377         ot->description= "Construct a conic mesh (ends filled)";
378         ot->idname= "MESH_OT_primitive_cone_add";
379         
380         /* api callbacks */
381         ot->invoke= ED_object_add_generic_invoke;
382         ot->exec= add_primitive_cone_exec;
383         ot->poll= ED_operator_scene_editable;
384         
385         /* flags */
386         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
387         
388         /* props */
389         RNA_def_int(ot->srna, "vertices", 32, 2, INT_MAX, "Vertices", "", 2, 500);
390         prop = RNA_def_float(ot->srna, "radius1", 1.0f, 0.0, FLT_MAX, "Radius 1", "", 0.001, 100.00);
391         RNA_def_property_subtype(prop, PROP_DISTANCE);
392         prop = RNA_def_float(ot->srna, "radius2", 0.0f, 0.0, FLT_MAX, "Radius 2", "", 0.001, 100.00);
393         RNA_def_property_subtype(prop, PROP_DISTANCE);
394         prop = RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00);
395         RNA_def_property_subtype(prop, PROP_DISTANCE);
396         RNA_def_enum(ot->srna, "end_fill_type", fill_type_items, 1, "Base Fill Type", "");
397
398         ED_object_add_generic_props(ot, TRUE);
399 }
400
401 static int add_primitive_grid_exec(bContext *C, wmOperator *op)
402 {
403         Object *obedit;
404         Mesh *me;
405         BMEditMesh *em;
406         float loc[3], rot[3], mat[4][4], dia = 1.0f;
407         int enter_editmode;
408         int state;
409         unsigned int layer;
410         
411         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
412         make_prim_init(C, "Grid", &dia, mat, &state, loc, rot, layer);
413
414         obedit = CTX_data_edit_object(C);
415         me = obedit->data;
416         em = me->edit_btmesh;
417
418         if (!EDBM_CallAndSelectOpf(em, op, "vertout", 
419                         "create_grid xsegments=%i ysegments=%i size=%f mat=%m4",
420                         RNA_int_get(op->ptr, "x_subdivisions"), 
421                         RNA_int_get(op->ptr, "y_subdivisions"), 
422                         RNA_float_get(op->ptr, "size") * dia, mat))
423         {
424                 return OPERATOR_CANCELLED;
425         }
426         
427         make_prim_finish(C, &state, enter_editmode);
428         return OPERATOR_FINISHED;
429 }
430
431 void MESH_OT_primitive_grid_add(wmOperatorType *ot)
432 {
433         PropertyRNA *prop;
434
435         /* identifiers */
436         ot->name= "Add Grid";
437         ot->description= "Construct a grid mesh";
438         ot->idname= "MESH_OT_primitive_grid_add";
439         
440         /* api callbacks */
441         ot->invoke= ED_object_add_generic_invoke;
442         ot->exec= add_primitive_grid_exec;
443         ot->poll= ED_operator_scene_editable;
444         
445         /* flags */
446         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
447         
448         /* props */
449         RNA_def_int(ot->srna, "x_subdivisions", 10, 3, INT_MAX, "X Subdivisions", "", 3, 1000);
450         RNA_def_int(ot->srna, "y_subdivisions", 10, 3, INT_MAX, "Y Subdivisions", "", 3, 1000);
451         prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, FLT_MAX);
452         RNA_def_property_subtype(prop, PROP_DISTANCE);
453
454         ED_object_add_generic_props(ot, TRUE);
455 }
456
457 static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
458 {
459         Object *obedit;
460         Mesh *me;
461         BMEditMesh *em;
462         float loc[3], rot[3], mat[4][4], dia;
463         int enter_editmode;
464         int state, view_aligned;
465         unsigned int layer;
466         
467         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, &view_aligned);
468         if (!view_aligned)
469                 rot[0] += M_PI/2.0f;
470         
471         make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer);
472
473         obedit = CTX_data_edit_object(C);
474         me = obedit->data;
475         em = me->edit_btmesh;
476
477         if (!EDBM_CallAndSelectOpf(em, op, "vertout", "create_monkey mat=%m4", mat)) {
478                 return OPERATOR_CANCELLED;
479         }
480         
481         make_prim_finish(C, &state, enter_editmode);
482         return OPERATOR_FINISHED;
483 }
484
485 void MESH_OT_primitive_monkey_add(wmOperatorType *ot)
486 {
487         /* identifiers */
488         ot->name= "Add Monkey";
489         ot->description= "Construct a Suzanne mesh";
490         ot->idname= "MESH_OT_primitive_monkey_add";
491         
492         /* api callbacks */
493         ot->invoke= ED_object_add_generic_invoke;
494         ot->exec= add_primitive_monkey_exec;
495         ot->poll= ED_operator_scene_editable;
496         
497         /* flags */
498         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
499
500         ED_object_add_generic_props(ot, TRUE);
501 }
502
503 static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
504 {
505         Object *obedit;
506         Mesh *me;
507         BMEditMesh *em;
508         float loc[3], rot[3], mat[4][4], dia;
509         int enter_editmode;
510         int state;
511         unsigned int layer;
512         
513         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
514         make_prim_init(C, "Sphere", &dia, mat, &state, loc, rot, layer);
515
516         obedit = CTX_data_edit_object(C);
517         me = obedit->data;
518         em = me->edit_btmesh;
519
520         if (!EDBM_CallAndSelectOpf(em, op, "vertout", 
521                         "create_uvsphere segments=%i revolutions=%i diameter=%f mat=%m4", 
522                         RNA_int_get(op->ptr, "ring_count"), RNA_int_get(op->ptr, "segments"),
523                         RNA_float_get(op->ptr,"size"), mat)) 
524                 return OPERATOR_CANCELLED;
525         
526         make_prim_finish(C, &state, enter_editmode);
527
528         return OPERATOR_FINISHED;       
529 }
530
531 void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot)
532 {
533         PropertyRNA *prop;
534
535         /* identifiers */
536         ot->name= "Add UV Sphere";
537         ot->description= "Construct a UV sphere mesh";
538         ot->idname= "MESH_OT_primitive_uv_sphere_add";
539         
540         /* api callbacks */
541         ot->invoke= ED_object_add_generic_invoke;
542         ot->exec= add_primitive_uvsphere_exec;
543         ot->poll= ED_operator_scene_editable;
544         
545         /* flags */
546         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
547         
548         /* props */
549         RNA_def_int(ot->srna, "segments", 32, 3, INT_MAX, "Segments", "", 3, 500);
550         RNA_def_int(ot->srna, "ring_count", 16, 3, INT_MAX, "Rings", "", 3, 500);
551         prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, 100.00);
552         RNA_def_property_subtype(prop, PROP_DISTANCE);
553
554         ED_object_add_generic_props(ot, TRUE);
555 }
556
557 static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
558 {
559         Object *obedit;
560         Mesh *me;
561         BMEditMesh *em;
562         float loc[3], rot[3], mat[4][4], dia;
563         int enter_editmode;
564         int state;
565         unsigned int layer;
566         
567         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
568         make_prim_init(C, "Icosphere", &dia, mat, &state, loc, rot, layer);
569
570         obedit = CTX_data_edit_object(C);
571         me = obedit->data;
572         em = me->edit_btmesh;
573
574         if (!EDBM_CallAndSelectOpf(em, op, "vertout", 
575                         "create_icosphere subdivisions=%i diameter=%f mat=%m4", 
576                         RNA_int_get(op->ptr, "subdivisions"),
577                         RNA_float_get(op->ptr, "size"), mat)) {
578                 return OPERATOR_CANCELLED;
579         }
580         
581         make_prim_finish(C, &state, enter_editmode);
582
583         return OPERATOR_FINISHED;       
584 }
585
586 void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot)
587 {
588         PropertyRNA *prop;
589
590         /* identifiers */
591         ot->name= "Add Ico Sphere";
592         ot->description= "Construct an Icosphere mesh";
593         ot->idname= "MESH_OT_primitive_ico_sphere_add";
594         
595         /* api callbacks */
596         ot->invoke= ED_object_add_generic_invoke;
597         ot->exec= add_primitive_icosphere_exec;
598         ot->poll= ED_operator_scene_editable;
599         
600         /* flags */
601         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
602         
603         /* props */
604         RNA_def_int(ot->srna, "subdivisions", 2, 1, INT_MAX, "Subdivisions", "", 1, 8);
605         prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00);
606         RNA_def_property_subtype(prop, PROP_DISTANCE);
607
608         ED_object_add_generic_props(ot, TRUE);
609 }