diff options
author | Brendon Murphy <meta.androcto1@gmail.com> | 2015-06-22 08:28:17 +0300 |
---|---|---|
committer | Brendon Murphy <meta.androcto1@gmail.com> | 2015-06-22 08:28:17 +0300 |
commit | 1883ee23fb258e05c91b4fb2121d7150b6673cd9 (patch) | |
tree | 9ff6d4bd8068b989d0cb844f4bffba00f8498dd4 | |
parent | ffaddb3a6f59dc9a2177c27391c8fd8444af3257 (diff) |
update parent to mesh, update & fix crasher in mesh_round_cube, update init.
-rw-r--r-- | add_mesh_extra_objects/__init__.py | 2 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_empty_as_parent.py | 100 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_round_cube.py | 307 |
3 files changed, 212 insertions, 197 deletions
diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py index ce4c36da..0b14f3dc 100644 --- a/add_mesh_extra_objects/__init__.py +++ b/add_mesh_extra_objects/__init__.py @@ -200,7 +200,7 @@ class INFO_MT_mesh_pipe_joints_add(bpy.types.Menu): def menu_func(self, context): self.layout.separator() self.layout.menu("INFO_MT_mesh_vert_add", text="Single Vert", icon="LAYER_ACTIVE") - self.layout.menu("INFO_MT_mesh_round_cube_add", text="Round Cube", icon="WIRE") + self.layout.operator("mesh.primitive_round_cube_add", text="Round Cube", icon="MOD_SUBSURF") self.layout.menu("INFO_MT_mesh_math_add", text="Math Function", icon="PACKAGE") self.layout.menu("INFO_MT_mesh_pipe_joints_add", text="Pipe Joints", icon="SNAP_PEEL_OBJECT") self.layout.menu("INFO_MT_mesh_gears_add", text="Gears", icon="SCRIPTWIN") diff --git a/add_mesh_extra_objects/add_empty_as_parent.py b/add_mesh_extra_objects/add_empty_as_parent.py index 86280554..b7431b6d 100644 --- a/add_mesh_extra_objects/add_empty_as_parent.py +++ b/add_mesh_extra_objects/add_empty_as_parent.py @@ -1,57 +1,115 @@ # GPL # Original Author Liero # import bpy -from bpy.props import StringProperty, FloatProperty, BoolProperty, FloatVectorProperty +from bpy.props import StringProperty, BoolProperty, EnumProperty -def centro(objetos): - x = sum([obj.location[0] for obj in objetos])/len(objetos) - y = sum([obj.location[1] for obj in objetos])/len(objetos) - z = sum([obj.location[2] for obj in objetos])/len(objetos) +def centro(sel): + x = sum([obj.location[0] for obj in sel])/len(sel) + y = sum([obj.location[1] for obj in sel])/len(sel) + z = sum([obj.location[2] for obj in sel])/len(sel) return (x,y,z) + class P2E(bpy.types.Operator): bl_idname = 'object.parent_to_empty' - bl_label = 'Parent Selected to Empty' + bl_label = 'Parent to Empty' bl_description = 'Parent selected objects to a new Empty' bl_options = {'REGISTER', 'UNDO'} nombre = StringProperty(name='', default='OBJECTS', description='Give the empty / group a name') - grupo = bpy.props.BoolProperty(name='Create Group', default=False, description='Also link objects to a new group') - cursor = bpy.props.BoolProperty(name='Cursor Location', default=False, description='Add the empty at cursor / selection center') - renombrar = bpy.props.BoolProperty(name='Rename Objects', default=False, description='Rename child objects') + grupo = bpy.props.BoolProperty(name='Create Group', default=False, description='Also add objects to a group') + locat = bpy.props.EnumProperty(name='', items=[('CURSOR','Cursor','Cursor'),('ACTIVE','Active','Active'), + ('CENTER','Center','Selection Center')],description='Empty location', default='CENTER') + renom = bpy.props.BoolProperty(name='Add Prefix', default=False, description='Add prefix to objects name') @classmethod def poll(cls, context): - return (context.object and context.object.select) + objs = context.selected_objects + return (len(objs) > 0) def draw(self, context): layout = self.layout layout.prop(self,'nombre') column = layout.column(align=True) + column.prop(self,'locat') column.prop(self,'grupo') - column.prop(self,'cursor') - column.prop(self,'renombrar') + column.prop(self,'renom') def execute(self, context): - objs = bpy.context.selected_objects - bpy.ops.object.mode_set() - if self.cursor: - loc = context.scene.cursor_location + objs = context.selected_objects + act = context.object + sce = context.scene + try: bpy.ops.object.mode_set() + except: pass + if self.locat == 'CURSOR': + loc = sce.cursor_location + elif self.locat == 'ACTIVE': + loc = act.location else: - loc = centro(objs) + loc = centro(objs) + bpy.ops.object.add(type='EMPTY',location=loc) - bpy.context.object.name = self.nombre + context.object.name = self.nombre + context.object.show_name = True + context.object.show_x_ray = True + if self.grupo: bpy.ops.group.create(name=self.nombre) bpy.ops.group.objects_add_active() + for o in objs: o.select = True if not o.parent: - bpy.ops.object.parent_set(type='OBJECT') + bpy.ops.object.parent_set(type='OBJECT') if self.grupo: bpy.ops.group.objects_add_active() o.select = False for o in objs: - if self.renombrar: + if self.renom: o.name = self.nombre+'_'+o.name - return {'FINISHED'}
\ No newline at end of file + return {'FINISHED'} + + +class PreFix(bpy.types.Operator): + bl_idname = 'object.toggle_prefix' + bl_label = 'Toggle Sufix' + bl_description = 'Toggle parent name as sufix for c' + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + act = bpy.context.object + return (act and act.type == 'EMPTY') + + def execute(self, context): + act = bpy.context.object + objs = act.children + prefix = act.name+'_' + remove = False + for o in objs: + if o.name.startswith(prefix): + remove = True + break + + if remove == True: + for o in objs: + if o.name.startswith(prefix): + o.name = o.name.partition(prefix)[2] + else: + for o in objs: + o.name = prefix+o.name + + return {'FINISHED'} + + +class PanelP2E(bpy.types.Panel): + bl_label = 'Parent to Empty' + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + bl_category = 'Relations' + + def draw(self, context): + layout = self.layout + layout.operator('object.parent_to_empty') + layout.operator('object.toggle_prefix') + diff --git a/add_mesh_extra_objects/add_mesh_round_cube.py b/add_mesh_extra_objects/add_mesh_round_cube.py index 1c677216..169a7da7 100644 --- a/add_mesh_extra_objects/add_mesh_round_cube.py +++ b/add_mesh_extra_objects/add_mesh_round_cube.py @@ -1,4 +1,4 @@ -# GPL # 'author': 'Alain Ducharme (Phymec)' +# GPL # Author: Alain Ducharme (phymec) import bpy from bpy_extras import object_utils @@ -15,14 +15,15 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0. ,0. ,0.), div_type='COR radius = max(radius, 0.) if not radius: + # No sphere arcdiv = 1 + odd_axis_align = False if arcdiv <= 0: arcdiv = max(round(pi * radius * lindiv * 0.5), 1) arcdiv = max(round(arcdiv), 1) - if lindiv <= 0.: - if radius: - lindiv = 1. / (pi / (arcdiv * 2.) * radius) + if lindiv <= 0. and radius: + lindiv = 1. / (pi / (arcdiv * 2.) * radius) lindiv = max(lindiv, 0.) if not lindiv: subdiv = CORNERS @@ -72,9 +73,9 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0. ,0. ,0.), div_type='COR dvc = arcdiv * 4 * sum(fxyz) if subdiv == ALL: dvc += sum(p1 * p2 for p1, p2 in permutations(fxyz, 2)) - elif subdiv == EDGES: + elif subdiv == EDGES and axis_aligned: # (0, 0, 2, 4) * sum(dxyz) + (0, 0, 2, 6) - dvc += ec * ec // 2 * sum(dxyz) + ec * (ec - 1) if axis_aligned else 0 + dvc += ec * ec // 2 * sum(dxyz) + ec * (ec - 1) else: dvc = (arcdiv * 4) * ec + ec * (ec - 1) if axis_aligned else 0 vert_count = int(6 * arcdiv*arcdiv + (0 if odd_aligned else 2) + dvc) @@ -83,6 +84,7 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0. ,0. ,0.), div_type='COR return arcdiv, lindiv, vert_count if not radius and not max(size) > 0: + # Single vertex return [(0,0,0)], [] # uv lookup table @@ -92,11 +94,11 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0. ,0. ,0.), div_type='COR v2 = v*v uvlt.append((v, v2, radius * sqrt(18. - 6. * v2) / 6.)) v = vi + j * step_size # v += step_size # instead of accumulating errors - # clear precision errors / signs at axis + # clear fp errors / signs at axis if abs(v) < 1e-10: v = 0.0 - # Round cube sides built left to right bottom up + # Sides built left to right bottom up # xp yp zp xd yd zd sides = ((0, 2, 1, (-1, 1, 1)), # Y+ Front (1, 2, 0, (-1, -1, 1)), # X- Left @@ -105,9 +107,10 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0. ,0. ,0.), div_type='COR (0, 1, 2, (-1, 1, -1)), # Z- Bottom (0, 1, 2, (-1, -1, 1))) # Z+ Top - # side vertex index table + # side vertex index table (for sphere) svit = [[[] for i in range(steps)] for i in range(6)] - # Extend rows for extrusion + # Extend svit rows for extrusion + yer = zer = 0 if ey: yer = axis_aligned + (dxyz[1] if subdiv else 0) svit[4].extend([[] for i in range(yer)]) @@ -116,8 +119,7 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0. ,0. ,0.), div_type='COR zer = axis_aligned + (dxyz[2] if subdiv else 0) for side in range(4): svit[side].extend([[] for i in range(zer)]) - ryi = rzi = 0 # row vertex indices - # Extend rows for odd_aligned + # Extend svit rows for odd_aligned if odd_aligned: for side in range(4): svit[side].append([]) @@ -129,117 +131,115 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0. ,0. ,0.), div_type='COR verts = [] if arcdiv == 1 and not odd_aligned and subdiv == ALL: - # Special case: 3D Grid Cuboid + # Special case: Grid Cuboid for side, (xp, yp, zp, dir) in enumerate(sides): svitc = svit[side] rows = len(svitc) if rows < dxyz[yp] + 2: svitc.extend([[] for i in range(dxyz[yp] + 2 - rows)]) vert[zp] = (half_chord + exyz[zp]) * dir[zp] - print(dssxyz, half_chord, exyz, dir) for j in range(dxyz[yp] + 2): vert[yp] = (j * dssxyz[yp] - half_chord - exyz[yp]) * dir[yp] for i in range(dxyz[xp] + 2): vert[xp] = (i * dssxyz[xp] - half_chord - exyz[xp]) * dir[xp] if (side == 5) or ((i < dxyz[xp] + 1 and j < dxyz[yp] + 1) and (side < 4 or (i and j))): - print(side, vert) svitc[j].append(len(verts)) verts.append(tuple(vert)) else: - for j in range(steps): - v, v2, mv2 = uvlt[j] - tv2mh = 1./3. * v2 - 0.5 - hv2 = 0.5 * v2 - - if j == hemi: - # Jump over non-edge row vertex indices - if ey: - ryi += yer - if ez: - rzi += zer - - for i in range(steps): - u, u2, mu2 = uvlt[i] - x = u * mv2 - y = v * mu2 - z = radius * sqrt(u2 * tv2mh - hv2 + 1.) - - for side, (xp, yp, zp, dir) in enumerate(sides): - svitc = svit[side] - ri = rzi if side < 4 else ryi - - vert[xp] = x - vert[yp] = y - vert[zp] = z - exr = exyz[xp] - eyr = exyz[yp] - - if (side == 5) or (i < arcdiv and j < arcdiv and (side < 4 or (i and j or odd_aligned))): - vert[0] = (vert[0] + copysign(ex, vert[0])) * dir[0] - vert[1] = (vert[1] + copysign(ey, vert[1])) * dir[1] - vert[2] = (vert[2] + copysign(ez, vert[2])) * dir[2] - rv = tuple(vert) - - if exr and i == hemi: - rx = vert[xp] # save xp - vert[xp] = rxi = (-exr - half_chord) * dir[xp] - if axis_aligned: + for side, (xp, yp, zp, dir) in enumerate(sides): + svitc = svit[side] + exr = exyz[xp] + eyr = exyz[yp] + ri = 0 # row index + rij = zer if side < 4 else yer + + if side == 5: + span = range(steps) + elif side < 4 or odd_aligned: + span = range(arcdiv) + else: + span = range(1, arcdiv) + ri = 1 + + for j in span: # rows + v, v2, mv2 = uvlt[j] + tv2mh = 1./3. * v2 - 0.5 + hv2 = 0.5 * v2 + + if j == hemi and rij: + # Jump over non-edge row indices + ri += rij + + for i in span: # columns + u, u2, mu2 = uvlt[i] + vert[xp] = u * mv2 + vert[yp] = v * mu2 + vert[zp] = radius * sqrt(u2 * tv2mh - hv2 + 1.) + + vert[0] = (vert[0] + copysign(ex, vert[0])) * dir[0] + vert[1] = (vert[1] + copysign(ey, vert[1])) * dir[1] + vert[2] = (vert[2] + copysign(ez, vert[2])) * dir[2] + rv = tuple(vert) + + if exr and i == hemi: + rx = vert[xp] # save rotated x + vert[xp] = rxi = (-exr - half_chord) * dir[xp] + if axis_aligned: + svitc[ri].append(len(verts)) + verts.append(tuple(vert)) + if subdiv: + offsetx = dssxyz[xp] * dir[xp] + for k in range(dxyz[xp]): + vert[xp] += offsetx svitc[ri].append(len(verts)) verts.append(tuple(vert)) + if eyr and j == hemi and axis_aligned: + vert[xp] = rxi + vert[yp] = -eyr * dir[yp] + svitc[hemi].append(len(verts)) + verts.append(tuple(vert)) if subdiv: - offsetx = dssxyz[xp] * dir[xp] + offsety = dssxyz[yp] * dir[yp] + ry = vert[yp] + for k in range(dxyz[yp]): + vert[yp] += offsety + svitc[hemi + axis_aligned + k].append(len(verts)) + verts.append(tuple(vert)) + vert[yp] = ry for k in range(dxyz[xp]): vert[xp] += offsetx - svitc[ri].append(len(verts)) + svitc[hemi].append(len(verts)) verts.append(tuple(vert)) - if eyr and j == hemi and axis_aligned: - vert[xp] = rxi - vert[yp] = -eyr * dir[yp] - svitc[hemi].append(len(verts)) - verts.append(tuple(vert)) - if subdiv: - offsety = dssxyz[yp] * dir[yp] - ry = vert[yp] - for k in range(dxyz[yp]): - vert[yp] += offsety - svitc[hemi + axis_aligned + k].append(len(verts)) - verts.append(tuple(vert)) - vert[yp] = ry - for k in range(dxyz[xp]): + if subdiv & ALL: + for l in range(dxyz[yp]): + vert[yp] += offsety + svitc[hemi + axis_aligned + l].append(len(verts)) + verts.append(tuple(vert)) + vert[yp] = ry + vert[xp] = rx # restore + + if eyr and j == hemi: + vert[yp] = (-eyr - half_chord) * dir[yp] + if axis_aligned: + svitc[hemi].append(len(verts)) + verts.append(tuple(vert)) + if subdiv: + offsety = dssxyz[yp] * dir[yp] + for k in range(dxyz[yp]): + vert[yp] += offsety + if exr and i == hemi and not axis_aligned and subdiv & ALL: + vert[xp] = rxi + for l in range(dxyz[xp]): vert[xp] += offsetx - svitc[hemi].append(len(verts)) + svitc[hemi + k].append(len(verts)) verts.append(tuple(vert)) - if subdiv & ALL: - for l in range(dxyz[yp]): - vert[yp] += offsety - svitc[hemi + axis_aligned + l].append(len(verts)) - verts.append(tuple(vert)) - vert[yp] = ry - vert[xp] = rx # restore - - if eyr and j == hemi: - vert[yp] = (-eyr - half_chord) * dir[yp] - if axis_aligned: - svitc[hemi].append(len(verts)) + vert[xp] = rx + svitc[hemi + axis_aligned + k].append(len(verts)) verts.append(tuple(vert)) - if subdiv: - offsety = dssxyz[yp] * dir[yp] - for k in range(dxyz[yp]): - vert[yp] += offsety - if exr and i == hemi and not axis_aligned and subdiv & ALL: - vert[xp] = rxi - for l in range(dxyz[xp]): - vert[xp] += offsetx - svitc[hemi + k].append(len(verts)) - verts.append(tuple(vert)) - vert[xp] = rx - svitc[hemi + axis_aligned + k].append(len(verts)) - verts.append(tuple(vert)) - svitc[ri].append(len(verts)) - verts.append(rv) - ryi += 1 - rzi += 1 + svitc[ri].append(len(verts)) + verts.append(rv) + ri += 1 # Complete svit edges (shared vertices) # Sides' right edge @@ -247,13 +247,9 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0. ,0. ,0.), div_type='COR for j, row in enumerate(rows[:-1]): svit[3 if not side else side - 1][j].append(row[0]) # Sides' top edge - for j, row in enumerate(svit[5]): - if not j: - for col in row: - svit[0][-1].append(col) - if j == len(svit[5]) - 1: - for col in reversed(row): - svit[2][-1].append(col) + svit[0][-1].extend(svit[5][0]) + svit[2][-1].extend(svit[5][-1][::-1]) + for row in svit[5]: svit[3][-1].insert(0, row[0]) svit[1][-1].append(row[-1]) if odd_aligned: @@ -320,14 +316,15 @@ def round_cube(radius=1.0, arcdiv=4, lindiv=0., size=(0. ,0. ,0.), div_type='COR from bpy.props import BoolProperty, EnumProperty, FloatProperty, FloatVectorProperty, IntProperty -class AddRoundCube(bpy.types.Operator): +class AddRoundCube(bpy.types.Operator, object_utils.AddObjectHelper): """Add Round Cube Primitive""" bl_idname = 'mesh.primitive_round_cube_add' bl_label = 'Add Round Cube' - bl_description = 'Add mesh primitives: Quadsphere, Capsule, Rounded Cuboid, 3D Grid' + bl_description = 'Add mesh primitives: Quadspheres, Capsules, Rounded Cuboids, 3D Grids, etc.' bl_options = {'REGISTER', 'UNDO', 'PRESET'} sanity_check_verts = 200000 + vert_count = 0 radius = FloatProperty( name = 'Radius', @@ -344,7 +341,7 @@ class AddRoundCube(bpy.types.Operator): arc_div = IntProperty( name = 'Arc Divisions', description = 'Arc curve divisions, per quadrant; 0 = derive from Linear', - default = 4, min = 0 + default = 4, min = 1 ) lin_div = FloatProperty( @@ -364,61 +361,23 @@ class AddRoundCube(bpy.types.Operator): ) odd_axis_align = BoolProperty( - name='Odd Axis Align', + name = 'Odd Axis Align', description = 'Align odd arc divisions with axes (Note: triangle corners!)', ) no_limit = BoolProperty( - name='No Limit', + name = 'No Limit', description = 'Do not limit to '+str(sanity_check_verts)+' vertices (sanity check)', - ) - - preset = EnumProperty( - name = 'Presets', - items = ( - ('CUSTOM', 'Custom', 'Round Cube'), - ('SPHERE', 'Sphere', 'Quadsphere'), - ('CAPSULE', 'Capsule', 'Capsule'), - ('CUBOID', 'Cube', 'Rounded Cuboid'), - ('3DGRID', 'Grid', '3D Grid Cube')), - default = 'CUSTOM', options={'HIDDEN'} + options = {'HIDDEN'} ) def execute(self, context): - if self.preset == 'SPHERE': - self.radius = 1.0 - self.size = (0.,0.,0.) - self.arc_div = max(self.arc_div, 4) - self.lin_div = 0. - self.div_type = 'CORNERS' - elif self.preset == 'CAPSULE': - self.radius = 0.5 - self.size = (0.,0.,3.) - self.arc_div = max(self.arc_div, 4) - self.lin_div = 0. - self.div_type = 'CORNERS' - elif self.preset == 'CUBOID': - self.radius = 0.25 - self.size = (2.,2.,2.) - self.arc_div = max(self.arc_div, 4) - self.lin_div = 0. - self.div_type = 'CORNERS' - elif self.preset == '3DGRID': - self.radius = 1.0 - self.arc_div = 1 - self.lin_div = max(self.lin_div, 5.) - self.div_type = 'ALL' - self.size = (2.,2.,2.) - self.odd_axis_align = False - self.preset = 'CUSTOM' - if self.arc_div <=0 and self.lin_div <= 0: self.report({'ERROR'}, 'Either Arc Divisions or Linear Divisions must be greater than zero!') return {'CANCELLED'} if not self.no_limit: - arcdiv, lindiv, vert_count = round_cube(self.radius, self.arc_div, self.lin_div, self.size, self.div_type, self.odd_axis_align, True) - if vert_count > self.sanity_check_verts: + if self.vert_count > self.sanity_check_verts: self.report({'ERROR'}, 'More than '+str(self.sanity_check_verts)+' vertices! Check "No Limit" to proceed') return {'CANCELLED'} @@ -426,54 +385,52 @@ class AddRoundCube(bpy.types.Operator): mesh = bpy.data.meshes.new('Roundcube') mesh.from_pydata(verts,[],faces) - object_utils.object_data_add(context, mesh, operator=None) + object_utils.object_data_add(context, mesh, operator=self) return {'FINISHED'} - def draw(self, context): + def check(self, context): + self.arcdiv, self.lindiv, self.vert_count = round_cube(self.radius, self.arc_div, self.lin_div, self.size, self.div_type, self.odd_axis_align, True) + return True # False - arcdiv, lindiv, vert_count = round_cube(self.radius, self.arc_div, self.lin_div, self.size, self.div_type, self.odd_axis_align, True) + def invoke(self, context, event): + self.check(context) + return self.execute(context) + def draw(self, context): layout = self.layout layout.prop(self, 'radius') - row = layout.row() - row.column().prop(self, 'size', expand=True) + layout.column().prop(self, 'size', expand=True) box = layout.box() row = box.row() row.alignment = 'CENTER' row.scale_y = 0.1 row.label('Divisions') - row = box.row()# align=True) + row = box.row() col = row.column() col.alignment = 'RIGHT' col.label('Arc:') - col.prop(self, 'arc_div', text="") - col.label('[ {} ]'.format(arcdiv)) + col.prop(self, 'arc_div', text='') + col.label('[ {} ]'.format(self.arcdiv)) col = row.column() col.alignment = 'RIGHT' col.label('Linear:') - col.prop(self, 'lin_div', text="") - col.label('[ {:.3g} ]'.format(lindiv)) + col.prop(self, 'lin_div', text='') + col.label('[ {:.3g} ]'.format(self.lindiv)) box.row().prop(self, 'div_type') row = box.row() - row.active = arcdiv % 2 + row.active = self.arcdiv % 2 row.prop(self, 'odd_axis_align') row = layout.row() - row.alert = vert_count > self.sanity_check_verts - row.prop(self, 'no_limit', text='No limit ({})'.format(vert_count)) + row.alert = self.vert_count > self.sanity_check_verts + row.prop(self, 'no_limit', text='No limit ({})'.format(self.vert_count)) + + col = layout.column(align=True) + col.prop(self, 'location', expand=True) + col = layout.column(align=True) + col.prop(self, 'rotation', expand=True) -class INFO_MT_mesh_round_cube_add(bpy.types.Menu): - bl_idname = 'INFO_MT_mesh_round_cube_add' - bl_label = 'Round Cube' - def draw(self, context): - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator(AddRoundCube.bl_idname, text = 'Custom', icon='MOD_SUBSURF') - layout.operator(AddRoundCube.bl_idname, text = 'Sphere', icon='META_BALL').preset = 'SPHERE' - layout.operator(AddRoundCube.bl_idname, text = 'Capsule', icon='META_ELLIPSOID').preset = 'CAPSULE' - layout.operator(AddRoundCube.bl_idname, text = 'Cube', icon='META_CUBE').preset = 'CUBOID' - layout.operator(AddRoundCube.bl_idname, text = 'Grid', icon='META_CUBE').preset = '3DGRID' |