diff --git a/add_mesh_archimedean_solids.py b/add_mesh_archimedean_solids.py index 40acdf36a1ed357ebdcf22b054fc00a75889db50..ea1f2b85c0ab5df39931fd039cfe065898b39188 100644 --- a/add_mesh_archimedean_solids.py +++ b/add_mesh_archimedean_solids.py @@ -226,101 +226,12 @@ def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): return faces - -def add_rhombicuboctahedron(quad_size=sqrt(2.0) / (1.0 + sqrt(2) / 2.0)): - faces = [] - verts = [] - - size = 2.0 - - # Top & bottom faces (quads) - face_top = [] - face_bot = [] - for z, up in [(size / 2.0, True), (-size / 2.0, False)]: - face = [] - face.append(len(verts)) - verts.append(Vector((quad_size / 2.0, quad_size / 2.0, z))) - face.append(len(verts)) - verts.append(Vector((quad_size / 2.0, -quad_size / 2.0, z))) - face.append(len(verts)) - verts.append(Vector((-quad_size / 2.0, -quad_size / 2.0, z))) - face.append(len(verts)) - verts.append(Vector((-quad_size / 2.0, quad_size / 2.0, z))) - - if up: - # Top face (quad) - face_top = face - else: - # Bottom face (quad) - face_bot = face - - edgeloop_up = [] - edgeloop_low = [] - for z, up in [(quad_size / 2.0, True), (-quad_size / 2.0, False)]: - edgeloop = [] - - edgeloop.append(len(verts)) - verts.append(Vector((size / 2.0, quad_size / 2.0, z))) - edgeloop.append(len(verts)) - verts.append(Vector((size / 2.0, -quad_size / 2.0, z))) - edgeloop.append(len(verts)) - verts.append(Vector((quad_size / 2.0, -size / 2.0, z))) - edgeloop.append(len(verts)) - verts.append(Vector((-quad_size / 2.0, -size / 2.0, z))) - edgeloop.append(len(verts)) - verts.append(Vector((-size / 2.0, -quad_size / 2.0, z))) - edgeloop.append(len(verts)) - verts.append(Vector((-size / 2.0, quad_size / 2.0, z))) - edgeloop.append(len(verts)) - verts.append(Vector((-quad_size / 2.0, size / 2.0, z))) - edgeloop.append(len(verts)) - verts.append(Vector((quad_size / 2.0, size / 2.0, z))) - - if up: - # Upper 8-sider - edgeloop_up = edgeloop - else: - # Lower 8-sider - edgeloop_low = edgeloop - - face_top_idx = len(faces) - faces.append(face_top) - faces.append(face_bot) - faces_middle = createFaces(edgeloop_low, edgeloop_up, closed=True) - faces.extend(faces_middle) - - # Upper Quads - faces.append([edgeloop_up[0], face_top[0], face_top[1], edgeloop_up[1]]) - faces.append([edgeloop_up[2], face_top[1], face_top[2], edgeloop_up[3]]) - faces.append([edgeloop_up[4], face_top[2], face_top[3], edgeloop_up[5]]) - faces.append([edgeloop_up[6], face_top[3], face_top[0], edgeloop_up[7]]) - - # Upper Tris - faces.append([face_top[0], edgeloop_up[0], edgeloop_up[7]]) - faces.append([face_top[1], edgeloop_up[2], edgeloop_up[1]]) - faces.append([face_top[2], edgeloop_up[4], edgeloop_up[3]]) - faces.append([face_top[3], edgeloop_up[6], edgeloop_up[5]]) - - # Lower Quads - faces.append([edgeloop_low[0], edgeloop_low[1], face_bot[1], face_bot[0]]) - faces.append([edgeloop_low[2], edgeloop_low[3], face_bot[2], face_bot[1]]) - faces.append([edgeloop_low[4], edgeloop_low[5], face_bot[3], face_bot[2]]) - faces.append([edgeloop_low[6], edgeloop_low[7], face_bot[0], face_bot[3]]) - - # Lower Tris - faces.append([face_bot[0], edgeloop_low[7], edgeloop_low[0]]) - faces.append([face_bot[1], edgeloop_low[1], edgeloop_low[2]]) - faces.append([face_bot[2], edgeloop_low[3], edgeloop_low[4]]) - faces.append([face_bot[3], edgeloop_low[5], edgeloop_low[6]]) - - # Invert face normal - f = faces[face_top_idx] - faces[face_top_idx] = [f[0]] + list(reversed(f[1:])) - - return verts, faces +######################## # Returns the middle location of a _regular_ polygon. +# verts ... List of vertex coordinates (Vector) used by the ngon. +# ngon ... List of ngones (vertex indices of each ngon point) def get_polygon_center(verts, ngons): faces = [] @@ -341,10 +252,11 @@ def get_polygon_center(verts, ngons): return verts, faces +# v1 ... First vertex point (Vector) +# v2 ... Second vertex point (Vector) +# edgelength_middle .. Length of the middle section (va->vb) +# (v1)----(va)---------------(vb)----(v2) def subdivide_edge_2_cuts(v1, v2, edgelength_middle): - v1 = Vector(v1) - v2 = Vector(v2) - length = (v2 - v1).length vn = (v2 - v1).normalize() @@ -356,17 +268,30 @@ def subdivide_edge_2_cuts(v1, v2, edgelength_middle): return (va, vb) +# Invert the normal of a face. +# Inverts the order of the vertices to change the normal direction of a face. +def invert_face_normal(face): + return [face[0]] + list(reversed(face[1:])) + +######################## + + def add_truncated_tetrahedron(hexagon_side=2.0 * sqrt(2.0) / 3.0, star_ngons=False): + + if (hexagon_side < 0.0 + or hexagon_side > 2.0 * sqrt(2.0)): + return None, None + verts = [] faces = [] # Vertices of a simple Tetrahedron verts_tet = [ - (1.0, 1.0, -1.0), # tip 0 - (-1.0, 1.0, 1.0), # tip 1 - (1.0, -1.0, 1.0), # tip 2 - (-1.0, -1.0, -1.0)] # tip 3 + Vector((1.0, 1.0, -1.0)), # tip 0 + Vector((-1.0, 1.0, 1.0)), # tip 1 + Vector((1.0, -1.0, 1.0)), # tip 2 + Vector((-1.0, -1.0, -1.0))] # tip 3 # Calculate truncated vertices tri0 = [] @@ -446,39 +371,317 @@ def add_truncated_tetrahedron(hexagon_side=2.0 * sqrt(2.0) / 3.0, return verts, faces -class AddRhombicuboctahedron(bpy.types.Operator): - '''Add a mesh for a thombicuboctahedron.''' - bl_idname = 'mesh.primitive_thombicuboctahedron_add' - bl_label = 'Add Rhombicuboctahedron' - bl_description = 'Create a mesh for a thombicuboctahedron.' - bl_options = {'REGISTER', 'UNDO'} +def add_cuboctahedron(octagon_side=0.0, star_ngons=False): + if (octagon_side > 2.0 or octagon_side < 0.0): + return None, None, None - # edit - Whether to add or update. - edit = BoolProperty(name='', - description='', - default=False, - options={'HIDDEN'}) - quad_size = FloatProperty(name="Quad Size", - description="Size of the orthogonal quad faces.", - min=0.01, - max=1.99, - default=sqrt(2.0) / (1.0 + sqrt(2) / 2.0)) + s = octagon_side + verts = [] + faces = [] - def execute(self, context): - props = self.properties + size = 2.0 - verts, faces = add_rhombicuboctahedron(props.quad_size) + name = "Cuboctahedron" + if s == 0.0: + # Upper quad face + dist = z = size / 2.0 + face_top = [len(verts), len(verts) + 1, len(verts) + 2, len(verts) + 3] + verts.append(Vector((dist, 0.0, z))) + verts.append(Vector((0.0, dist, z))) + verts.append(Vector((-dist, 0.0, z))) + verts.append(Vector((0.0, -dist, z))) + faces.append(face_top) + + # 4 vertices on the z=0.0 plane + z = 0.0 + v_xp_yp = len(verts) + verts.append(Vector((dist, dist, z))) + v_xp_yn = len(verts) + verts.append(Vector((dist, -dist, z))) + v_xn_yn = len(verts) + verts.append(Vector((-dist, -dist, z))) + v_xn_yp = len(verts) + verts.append(Vector((-dist, dist, z))) + + # Lower quad face + z = -size / 2.0 + face_bot = [len(verts), len(verts) + 1, len(verts) + 2, len(verts) + 3] + verts.append((dist, 0.0, z)) + verts.append((0.0, -dist, z)) + verts.append((-dist, 0.0, z)) + verts.append((0.0, dist, z)) + faces.append(face_bot) + + # Last 4 faces + face_yp = [v_xp_yp, face_bot[3], v_xn_yp, face_top[1]] + face_yn = [v_xn_yn, face_bot[1], v_xp_yn, face_top[3]] + face_xp = [v_xp_yn, face_bot[0], v_xp_yp, face_top[0]] + face_xn = [v_xn_yp, face_bot[2], v_xn_yn, face_top[2]] + faces.extend([face_yp, face_yn, face_xp, face_xn]) + + # Tris top + tri_xp_yp_zp = [v_xp_yp, face_top[1], face_top[0]] + tri_xp_yn_zp = [v_xp_yn, face_top[0], face_top[3]] + tri_xn_yp_zp = [v_xn_yp, face_top[2], face_top[1]] + tri_xn_yn_zp = [v_xn_yn, face_top[3], face_top[2]] + faces.extend([tri_xp_yp_zp, tri_xp_yn_zp, tri_xn_yp_zp, tri_xn_yn_zp]) + + # Tris bottom + tri_xp_yp_zn = [v_xp_yn, face_bot[1], face_bot[0]] + tri_xp_yn_zn = [v_xp_yp, face_bot[0], face_bot[3]] + tri_xn_yp_zn = [v_xn_yn, face_bot[2], face_bot[1]] + tri_xn_yn_zn = [v_xn_yp, face_bot[3], face_bot[2]] + faces.extend([tri_xp_yp_zn, tri_xp_yn_zn, tri_xn_yp_zn, tri_xn_yn_zn]) - obj = create_mesh_object(context, verts, [], faces, - 'Rhombicuboctahedron', props.edit) + else: + name = "TruncatedCube" + + # Vertices of a simple Cube + verts_cube = [ + Vector((1.0, 1.0, 1.0)), # tip 0 + Vector((1.0, -1.0, 1.0)), # tip 1 + Vector((-1.0, -1.0, 1.0)), # tip 2 + Vector((-1.0, 1.0, 1.0)), # tip 3 + Vector((1.0, 1.0, -1.0)), # tip 4 + Vector((1.0, -1.0, -1.0)), # tip 5 + Vector((-1.0, -1.0, -1.0)), # tip 6 + Vector((-1.0, 1.0, -1.0))] # tip 7 + + tri_xp_yp_zp = [] + tri_xp_yn_zp = [] + tri_xn_yp_zp = [] + tri_xn_yn_zp = [] + tri_xp_yp_zn = [] + tri_xp_yn_zn = [] + tri_xn_yp_zn = [] + tri_xn_yn_zn = [] + + # Prepare top & bottom octagons. + ngon_top = [] + ngon_bot = [] + + # Top edges + va, vb = subdivide_edge_2_cuts(verts_cube[0], verts_cube[1], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xp_yp_zp.append(va_idx) + tri_xp_yn_zp.append(vb_idx) + ngon_top.extend([va_idx, vb_idx]) + va, vb = subdivide_edge_2_cuts(verts_cube[1], verts_cube[2], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xp_yn_zp.append(va_idx) + tri_xn_yn_zp.append(vb_idx) + ngon_top.extend([va_idx, vb_idx]) + va, vb = subdivide_edge_2_cuts(verts_cube[2], verts_cube[3], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xn_yn_zp.append(va_idx) + tri_xn_yp_zp.append(vb_idx) + ngon_top.extend([va_idx, vb_idx]) + va, vb = subdivide_edge_2_cuts(verts_cube[3], verts_cube[0], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xn_yp_zp.append(va_idx) + tri_xp_yp_zp.append(vb_idx) + ngon_top.extend([va_idx, vb_idx]) + + # Top-down edges + va, vb = subdivide_edge_2_cuts(verts_cube[0], verts_cube[4], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xp_yp_zp.append(va_idx) + tri_xp_yp_zn.append(vb_idx) + top_down_0 = [va_idx, vb_idx] + va, vb = subdivide_edge_2_cuts(verts_cube[1], verts_cube[5], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xp_yn_zp.append(va_idx) + tri_xp_yn_zn.append(vb_idx) + top_down_1 = [va_idx, vb_idx] + va, vb = subdivide_edge_2_cuts(verts_cube[2], verts_cube[6], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xn_yn_zp.append(va_idx) + tri_xn_yn_zn.append(vb_idx) + top_down_2 = [va_idx, vb_idx] + va, vb = subdivide_edge_2_cuts(verts_cube[3], verts_cube[7], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xn_yp_zp.append(va_idx) + tri_xn_yp_zn.append(vb_idx) + top_down_3 = [va_idx, vb_idx] + + # Bottom edges + va, vb = subdivide_edge_2_cuts(verts_cube[4], verts_cube[5], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xp_yp_zn.append(va_idx) + tri_xp_yn_zn.append(vb_idx) + ngon_bot.extend([va_idx, vb_idx]) + va, vb = subdivide_edge_2_cuts(verts_cube[5], verts_cube[6], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xp_yn_zn.append(va_idx) + tri_xn_yn_zn.append(vb_idx) + ngon_bot.extend([va_idx, vb_idx]) + va, vb = subdivide_edge_2_cuts(verts_cube[6], verts_cube[7], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xn_yn_zn.append(va_idx) + tri_xn_yp_zn.append(vb_idx) + ngon_bot.extend([va_idx, vb_idx]) + va, vb = subdivide_edge_2_cuts(verts_cube[7], verts_cube[4], s) + va_idx, vb_idx = len(verts), len(verts) + 1 + verts.extend([va, vb]) + tri_xn_yp_zn.append(va_idx) + tri_xp_yp_zn.append(vb_idx) + ngon_bot.extend([va_idx, vb_idx]) + + # Octagon polygons (n-gons) + ngon_0 = [ + top_down_0[1], top_down_0[0], ngon_top[0], ngon_top[1], + top_down_1[0], top_down_1[1], ngon_bot[1], ngon_bot[0]] + ngon_1 = [ + top_down_1[1], top_down_1[0], ngon_top[2], ngon_top[3], + top_down_2[0], top_down_2[1], ngon_bot[3], ngon_bot[2]] + ngon_2 = [ + top_down_2[1], top_down_2[0], ngon_top[4], ngon_top[5], + top_down_3[0], top_down_3[1], ngon_bot[5], ngon_bot[4]] + ngon_3 = [ + top_down_3[1], top_down_3[0], ngon_top[6], ngon_top[7], + top_down_0[0], top_down_0[1], ngon_bot[7], ngon_bot[6]] + + # Invert face normals where needed. + ngon_top = invert_face_normal(ngon_top) + tri_xp_yp_zp = invert_face_normal(tri_xp_yp_zp) + tri_xp_yn_zn = invert_face_normal(tri_xp_yn_zn) + tri_xn_yp_zn = invert_face_normal(tri_xn_yp_zn) + tri_xn_yn_zn = invert_face_normal(tri_xn_yn_zn) + + # Tris + faces.extend([tri_xp_yp_zp, tri_xp_yn_zp, tri_xn_yp_zp, tri_xn_yn_zp]) + faces.extend([tri_xp_yp_zn, tri_xp_yn_zn, tri_xn_yp_zn, tri_xn_yn_zn]) + + # Offset vertices so QUADS are created with orthagonal edges. + # Superficial change - Could be omitted, especially for stars. + ngon_bot = ngon_bot[1:] + [ngon_bot[0]] + ngon_0 = ngon_0[1:] + [ngon_0[0]] + ngon_1 = ngon_1[1:] + [ngon_1[0]] + ngon_2 = ngon_2[1:] + [ngon_2[0]] + ngon_3 = ngon_3[1:] + [ngon_3[0]] + + ngons = [ngon_top, ngon_bot, ngon_0, ngon_1, ngon_2, ngon_3] + if star_ngons: + # Create stars from octagons. + verts, faces_star = get_polygon_center(verts, ngons) + faces.extend(faces_star) - # Store 'recall' properties in the object. - recall_args_list = { - 'edit': True, - 'quad_size': props.quad_size} - store_recall_properties(obj, self, recall_args_list) + else: + # Create quads from octagons. + for ngon in ngons: + faces.extend([ + [ngon[0], ngon[1], ngon[2], ngon[3]], + [ngon[0], ngon[3], ngon[4], ngon[7]], + [ngon[7], ngon[4], ngon[5], ngon[6]]]) - return {'FINISHED'} + return verts, faces, name + + +def add_rhombicuboctahedron(quad_size=sqrt(2.0) / (1.0 + sqrt(2) / 2.0)): + if (quad_size > 2.0 or quad_size < 0.0): + return None, None + + faces = [] + verts = [] + + size = 2.0 + + # Top & bottom faces (quads) + face_top = [] + face_bot = [] + for z, up in [(size / 2.0, True), (-size / 2.0, False)]: + face = [] + face.append(len(verts)) + verts.append(Vector((quad_size / 2.0, quad_size / 2.0, z))) + face.append(len(verts)) + verts.append(Vector((quad_size / 2.0, -quad_size / 2.0, z))) + face.append(len(verts)) + verts.append(Vector((-quad_size / 2.0, -quad_size / 2.0, z))) + face.append(len(verts)) + verts.append(Vector((-quad_size / 2.0, quad_size / 2.0, z))) + + if up: + # Top face (quad) + face_top = face + else: + # Bottom face (quad) + face_bot = face + + edgeloop_up = [] + edgeloop_low = [] + for z, up in [(quad_size / 2.0, True), (-quad_size / 2.0, False)]: + edgeloop = [] + + edgeloop.append(len(verts)) + verts.append(Vector((size / 2.0, quad_size / 2.0, z))) + edgeloop.append(len(verts)) + verts.append(Vector((size / 2.0, -quad_size / 2.0, z))) + edgeloop.append(len(verts)) + verts.append(Vector((quad_size / 2.0, -size / 2.0, z))) + edgeloop.append(len(verts)) + verts.append(Vector((-quad_size / 2.0, -size / 2.0, z))) + edgeloop.append(len(verts)) + verts.append(Vector((-size / 2.0, -quad_size / 2.0, z))) + edgeloop.append(len(verts)) + verts.append(Vector((-size / 2.0, quad_size / 2.0, z))) + edgeloop.append(len(verts)) + verts.append(Vector((-quad_size / 2.0, size / 2.0, z))) + edgeloop.append(len(verts)) + verts.append(Vector((quad_size / 2.0, size / 2.0, z))) + + if up: + # Upper 8-sider + edgeloop_up = edgeloop + else: + # Lower 8-sider + edgeloop_low = edgeloop + + face_top_idx = len(faces) + faces.append(face_top) + faces.append(face_bot) + faces_middle = createFaces(edgeloop_low, edgeloop_up, closed=True) + faces.extend(faces_middle) + + # Upper Quads + faces.append([edgeloop_up[0], face_top[0], face_top[1], edgeloop_up[1]]) + faces.append([edgeloop_up[2], face_top[1], face_top[2], edgeloop_up[3]]) + faces.append([edgeloop_up[4], face_top[2], face_top[3], edgeloop_up[5]]) + faces.append([edgeloop_up[6], face_top[3], face_top[0], edgeloop_up[7]]) + + # Upper Tris + faces.append([face_top[0], edgeloop_up[0], edgeloop_up[7]]) + faces.append([face_top[1], edgeloop_up[2], edgeloop_up[1]]) + faces.append([face_top[2], edgeloop_up[4], edgeloop_up[3]]) + faces.append([face_top[3], edgeloop_up[6], edgeloop_up[5]]) + + # Lower Quads + faces.append([edgeloop_low[0], edgeloop_low[1], face_bot[1], face_bot[0]]) + faces.append([edgeloop_low[2], edgeloop_low[3], face_bot[2], face_bot[1]]) + faces.append([edgeloop_low[4], edgeloop_low[5], face_bot[3], face_bot[2]]) + faces.append([edgeloop_low[6], edgeloop_low[7], face_bot[0], face_bot[3]]) + + # Lower Tris + faces.append([face_bot[0], edgeloop_low[7], edgeloop_low[0]]) + faces.append([face_bot[1], edgeloop_low[1], edgeloop_low[2]]) + faces.append([face_bot[2], edgeloop_low[3], edgeloop_low[4]]) + faces.append([face_bot[3], edgeloop_low[5], edgeloop_low[6]]) + + # Invert face normal + f = faces[face_top_idx] + faces[face_top_idx] = invert_face_normal(faces[face_top_idx]) + + return verts, faces class AddTruncatedTetrahedron(bpy.types.Operator): @@ -510,6 +713,9 @@ class AddTruncatedTetrahedron(bpy.types.Operator): props.hexagon_side, props.star_ngons) + if not verts: + return {'CANCELLED'} + obj = create_mesh_object(context, verts, [], faces, 'TrTetrahedron', props.edit) @@ -523,6 +729,88 @@ class AddTruncatedTetrahedron(bpy.types.Operator): return {'FINISHED'} +class AddCuboctahedron(bpy.types.Operator): + '''Add a mesh for a cuboctahedron (truncated cube).''' + bl_idname = 'mesh.primitive_cuboctahedron_add' + bl_label = 'Add Cuboctahedron' + bl_description = 'Create a mesh for a cuboctahedron (truncated cube).' + bl_options = {'REGISTER', 'UNDO'} + + # edit - Whether to add or update. + edit = BoolProperty(name='', + description='', + default=False, + options={'HIDDEN'}) + octagon_side = FloatProperty(name='Octagon Side', + description='One length of the octagon side' \ + ' (on the original cube edge).', + min=0.00, + max=1.99, + default=0.0) + star_ngons = BoolProperty(name='Star N-Gon', + description='Create star-shaped octagons.', + default=False) + + def execute(self, context): + props = self.properties + + verts, faces, name = add_cuboctahedron( + props.octagon_side, + props.star_ngons) + + if not verts: + return {'CANCELLED'} + + obj = create_mesh_object(context, verts, [], faces, name, props.edit) + + # Store 'recall' properties in the object. + recall_args_list = { + 'edit': True, + 'octagon_side': props.octagon_side, + 'star_ngons': props.star_ngons} + store_recall_properties(obj, self, recall_args_list) + + return {'FINISHED'} + + +class AddRhombicuboctahedron(bpy.types.Operator): + '''Add a mesh for a thombicuboctahedron.''' + bl_idname = 'mesh.primitive_thombicuboctahedron_add' + bl_label = 'Add Rhombicuboctahedron' + bl_description = 'Create a mesh for a thombicuboctahedron.' + bl_options = {'REGISTER', 'UNDO'} + + # edit - Whether to add or update. + edit = BoolProperty(name='', + description='', + default=False, + options={'HIDDEN'}) + quad_size = FloatProperty(name="Quad Size", + description="Size of the orthogonal quad faces.", + min=0.01, + max=1.99, + default=sqrt(2.0) / (1.0 + sqrt(2) / 2.0)) + + def execute(self, context): + props = self.properties + + verts, faces = add_rhombicuboctahedron(props.quad_size) + + if not verts: + return {'CANCELLED'} + + obj = create_mesh_object(context, verts, [], faces, + 'Rhombicuboctahedron', props.edit) + + # Store 'recall' properties in the object. + recall_args_list = { + 'edit': True, + 'quad_size': props.quad_size} + store_recall_properties(obj, self, recall_args_list) + + return {'FINISHED'} + + class INFO_MT_mesh_archimedean_solids_add(bpy.types.Menu): # Define the "Archimedean Solids" menu bl_idname = "INFO_MT_mesh_archimedean_solids_add" @@ -533,6 +821,8 @@ class INFO_MT_mesh_archimedean_solids_add(bpy.types.Menu): layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("mesh.primitive_truncated_tetrahedron_add", text="Truncated Tetrahedron") + layout.operator("mesh.primitive_cuboctahedron_add", + text="Cuboctahedron") layout.operator("mesh.primitive_thombicuboctahedron_add", text="Rhombicuboctahedron") @@ -545,8 +835,9 @@ menu_func = (lambda self, context: self.layout.menu( def register(): # Register the operators/menus. - bpy.types.register(AddRhombicuboctahedron) bpy.types.register(AddTruncatedTetrahedron) + bpy.types.register(AddCuboctahedron) + bpy.types.register(AddRhombicuboctahedron) bpy.types.register(INFO_MT_mesh_archimedean_solids_add) # Add "Archimedean Solids" menu to the "Add Mesh" menu @@ -555,8 +846,9 @@ def register(): def unregister(): # Unregister the operators/menus. - bpy.types.unregister(AddRhombicuboctahedron) bpy.types.unregister(AddTruncatedTetrahedron) + bpy.types.unregister(AddCuboctahedron) + bpy.types.unregister(AddRhombicuboctahedron) bpy.types.unregister(INFO_MT_mesh_archimedean_solids_add) # Remove "Archimedean Solids" menu from the "Add Mesh" menu.