60c0ebbc7b302e128456c9f7fb767d6c725c1364
[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 #include "mesh_intern.h"
55
56 /* uses context to figure out transform for primitive */
57 /* returns standard diameter */
58 static float new_primitive_matrix(bContext *C, float *loc, float *rot, float primmat[][4])
59 {
60         Object *obedit = CTX_data_edit_object(C);
61         View3D *v3d = CTX_wm_view3d(C);
62         float mat[3][3], rmat[3][3], cmat[3][3], imat[3][3];
63         
64         unit_m4(primmat);
65
66         eul_to_mat3(rmat, rot);
67         invert_m3(rmat);
68         
69         /* inverse transform for initial rotation and object */
70         copy_m3_m4(mat, obedit->obmat);
71         mul_m3_m3m3(cmat, rmat, mat);
72         invert_m3_m3(imat, cmat);
73         copy_m4_m3(primmat, imat);
74
75         /* center */
76         copy_v3_v3(primmat[3], loc);
77         sub_v3_v3(primmat[3], obedit->obmat[3]);
78         invert_m3_m3(imat, mat);
79         mul_m3_v3(imat, primmat[3]);
80
81         return v3d ? v3d->grid : 1.0f;
82 }
83
84 /* ********* add primitive operators ************* */
85
86 static void make_prim_init(bContext *C, const char *idname,
87                            float *dia, float mat[][4],
88                            int *state, float *loc, float *rot, unsigned int layer)
89 {
90         Object *obedit = CTX_data_edit_object(C);
91
92         *state = 0;
93         if (obedit == NULL || obedit->type != OB_MESH) {
94                 obedit = ED_object_add_type(C, OB_MESH, loc, rot, FALSE, layer);
95                 
96                 rename_id((ID *)obedit, idname);
97                 rename_id((ID *)obedit->data, idname);
98
99                 /* create editmode */
100                 ED_object_enter_editmode(C, EM_DO_UNDO | EM_IGNORE_LAYER); /* rare cases the active layer is messed up */
101                 *state = 1;
102         }
103
104         *dia = new_primitive_matrix(C, loc, rot, mat);
105 }
106
107 static void make_prim_finish(bContext *C, int *state, int enter_editmode)
108 {
109         Object *obedit = CTX_data_edit_object(C);
110         BMEditMesh *em = BMEdit_FromObject(obedit);
111
112         /* Primitive has all verts selected, use vert select flush
113          * to push this up to edges & faces. */
114         EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
115
116         EDBM_update_generic(C, em, TRUE);
117
118         /* userdef */
119         if (*state && !enter_editmode) {
120                 ED_object_exit_editmode(C, EM_FREEDATA); /* adding EM_DO_UNDO messes up operator redo */
121         }
122         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
123 }
124
125 static int add_primitive_plane_exec(bContext *C, wmOperator *op)
126 {
127         Object *obedit;
128         Mesh *me;
129         BMEditMesh *em;
130         float loc[3], rot[3], mat[4][4], dia;
131         int enter_editmode;
132         int state;
133         unsigned int layer;
134         
135         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
136         make_prim_init(C, "Plane", &dia, mat, &state, loc, rot, layer);
137
138         obedit = CTX_data_edit_object(C);
139         me = obedit->data;
140         em = me->edit_btmesh;
141
142         if (!EDBM_op_call_and_selectf(em, op, "vertout",
143                                       "create_grid xsegments=%i ysegments=%i size=%f mat=%m4", 1, 1, dia, mat))
144         {
145                 return OPERATOR_CANCELLED;
146         }
147
148         make_prim_finish(C, &state, enter_editmode);
149
150         return OPERATOR_FINISHED;
151 }
152
153 void MESH_OT_primitive_plane_add(wmOperatorType *ot)
154 {
155         /* identifiers */
156         ot->name = "Add Plane";
157         ot->description = "Construct a filled planar mesh with 4 vertices";
158         ot->idname = "MESH_OT_primitive_plane_add";
159         
160         /* api callbacks */
161         ot->invoke = ED_object_add_generic_invoke;
162         ot->exec = add_primitive_plane_exec;
163         ot->poll = ED_operator_scene_editable;
164         
165         /* flags */
166         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
167
168         ED_object_add_generic_props(ot, TRUE);
169 }
170
171 static int add_primitive_cube_exec(bContext *C, wmOperator *op)
172 {
173         Object *obedit;
174         Mesh *me;
175         BMEditMesh *em;
176         float loc[3], rot[3], mat[4][4], dia;
177         int enter_editmode;
178         int state;
179         unsigned int layer;
180         
181         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
182         make_prim_init(C, "Cube", &dia, mat, &state, loc, rot, layer);
183
184         obedit = CTX_data_edit_object(C);
185         me = obedit->data;
186         em = me->edit_btmesh;
187
188         if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_cube mat=%m4 size=%f", mat, dia * 2.0f)) {
189                 return OPERATOR_CANCELLED;
190         }
191         
192         /* BMESH_TODO make plane side this: M_SQRT2 - plane (diameter of 1.41 makes it unit size) */
193         make_prim_finish(C, &state, enter_editmode);
194
195         return OPERATOR_FINISHED;
196 }
197
198 void MESH_OT_primitive_cube_add(wmOperatorType *ot)
199 {
200         /* identifiers */
201         ot->name = "Add Cube";
202         ot->description = "Construct a cube mesh";
203         ot->idname = "MESH_OT_primitive_cube_add";
204         
205         /* api callbacks */
206         ot->invoke = ED_object_add_generic_invoke;
207         ot->exec = add_primitive_cube_exec;
208         ot->poll = ED_operator_scene_editable;
209         
210         /* flags */
211         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
212
213         ED_object_add_generic_props(ot, TRUE);
214 }
215
216 static const EnumPropertyItem fill_type_items[] = {
217         {0, "NOTHING", 0, "Nothing", "Don't fill at all"},
218         {1, "NGON", 0, "Ngon", "Use ngons"},
219         {2, "TRIFAN", 0, "Triangle Fan", "Use triangle fans"},
220         {0, NULL, 0, NULL, NULL}};
221
222 static int add_primitive_circle_exec(bContext *C, wmOperator *op)
223 {
224         Object *obedit;
225         Mesh *me;
226         BMEditMesh *em;
227         float loc[3], rot[3], mat[4][4], dia;
228         int enter_editmode;
229         int state, cap_end, cap_tri;
230         unsigned int layer;
231         
232         cap_end = RNA_enum_get(op->ptr, "fill_type");
233         cap_tri = (cap_end == 2);
234         
235         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
236         make_prim_init(C, "Circle", &dia, mat, &state, loc, rot, layer);
237
238         obedit = CTX_data_edit_object(C);
239         me = obedit->data;
240         em = me->edit_btmesh;
241
242         if (!EDBM_op_call_and_selectf(em, op, "vertout",
243                                       "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b mat=%m4",
244                                       RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"),
245                                       cap_end, cap_tri, mat))
246         {
247                 return OPERATOR_CANCELLED;
248         }
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_op_call_and_selectf(
302                 em, op, "vertout",
303                 "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4",
304                 RNA_int_get(op->ptr, "vertices"),
305                 RNA_float_get(op->ptr, "radius"),
306                 RNA_float_get(op->ptr, "radius"),
307                 cap_end, cap_tri,
308                 RNA_float_get(op->ptr, "depth"), mat))
309         {
310                 return OPERATOR_CANCELLED;
311         }
312         
313         make_prim_finish(C, &state, enter_editmode);
314         
315         return OPERATOR_FINISHED;
316 }
317
318 void MESH_OT_primitive_cylinder_add(wmOperatorType *ot)
319 {
320         PropertyRNA *prop;
321
322         /* identifiers */
323         ot->name = "Add Cylinder";
324         ot->description = "Construct a cylinder mesh";
325         ot->idname = "MESH_OT_primitive_cylinder_add";
326         
327         /* api callbacks */
328         ot->invoke = ED_object_add_generic_invoke;
329         ot->exec = add_primitive_cylinder_exec;
330         ot->poll = ED_operator_scene_editable;
331         
332         /* flags */
333         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
334         
335         /* props */
336         RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500);
337         prop = RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00);
338         RNA_def_property_subtype(prop, PROP_DISTANCE);
339         prop = RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00);
340         RNA_def_property_subtype(prop, PROP_DISTANCE);
341         RNA_def_enum(ot->srna, "end_fill_type", fill_type_items, 1, "Cap Fill Type", "");
342
343         ED_object_add_generic_props(ot, TRUE);
344 }
345
346 static int add_primitive_cone_exec(bContext *C, wmOperator *op)
347 {
348         Object *obedit;
349         Mesh *me;
350         BMEditMesh *em;
351         float loc[3], rot[3], mat[4][4], dia;
352         int enter_editmode;
353         int state, cap_end, cap_tri;
354         unsigned int layer;
355         
356         cap_end = RNA_enum_get(op->ptr, "end_fill_type");
357         cap_tri = (cap_end == 2);
358         
359         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
360         make_prim_init(C, "Cone", &dia, mat, &state, loc, rot, layer);
361
362         obedit = CTX_data_edit_object(C);
363         me = obedit->data;
364         em = me->edit_btmesh;
365
366         if (!EDBM_op_call_and_selectf(
367                 em, op, "vertout",
368                 "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4",
369                 RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"),
370                 RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat))
371         {
372                 return OPERATOR_CANCELLED;
373         }
374         
375         make_prim_finish(C, &state, enter_editmode);
376
377         return OPERATOR_FINISHED;
378 }
379
380 void MESH_OT_primitive_cone_add(wmOperatorType *ot)
381 {
382         PropertyRNA *prop;
383
384         /* identifiers */
385         ot->name = "Add Cone";
386         ot->description = "Construct a conic mesh";
387         ot->idname = "MESH_OT_primitive_cone_add";
388         
389         /* api callbacks */
390         ot->invoke = ED_object_add_generic_invoke;
391         ot->exec = add_primitive_cone_exec;
392         ot->poll = ED_operator_scene_editable;
393         
394         /* flags */
395         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
396         
397         /* props */
398         RNA_def_int(ot->srna, "vertices", 32, 3, INT_MAX, "Vertices", "", 3, 500);
399         prop = RNA_def_float(ot->srna, "radius1", 1.0f, 0.0, FLT_MAX, "Radius 1", "", 0.001, 100.00);
400         RNA_def_property_subtype(prop, PROP_DISTANCE);
401         prop = RNA_def_float(ot->srna, "radius2", 0.0f, 0.0, FLT_MAX, "Radius 2", "", 0.001, 100.00);
402         RNA_def_property_subtype(prop, PROP_DISTANCE);
403         prop = RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00);
404         RNA_def_property_subtype(prop, PROP_DISTANCE);
405         RNA_def_enum(ot->srna, "end_fill_type", fill_type_items, 1, "Base Fill Type", "");
406
407         ED_object_add_generic_props(ot, TRUE);
408 }
409
410 static int add_primitive_grid_exec(bContext *C, wmOperator *op)
411 {
412         Object *obedit;
413         Mesh *me;
414         BMEditMesh *em;
415         float loc[3], rot[3], mat[4][4], dia;
416         int enter_editmode;
417         int state;
418         unsigned int layer;
419         
420         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
421         make_prim_init(C, "Grid", &dia, mat, &state, loc, rot, layer);
422
423         obedit = CTX_data_edit_object(C);
424         me = obedit->data;
425         em = me->edit_btmesh;
426
427         if (!EDBM_op_call_and_selectf(em, op, "vertout",
428                                       "create_grid xsegments=%i ysegments=%i size=%f mat=%m4",
429                                       RNA_int_get(op->ptr, "x_subdivisions"),
430                                       RNA_int_get(op->ptr, "y_subdivisions"),
431                                       RNA_float_get(op->ptr, "size") * dia, mat))
432         {
433                 return OPERATOR_CANCELLED;
434         }
435         
436         make_prim_finish(C, &state, enter_editmode);
437         return OPERATOR_FINISHED;
438 }
439
440 void MESH_OT_primitive_grid_add(wmOperatorType *ot)
441 {
442         PropertyRNA *prop;
443
444         /* identifiers */
445         ot->name = "Add Grid";
446         ot->description = "Construct a grid mesh";
447         ot->idname = "MESH_OT_primitive_grid_add";
448         
449         /* api callbacks */
450         ot->invoke = ED_object_add_generic_invoke;
451         ot->exec = add_primitive_grid_exec;
452         ot->poll = ED_operator_scene_editable;
453         
454         /* flags */
455         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
456         
457         /* props */
458         RNA_def_int(ot->srna, "x_subdivisions", 10, 3, INT_MAX, "X Subdivisions", "", 3, 1000);
459         RNA_def_int(ot->srna, "y_subdivisions", 10, 3, INT_MAX, "Y Subdivisions", "", 3, 1000);
460         prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, FLT_MAX);
461         RNA_def_property_subtype(prop, PROP_DISTANCE);
462
463         ED_object_add_generic_props(ot, TRUE);
464 }
465
466 static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
467 {
468         Object *obedit;
469         Mesh *me;
470         BMEditMesh *em;
471         float loc[3], rot[3], mat[4][4], dia;
472         int enter_editmode;
473         int state, view_aligned;
474         unsigned int layer;
475         
476         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, &view_aligned);
477         if (!view_aligned)
478                 rot[0] += (float)M_PI / 2.0f;
479         
480         make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer);
481
482         obedit = CTX_data_edit_object(C);
483         me = obedit->data;
484         em = me->edit_btmesh;
485
486         if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_monkey mat=%m4", mat)) {
487                 return OPERATOR_CANCELLED;
488         }
489         
490         make_prim_finish(C, &state, enter_editmode);
491         return OPERATOR_FINISHED;
492 }
493
494 void MESH_OT_primitive_monkey_add(wmOperatorType *ot)
495 {
496         /* identifiers */
497         ot->name = "Add Monkey";
498         ot->description = "Construct a Suzanne mesh";
499         ot->idname = "MESH_OT_primitive_monkey_add";
500         
501         /* api callbacks */
502         ot->invoke = ED_object_add_generic_invoke;
503         ot->exec = add_primitive_monkey_exec;
504         ot->poll = ED_operator_scene_editable;
505         
506         /* flags */
507         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
508
509         ED_object_add_generic_props(ot, TRUE);
510 }
511
512 static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
513 {
514         Object *obedit;
515         Mesh *me;
516         BMEditMesh *em;
517         float loc[3], rot[3], mat[4][4], dia;
518         int enter_editmode;
519         int state;
520         unsigned int layer;
521         
522         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
523         make_prim_init(C, "Sphere", &dia, mat, &state, loc, rot, layer);
524
525         obedit = CTX_data_edit_object(C);
526         me = obedit->data;
527         em = me->edit_btmesh;
528
529         if (!EDBM_op_call_and_selectf(em, op, "vertout",
530                                       "create_uvsphere segments=%i revolutions=%i diameter=%f mat=%m4",
531                                       RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"),
532                                       RNA_float_get(op->ptr, "size"), mat))
533         {
534                 return OPERATOR_CANCELLED;
535         }
536         
537         make_prim_finish(C, &state, enter_editmode);
538
539         return OPERATOR_FINISHED;       
540 }
541
542 void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot)
543 {
544         PropertyRNA *prop;
545
546         /* identifiers */
547         ot->name = "Add UV Sphere";
548         ot->description = "Construct a UV sphere mesh";
549         ot->idname = "MESH_OT_primitive_uv_sphere_add";
550         
551         /* api callbacks */
552         ot->invoke = ED_object_add_generic_invoke;
553         ot->exec = add_primitive_uvsphere_exec;
554         ot->poll = ED_operator_scene_editable;
555         
556         /* flags */
557         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
558         
559         /* props */
560         RNA_def_int(ot->srna, "segments", 32, 3, INT_MAX, "Segments", "", 3, 500);
561         RNA_def_int(ot->srna, "ring_count", 16, 3, INT_MAX, "Rings", "", 3, 500);
562         prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, 100.00);
563         RNA_def_property_subtype(prop, PROP_DISTANCE);
564
565         ED_object_add_generic_props(ot, TRUE);
566 }
567
568 static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
569 {
570         Object *obedit;
571         Mesh *me;
572         BMEditMesh *em;
573         float loc[3], rot[3], mat[4][4], dia;
574         int enter_editmode;
575         int state;
576         unsigned int layer;
577         
578         ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
579         make_prim_init(C, "Icosphere", &dia, mat, &state, loc, rot, layer);
580
581         obedit = CTX_data_edit_object(C);
582         me = obedit->data;
583         em = me->edit_btmesh;
584
585         if (!EDBM_op_call_and_selectf(
586                 em, op, "vertout",
587                 "create_icosphere subdivisions=%i diameter=%f mat=%m4",
588                 RNA_int_get(op->ptr, "subdivisions"),
589                 RNA_float_get(op->ptr, "size"), mat))
590         {
591                 return OPERATOR_CANCELLED;
592         }
593         
594         make_prim_finish(C, &state, enter_editmode);
595
596         return OPERATOR_FINISHED;       
597 }
598
599 void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot)
600 {
601         PropertyRNA *prop;
602
603         /* identifiers */
604         ot->name = "Add Ico Sphere";
605         ot->description = "Construct an Icosphere mesh";
606         ot->idname = "MESH_OT_primitive_ico_sphere_add";
607         
608         /* api callbacks */
609         ot->invoke = ED_object_add_generic_invoke;
610         ot->exec = add_primitive_icosphere_exec;
611         ot->poll = ED_operator_scene_editable;
612         
613         /* flags */
614         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
615         
616         /* props */
617         RNA_def_int(ot->srna, "subdivisions", 2, 1, INT_MAX, "Subdivisions", "", 1, 8);
618         prop = RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00);
619         RNA_def_property_subtype(prop, PROP_DISTANCE);
620
621         ED_object_add_generic_props(ot, TRUE);
622 }