diff options
author | Brendon Murphy <meta.androcto1@gmail.com> | 2010-05-23 12:36:04 +0400 |
---|---|---|
committer | Brendon Murphy <meta.androcto1@gmail.com> | 2010-05-23 12:36:04 +0400 |
commit | 1ac918d53efc292f4826486dda3ece8a599911ac (patch) | |
tree | 393991f96aed7d5dbcaa46c13103fe87f62428cf | |
parent | 2a7db02d70385df24995a7647706b82335ffd4d7 (diff) |
moved back to contrib/py/scripts/addons/add_mesh_archimedean_solids.py
new Solids script handles these functions.
[[Split portion of a mixed commit.]]
-rw-r--r-- | add_mesh_archimedean_solids.py | 1468 |
1 files changed, 0 insertions, 1468 deletions
diff --git a/add_mesh_archimedean_solids.py b/add_mesh_archimedean_solids.py deleted file mode 100644 index eef71785..00000000 --- a/add_mesh_archimedean_solids.py +++ /dev/null @@ -1,1468 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -bl_addon_info = { - 'name': 'Add Mesh: Archimedean Solids', - 'author': 'Buerbaum Martin (Pontiac)', - 'version': '0.1', - 'blender': (2, 5, 3), - 'location': 'View3D > Add > Mesh > Archimedean Solids', - 'description': 'Adds various archimedean solids to the Add Mesh menu', - 'url': - 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \ - 'Scripts/Add_Mesh/Archimedean_Solids', # @todo write the page - 'category': 'Add Mesh'} - -import bpy -from math import sqrt -from mathutils import * -from bpy.props import * - - -# Stores the values of a list of properties and the -# operator id in a property group ('recall_op') inside the object. -# Could (in theory) be used for non-objects. -# Note: Replaces any existing property group with the same name! -# ob ... Object to store the properties in. -# op ... The operator that should be used. -# op_args ... A dictionary with valid Blender -# properties (operator arguments/parameters). -def store_recall_properties(ob, op, op_args): - if ob and op and op_args: - recall_properties = {} - - # Add the operator identifier and op parameters to the properties. - recall_properties['op'] = op.bl_idname - recall_properties['args'] = op_args - - # Store new recall properties. - ob['recall'] = recall_properties - - -# calculates the matrix for the new object -# depending on user pref -def align_matrix(context): - loc = TranslationMatrix(context.scene.cursor_location) - obj_align = context.user_preferences.edit.object_align - if (context.space_data.type == 'VIEW_3D' - and obj_align == 'VIEW'): - rot = context.space_data.region_3d.view_matrix.rotation_part().invert().resize4x4() - else: - rot = Matrix() - align_matrix = loc * rot - return align_matrix - - -# Create a new mesh (object) from verts/edges/faces. -# verts/edges/faces ... List of vertices/edges/faces for the -# new mesh (as used in from_pydata). -# name ... Name of the new mesh (& object). -# edit ... Replace existing mesh data. -# Note: Using "edit" will destroy/delete existing mesh data. -def create_mesh_object(context, verts, edges, faces, name, edit, align_matrix): - scene = context.scene - obj_act = scene.objects.active - - # Can't edit anything, unless we have an active obj. - if edit and not obj_act: - return None - - # Create new mesh - mesh = bpy.data.meshes.new(name) - - # Make a mesh from a list of verts/edges/faces. - mesh.from_pydata(verts, edges, faces) - - # Update mesh geometry after adding stuff. - mesh.update() - - # Deselect all objects. - bpy.ops.object.select_all(action='DESELECT') - - if edit: - # Replace geometry of existing object - - # Use the active obj and select it. - ob_new = obj_act - ob_new.selected = True - - if obj_act.mode == 'OBJECT': - # Get existing mesh datablock. - old_mesh = ob_new.data - - # Set object data to nothing - ob_new.data = None - - # Clear users of existing mesh datablock. - old_mesh.user_clear() - - # Remove old mesh datablock if no users are left. - if (old_mesh.users == 0): - bpy.data.meshes.remove(old_mesh) - - # Assign new mesh datablock. - ob_new.data = mesh - - else: - # Create new object - ob_new = bpy.data.objects.new(name, mesh) - - # Link new object to the given scene and select it. - scene.objects.link(ob_new) - ob_new.selected = True - - # Place the object at the 3D cursor location. - # apply viewRotaion - ob_new.matrix = align_matrix - - if obj_act and obj_act.mode == 'EDIT': - if not edit: - # We are in EditMode, switch to ObjectMode. - bpy.ops.object.mode_set(mode='OBJECT') - - # Select the active object as well. - obj_act.selected = True - - # Apply location of new object. - scene.update() - - # Join new object into the active. - bpy.ops.object.join() - - # Switching back to EditMode. - bpy.ops.object.mode_set(mode='EDIT') - - ob_new = obj_act - - else: - # We are in ObjectMode. - # Make the new object the active one. - scene.objects.active = ob_new - - return ob_new - - -# A very simple "bridge" tool. -# Connects two equally long vertex rows with faces. -# Returns a list of the new faces (list of lists) -# -# vertIdx1 ... First vertex list (list of vertex indices). -# vertIdx2 ... Second vertex list (list of vertex indices). -# closed ... Creates a loop (first & last are closed). -# flipped ... Invert the normal of the face(s). -# -# Note: You can set vertIdx1 to a single vertex index to create -# a fan/star of faces. -# Note: If both vertex idx list are the same length they have -# to have at least 2 vertices. -def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): - faces = [] - - if not vertIdx1 or not vertIdx2: - return None - - if len(vertIdx1) < 2 and len(vertIdx2) < 2: - return None - - fan = False - if (len(vertIdx1) != len(vertIdx2)): - if (len(vertIdx1) == 1 and len(vertIdx2) > 1): - fan = True - else: - return None - - total = len(vertIdx2) - - if closed: - # Bridge the start with the end. - if flipped: - face = [ - vertIdx1[0], - vertIdx2[0], - vertIdx2[total - 1]] - if not fan: - face.append(vertIdx1[total - 1]) - faces.append(face) - - else: - face = [vertIdx2[0], vertIdx1[0]] - if not fan: - face.append(vertIdx1[total - 1]) - face.append(vertIdx2[total - 1]) - faces.append(face) - - # Bridge the rest of the faces. - for num in range(total - 1): - if flipped: - if fan: - face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]] - else: - face = [vertIdx2[num], vertIdx1[num], - vertIdx1[num + 1], vertIdx2[num + 1]] - faces.append(face) - else: - if fan: - face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]] - else: - face = [vertIdx1[num], vertIdx2[num], - vertIdx2[num + 1], vertIdx1[num + 1]] - faces.append(face) - - return faces - -######################## - - -# Converts regular ngons to quads -# Note: Exists because most "fill" functions can not be -# controlled as easily. -def ngon_fill(ngon, offset=0): - if offset > 0: - for i in range(offset): - ngon = ngon[1:] + [ngon[0]] - - if len(ngon) == 6: - # Hexagon - return [ - [ngon[0], ngon[1], ngon[2], ngon[3]], - [ngon[0], ngon[3], ngon[4], ngon[5]]] - - elif len(ngon) == 8: - # Octagon - return [ - [ngon[0], ngon[1], ngon[2], ngon[3]], - [ngon[0], ngon[3], ngon[4], ngon[7]], - [ngon[7], ngon[4], ngon[5], ngon[6]]] - - else: - return None - # Not supported (yet) - - -# 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 = [] - - for f in ngons: - loc = Vector((0.0, 0.0, 0.0)) - - for vert_idx in f: - loc = loc + Vector(verts[vert_idx]) - - loc = loc / len(f) - - vert_idx_new = len(verts) - verts.append(loc) - - face_star = createFaces([vert_idx_new], f, closed=True) - faces.extend(face_star) - - 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): - length = (v2 - v1).length - vn = (v2 - v1).normalize() - - edgelength_1a_b2 = (length - edgelength_middle) / 2.0 - - va = v1 + vn * edgelength_1a_b2 - vb = v1 + vn * (edgelength_1a_b2 + 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:])) - -######################## - - -# http://en.wikipedia.org/wiki/Truncated_tetrahedron -def add_truncated_tetrahedron(hexagon_side=2.0 * sqrt(2.0) / 3.0, - star_ngons=False): - - size = 2.0 - - if (hexagon_side < 0.0 - or hexagon_side > size * sqrt(2.0)): - return None, None - - verts = [] - faces = [] - - # Vertices of a simple Tetrahedron - verts_tet = [ - 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 = [] - tri1 = [] - tri2 = [] - tri3 = [] - - va, vb = subdivide_edge_2_cuts(verts_tet[0], verts_tet[1], hexagon_side) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tri0.append(va_idx) - tri1.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_tet[0], verts_tet[2], hexagon_side) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tri0.append(va_idx) - tri2.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_tet[0], verts_tet[3], hexagon_side) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tri0.append(va_idx) - tri3.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_tet[1], verts_tet[2], hexagon_side) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tri1.append(va_idx) - tri2.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_tet[1], verts_tet[3], hexagon_side) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tri1.append(va_idx) - tri3.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_tet[2], verts_tet[3], hexagon_side) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tri2.append(va_idx) - tri3.append(vb_idx) - - # Hexagon polygons (n-gons) - ngon012 = [tri0[1], tri0[0], tri1[0], tri1[1], tri2[1], tri2[0]] - ngon031 = [tri0[0], tri0[2], tri3[0], tri3[1], tri1[2], tri1[0]] - ngon023 = [tri0[2], tri0[1], tri2[0], tri2[2], tri3[2], tri3[0]] - ngon132 = [tri1[1], tri1[2], tri3[1], tri3[2], tri2[2], tri2[1]] - - if star_ngons: - # Create stars from hexagons - verts, faces_star = get_polygon_center(verts, - [ngon012, ngon031, ngon023, ngon132]) - faces.extend(faces_star) - - else: - # Create quads from hexagons - hex_quads = ngon_fill(ngon012) - faces.extend(hex_quads) - hex_quads = ngon_fill(ngon031) - faces.extend(hex_quads) - hex_quads = ngon_fill(ngon023) - faces.extend(hex_quads) - hex_quads = ngon_fill(ngon132) - faces.extend(hex_quads) - - # Invert face normals - tri1 = [tri1[0]] + list(reversed(tri1[1:])) - tri3 = [tri3[0]] + list(reversed(tri3[1:])) - - # Tri faces - faces.extend([tri0, tri1, tri2, tri3]) - - return verts, faces - - -# http://en.wikipedia.org/wiki/Truncated_cube -# http://en.wikipedia.org/wiki/Cuboctahedron -def add_cuboctahedron(octagon_side=0.0, star_ngons=False): - size = 2.0 - - if (octagon_side > size or octagon_side < 0.0): - return None, None, None - - s = octagon_side - verts = [] - faces = [] - - 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]) - - 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]) - - if star_ngons: - ngons = [ngon_top, ngon_bot, ngon_0, ngon_1, ngon_2, ngon_3] - # Create stars from octagons. - verts, faces_star = get_polygon_center(verts, ngons) - faces.extend(faces_star) - - else: - # Create quads from octagons. - - # The top octagon is the only polygon we don't need to offset. - oct_quads = ngon_fill(ngon_top) - faces.extend(oct_quads) - - ngons = [ngon_bot, ngon_0, ngon_1, ngon_2, ngon_3] - for ngon in ngons: - # offset=1 Offset vertices so QUADS are created with - # orthagonal edges. Superficial change - Could be omitted. - oct_quads = ngon_fill(ngon, offset=1) - faces.extend(oct_quads) - - return verts, faces, name - - -# http://en.wikipedia.org/wiki/Rhombicuboctahedron -# Note: quad_size=0 would result in a Cuboctahedron -def add_rhombicuboctahedron(quad_size=sqrt(2.0) / (1.0 + sqrt(2) / 2.0)): - size = 2.0 - - if (quad_size > size or quad_size < 0.0): - return None, None - - faces = [] - verts = [] - - # 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 - - -# http://en.wikipedia.org/wiki/Truncated_octahedron -def add_truncated_octahedron(hexagon_side=sqrt(2) / 3.0, star_ngons=False): - if (hexagon_side < 0.0 - or hexagon_side > sqrt(2)): - return None, None - - hs = hexagon_side - - verts = [] - faces = [] - - # Vertices of a simple Octahedron - verts_oct = [ - Vector((0.0, 0.0, 1.0)), # tip 0 - Top - Vector((1.0, 0.0, 0.0)), # tip 1 - xp y0 - Vector((0.0, -1.0, 0.0)), # tip 2 - x0 yn - Vector((-1.0, 0.0, 0.0)), # tip 3 - xn y0 - Vector((0.0, 1.0, 0.0)), # tip 4 - x0 yp - Vector((0.0, 0.0, -1.0))] # tip 5 - Bottom - - tip_top = [] - tip_1 = [] - tip_2 = [] - tip_3 = [] - tip_4 = [] - tip_bot = [] - - # Top edges - va, vb = subdivide_edge_2_cuts(verts_oct[0], verts_oct[1], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_top.append(va_idx) - tip_1.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_oct[0], verts_oct[2], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_top.append(va_idx) - tip_2.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_oct[0], verts_oct[3], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_top.append(va_idx) - tip_3.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_oct[0], verts_oct[4], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_top.append(va_idx) - tip_4.append(vb_idx) - - # Circumference edges - va, vb = subdivide_edge_2_cuts(verts_oct[1], verts_oct[2], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_1.append(va_idx) - tip_2.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_oct[2], verts_oct[3], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_2.append(va_idx) - tip_3.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_oct[3], verts_oct[4], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_3.append(va_idx) - tip_4.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_oct[4], verts_oct[1], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_4.append(va_idx) - tip_1.append(vb_idx) - - # Bottom edges - va, vb = subdivide_edge_2_cuts(verts_oct[5], verts_oct[1], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_bot.append(va_idx) - tip_1.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_oct[5], verts_oct[2], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_bot.append(va_idx) - tip_2.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_oct[5], verts_oct[3], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_bot.append(va_idx) - tip_3.append(vb_idx) - va, vb = subdivide_edge_2_cuts(verts_oct[5], verts_oct[4], hs) - va_idx, vb_idx = len(verts), len(verts) + 1 - verts.extend([va, vb]) - tip_bot.append(va_idx) - tip_4.append(vb_idx) - - # Hexagons - ngon_12_zp = [tip_top[0], tip_top[1], - tip_2[0], tip_2[1], - tip_1[1], tip_1[0]] - ngon_23_zp = [tip_top[1], tip_top[2], - tip_3[0], tip_3[1], - tip_2[2], tip_2[0]] - ngon_34_zp = [tip_top[2], tip_top[3], - tip_4[0], tip_4[1], - tip_3[2], tip_3[0]] - ngon_41_zp = [tip_top[3], tip_top[0], - tip_1[0], tip_1[2], - tip_4[2], tip_4[0]] - - ngon_12_zn = [tip_bot[0], tip_bot[1], - tip_2[3], tip_2[1], - tip_1[1], tip_1[3]] - ngon_23_zn = [tip_bot[1], tip_bot[2], - tip_3[3], tip_3[1], - tip_2[2], tip_2[3]] - ngon_34_zn = [tip_bot[2], tip_bot[3], - tip_4[3], tip_4[1], - tip_3[2], tip_3[3]] - ngon_41_zn = [tip_bot[3], tip_bot[0], - tip_1[3], tip_1[2], - tip_4[2], tip_4[3]] - - # Fix vertex order (and fix normal at the same time) - tip_1 = tip_1[:2] + list(reversed(tip_1[2:])) - tip_2 = list(reversed(tip_2[:2])) + tip_2[2:] - tip_3 = list(reversed(tip_3[:2])) + tip_3[2:] - tip_4 = list(reversed(tip_4[:2])) + tip_4[2:] - - # Invert face normals - tip_top = invert_face_normal(tip_top) - ngon_12_zn = invert_face_normal(ngon_12_zn) - ngon_23_zn = invert_face_normal(ngon_23_zn) - ngon_34_zn = invert_face_normal(ngon_34_zn) - ngon_41_zn = invert_face_normal(ngon_41_zn) - - # Tip quads - faces.extend([tip_top, tip_bot]) - faces.extend([tip_1, tip_2, tip_3, tip_4]) - - if star_ngons: - ngons = [ngon_12_zp, ngon_23_zp, ngon_34_zp, ngon_41_zp, - ngon_12_zn, ngon_23_zn, ngon_34_zn, ngon_41_zn] - # Create stars from octagons. - verts, faces_star = get_polygon_center(verts, ngons) - faces.extend(faces_star) - - else: - # Create quads from hexagons. - ngons = [ngon_12_zp, ngon_23_zp, ngon_34_zp, ngon_41_zp] - for ngon in ngons: - # offset=2 Offset vertices so QUADS are created with - # orthagonal edges. Superficial change - Could be omitted. - hex_quads = ngon_fill(ngon, offset=2) - faces.extend(hex_quads) - - ngons = [ngon_12_zn, ngon_23_zn, ngon_34_zn, ngon_41_zn] - for ngon in ngons: - # offset=1 Offset vertices so QUADS are created with - # orthagonal edges. Superficial change - Could be omitted. - hex_quads = ngon_fill(ngon, offset=1) - faces.extend(hex_quads) - - return verts, faces - - -# http://en.wikipedia.org/wiki/Truncated_cuboctahedron -def add_truncated_cuboctahedron( - octagon_size=2.0 - (2.0 / sqrt(2.0)) * (2.0 / (4.0 / sqrt(2.0) + 1.0)), - octagon_side=2.0 / (4.0 / sqrt(2.0) + 1.0), - star_ngons=False): - - size = 2.0 - - if (octagon_side < 0.0 - or octagon_size < 0.0 - or octagon_size < octagon_side - or octagon_size > size - or octagon_side > size): - return None, None - - verts = [] - faces = [] - - oside = octagon_side - - # 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. - oct_top = [] - oct_bot = [] - hex_0_zp = [] - hex_1_zp = [] - hex_2_zp = [] - hex_3_zp = [] - hex_0_zn = [] - hex_1_zn = [] - hex_2_zn = [] - hex_3_zn = [] - - bevel_size = (size - octagon_size) / 2.0 - - # Top edges #### - bevel_z = Vector((0.0, 0.0, -bevel_size)) - - va, vb = subdivide_edge_2_cuts(verts_cube[0], verts_cube[1], oside) - va1, vb1 = va + Vector((-bevel_size, 0, 0)), vb + Vector((-bevel_size, 0, 0)) - va2, vb2 = va + bevel_z, vb + bevel_z - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xp_yp_zp.append(va_idx) - #tri_xp_yn_zp.append(vb_idx) - oct_top.extend([va1_idx, vb1_idx]) - quad_01_zp = [va1_idx, vb1_idx, vb2_idx, va2_idx] - hex_0_zp.extend([va2_idx, va1_idx]) - hex_1_zp.extend([vb2_idx, vb1_idx]) - - va, vb = subdivide_edge_2_cuts(verts_cube[1], verts_cube[2], oside) - va1, vb1 = va + Vector((0, bevel_size, 0)), vb + Vector((0, bevel_size, 0)) - va2, vb2 = va + bevel_z, vb + bevel_z - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xp_yn_zp.append(va_idx) - #tri_xn_yn_zp.append(vb_idx) - oct_top.extend([va1_idx, vb1_idx]) - quad_12_zp = [va1_idx, vb1_idx, vb2_idx, va2_idx] - hex_1_zp.extend([va1_idx, va2_idx]) - hex_2_zp.extend([vb2_idx, vb1_idx]) - - va, vb = subdivide_edge_2_cuts(verts_cube[2], verts_cube[3], oside) - va1, vb1 = va + Vector((bevel_size, 0, 0)), vb + Vector((bevel_size, 0, 0)) - va2, vb2 = va + bevel_z, vb + bevel_z - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - oct_top.extend([va1_idx, vb1_idx]) - quad_23_zp = [va1_idx, vb1_idx, vb2_idx, va2_idx] - hex_2_zp.extend([va1_idx, va2_idx]) - hex_3_zp.extend([vb2_idx, vb1_idx]) - - va, vb = subdivide_edge_2_cuts(verts_cube[3], verts_cube[0], oside) - va1, vb1 = va + Vector((0, -bevel_size, 0)), vb + Vector((0, -bevel_size, 0)) - va2, vb2 = va + bevel_z, vb + bevel_z - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xn_yp_zp.append(va_idx) - #tri_xp_yp_zp.append(vb_idx) - oct_top.extend([va1_idx, vb1_idx]) - quad_30_zp = [va1_idx, vb1_idx, vb2_idx, va2_idx] - hex_3_zp.extend([va1_idx, va2_idx]) - hex_0_zp.extend([vb1_idx, vb2_idx]) - - # Top-down edges #### - va, vb = subdivide_edge_2_cuts(verts_cube[0], verts_cube[4], oside) - va1, vb1 = va + Vector((-bevel_size, 0, 0)), vb + Vector((-bevel_size, 0, 0)) - va2, vb2 = va + Vector((0, -bevel_size, 0)), vb + Vector((0, -bevel_size, 0)) - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xp_yp_zp.append(va_idx) - #tri_xp_yp_zn.append(vb_idx) - top_down_0_1 = [va1_idx, vb1_idx] - top_down_0_2 = [va2_idx, vb2_idx] - quad_04 = [vb1_idx, va1_idx, va2_idx, vb2_idx] - hex_0_zp.extend([va1_idx, va2_idx]) - hex_0_zn.extend([vb1_idx, vb2_idx]) - - va, vb = subdivide_edge_2_cuts(verts_cube[1], verts_cube[5], oside) - va1, vb1 = va + Vector((-bevel_size, 0, 0)), vb + Vector((-bevel_size, 0, 0)) - va2, vb2 = va + Vector((0, bevel_size, 0)), vb + Vector((0, bevel_size, 0)) - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xp_yn_zp.append(va_idx) - #tri_xp_yn_zn.append(vb_idx) - top_down_1_1 = [va1_idx, vb1_idx] - top_down_1_2 = [va2_idx, vb2_idx] - quad_15 = [va1_idx, vb1_idx, vb2_idx, va2_idx] - hex_1_zp.extend([va1_idx, va2_idx]) - hex_1_zn.extend([vb1_idx, vb2_idx]) - - va, vb = subdivide_edge_2_cuts(verts_cube[2], verts_cube[6], oside) - va1, vb1 = va + Vector((bevel_size, 0, 0)), vb + Vector((bevel_size, 0, 0)) - va2, vb2 = va + Vector((0, bevel_size, 0)), vb + Vector((0, bevel_size, 0)) - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xn_yn_zp.append(va_idx) - #tri_xn_yn_zn.append(vb_idx) - top_down_2_1 = [va1_idx, vb1_idx] - top_down_2_2 = [va2_idx, vb2_idx] - quad_26 = [vb1_idx, va1_idx, va2_idx, vb2_idx] - hex_2_zp.extend([va2_idx, va1_idx]) - hex_2_zn.extend([vb2_idx, vb1_idx]) - - va, vb = subdivide_edge_2_cuts(verts_cube[3], verts_cube[7], oside) - va1, vb1 = va + Vector((bevel_size, 0, 0)), vb + Vector((bevel_size, 0, 0)) - va2, vb2 = va + Vector((0, -bevel_size, 0)), vb + Vector((0, -bevel_size, 0)) - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xn_yp_zp.append(va_idx) - #tri_xn_yp_zn.append(vb_idx) - top_down_3_1 = [va1_idx, vb1_idx] - top_down_3_2 = [va2_idx, vb2_idx] - quad_37 = [va1_idx, vb1_idx, vb2_idx, va2_idx] - hex_3_zp.extend([va1_idx, va2_idx]) - hex_3_zn.extend([vb1_idx, vb2_idx]) - - # Bottom edges #### - bevel_z = Vector((0.0, 0.0, bevel_size)) - - va, vb = subdivide_edge_2_cuts(verts_cube[4], verts_cube[5], oside) - va1, vb1 = va + Vector((-bevel_size, 0, 0)), vb + Vector((-bevel_size, 0, 0)) - va2, vb2 = va + bevel_z, vb + bevel_z - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xp_yp_zn.append(va_idx) - #tri_xp_yn_zn.append(vb_idx) - oct_bot.extend([va1_idx, vb1_idx]) - quad_45_zn = [vb1_idx, va1_idx, va2_idx, vb2_idx] - hex_0_zn.extend([va2_idx, va1_idx]) - hex_1_zn.extend([vb2_idx, vb1_idx]) - - va, vb = subdivide_edge_2_cuts(verts_cube[5], verts_cube[6], oside) - va1, vb1 = va + Vector((0, bevel_size, 0)), vb + Vector((0, bevel_size, 0)) - va2, vb2 = va + bevel_z, vb + bevel_z - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xp_yn_zn.append(va_idx) - #tri_xn_yn_zn.append(vb_idx) - oct_bot.extend([va1_idx, vb1_idx]) - quad_56_zn = [vb1_idx, va1_idx, va2_idx, vb2_idx] - hex_1_zn.extend([va1_idx, va2_idx]) - hex_2_zn.extend([vb2_idx, vb1_idx]) - - va, vb = subdivide_edge_2_cuts(verts_cube[6], verts_cube[7], oside) - va1, vb1 = va + Vector((bevel_size, 0, 0)), vb + Vector((bevel_size, 0, 0)) - va2, vb2 = va + bevel_z, vb + bevel_z - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xn_yn_zn.append(va_idx) - #tri_xn_yp_zn.append(vb_idx) - oct_bot.extend([va1_idx, vb1_idx]) - quad_67_zn = [vb1_idx, va1_idx, va2_idx, vb2_idx] - hex_2_zn.extend([va1_idx, va2_idx]) - hex_3_zn.extend([vb2_idx, vb1_idx]) - - va, vb = subdivide_edge_2_cuts(verts_cube[7], verts_cube[4], oside) - va1, vb1 = va + Vector((0, -bevel_size, 0)), vb + Vector((0, -bevel_size, 0)) - va2, vb2 = va + bevel_z, vb + bevel_z - va1_idx, vb1_idx = len(verts), len(verts) + 1 - va2_idx, vb2_idx = len(verts) + 2, len(verts) + 3 - verts.extend([va1, vb1, va2, vb2]) - #tri_xn_yp_zn.append(va_idx) - #tri_xp_yp_zn.append(vb_idx) - oct_bot.extend([va1_idx, vb1_idx]) - quad_74_zn = [vb1_idx, va1_idx, va2_idx, vb2_idx] - hex_3_zn.extend([va1_idx, va2_idx]) - hex_0_zn.extend([vb1_idx, vb2_idx]) - - # Octagon polygons (n-gons) - oct_0 = [ - top_down_0_2[1], top_down_0_2[0], quad_01_zp[3], quad_01_zp[2], - top_down_1_2[0], top_down_1_2[1], quad_45_zn[3], quad_45_zn[2]] - oct_1 = [ - top_down_1_1[1], top_down_1_1[0], quad_12_zp[3], quad_12_zp[2], - top_down_2_1[0], top_down_2_1[1], quad_56_zn[3], quad_56_zn[2]] - oct_2 = [ - top_down_2_2[1], top_down_2_2[0], quad_23_zp[3], quad_23_zp[2], - top_down_3_2[0], top_down_3_2[1], quad_67_zn[3], quad_67_zn[2]] - oct_3 = [ - top_down_3_1[1], top_down_3_1[0], quad_30_zp[3], quad_30_zp[2], - top_down_0_1[0], top_down_0_1[1], quad_74_zn[3], quad_74_zn[2]] - - # Invert face normals where needed. - oct_top = invert_face_normal(oct_top) - hex_0_zp = invert_face_normal(hex_0_zp) - hex_1_zn = invert_face_normal(hex_1_zn) - hex_2_zn = invert_face_normal(hex_2_zn) - hex_3_zn = invert_face_normal(hex_3_zn) - - # Quads - faces.extend([quad_01_zp, quad_12_zp, quad_23_zp, quad_30_zp]) - faces.extend([quad_04, quad_15, quad_26, quad_37]) - faces.extend([quad_45_zn, quad_56_zn, quad_67_zn, quad_74_zn]) - - if star_ngons: - # Create stars from octagons. - ngons = [oct_top, oct_bot, oct_bot, oct_0, oct_1, oct_2, oct_3] - - verts, faces_star = get_polygon_center(verts, ngons) - faces.extend(faces_star) - - # Create stars from hexagons. - # @todo - - else: - # Create quads from octagons. - - # The top octagon is the only polygon we don't need to offset. - oct_quads = ngon_fill(oct_top) - faces.extend(oct_quads) - - ngons = [oct_bot, oct_0, oct_1, oct_2, oct_3] - for ngon in ngons: - # offset=1 Offset vertices so QUADS are created with - # orthagonal edges. Superficial change - Could be omitted. - oct_quads = ngon_fill(ngon, offset=1) - faces.extend(oct_quads) - - # Create quads from hexagons. - ngons = [hex_0_zp, hex_1_zp, hex_2_zp, hex_3_zp] - for ngon in ngons: - hex_quads = ngon_fill(ngon) - faces.extend(hex_quads) - - hex_quads = ngon_fill(hex_0_zn, offset=2) - faces.extend(hex_quads) - - ngons = [hex_1_zn, hex_2_zn, hex_3_zn] - for ngon in ngons: - hex_quads = ngon_fill(ngon, offset=1) - faces.extend(hex_quads) - - return verts, faces - -######################## - - -class AddTruncatedTetrahedron(bpy.types.Operator): - '''Add a mesh for a truncated tetrahedron.''' - bl_idname = 'mesh.primitive_truncated_tetrahedron_add' - bl_label = 'Add Truncated Tetrahedron' - bl_description = 'Create a mesh for a truncated tetrahedron.' - bl_options = {'REGISTER', 'UNDO'} - - # edit - Whether to add or update. - edit = BoolProperty(name='', - description='', - default=False, - options={'HIDDEN'}) - hexagon_side = FloatProperty(name='Hexagon Side', - description='One length of the hexagon side' \ - ' (on the original tetrahedron edge).', - min=0.01, - max=2.0 * sqrt(2.0) - 0.01, - default=2.0 * sqrt(2.0) / 3.0) - star_ngons = BoolProperty(name='Star N-Gon', - description='Create star-shaped hexagons.', - default=False) - align_matrix = Matrix() - - def execute(self, context): - props = self.properties - - verts, faces = add_truncated_tetrahedron( - props.hexagon_side, - props.star_ngons) - - if not verts: - return {'CANCELLED'} - - obj = create_mesh_object(context, verts, [], faces, - 'TrTetrahedron', props.edit, self.align_matrix) - - # Store 'recall' properties in the object. - recall_args_list = { - 'edit': True, - 'hexagon_side': props.hexagon_side, - 'star_ngons': props.star_ngons} - store_recall_properties(obj, self, recall_args_list) - - return {'FINISHED'} - - def invoke(self, context, event): - self.align_matrix = align_matrix(context) - self.execute(context) - 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 or Truncated Cube' - bl_description = 'Create a mesh for a cuboctahedron (or 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).' \ - ' 0: Cuboctahedron, >0: Truncated Cube', - min=0.00, - max=1.99, - default=0.0) - star_ngons = BoolProperty(name='Star N-Gon', - description='Create star-shaped octagons.', - default=False) - align_matrix = Matrix() - - 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, self.align_matrix) - - # 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'} - - def invoke(self, context, event): - self.align_matrix = align_matrix(context) - self.execute(context) - return {'FINISHED'} - - -class AddRhombicuboctahedron(bpy.types.Operator): - '''Add a mesh for a rhombicuboctahedron.''' - bl_idname = 'mesh.primitive_rhombicuboctahedron_add' - bl_label = 'Add Rhombicuboctahedron' - bl_description = 'Create a mesh for a rhombicuboctahedron.' - 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)) - align_matrix = Matrix() - - 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, self.align_matrix) - - # 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'} - - def invoke(self, context, event): - self.align_matrix = align_matrix(context) - self.execute(context) - return {'FINISHED'} - - -class AddTruncatedOctahedron(bpy.types.Operator): - '''Add a mesh for a truncated octahedron.''' - bl_idname = 'mesh.primitive_truncated_octahedron_add' - bl_label = 'Add Truncated Octahedron' - bl_description = 'Create a mesh for a truncated octahedron.' - bl_options = {'REGISTER', 'UNDO'} - - # edit - Whether to add or update. - edit = BoolProperty(name='', - description='', - default=False, - options={'HIDDEN'}) - hexagon_side = FloatProperty(name='Hexagon Side', - description='One length of the hexagon side' \ - ' (on the original octahedron edge).', - min=0.01, - max=sqrt(2) - 0.1, - default=sqrt(2) / 3.0) - star_ngons = BoolProperty(name='Star N-Gon', - description='Create star-shaped hexagons.', - default=False) - align_matrix = Matrix() - - def execute(self, context): - props = self.properties - - verts, faces = add_truncated_octahedron( - props.hexagon_side, - props.star_ngons) - - if not verts: - return {'CANCELLED'} - - obj = create_mesh_object(context, verts, [], faces, - 'TrOctahedron', props.edit, self.align_matrix) - - # Store 'recall' properties in the object. - recall_args_list = { - 'edit': True, - 'hexagon_side': props.hexagon_side, - 'star_ngons': props.star_ngons} - store_recall_properties(obj, self, recall_args_list) - - return {'FINISHED'} - - def invoke(self, context, event): - self.align_matrix = align_matrix(context) - self.execute(context) - return {'FINISHED'} - - -class AddTruncatedCuboctahedron(bpy.types.Operator): - '''Add a mesh for a truncated cuboctahedron.''' - bl_idname = 'mesh.primitive_truncated_cuboctahedron_add' - bl_label = 'Add Truncated Cuboctahedron' - bl_description = 'Create a mesh for a truncated cuboctahedron.' - bl_options = {'REGISTER', 'UNDO'} - - # edit - Whether to add or update. - edit = BoolProperty(name='', - description='', - default=False, - options={'HIDDEN'}) - octagon_size = FloatProperty(name='Octagon Size', - description='The size (height/width) of the octagon.', - min=0.02, - max=1.99, - default=2.0 - (2.0 / sqrt(2.0)) * (2.0 / (4.0 / sqrt(2.0) + 1.0))) - octagon_side = FloatProperty(name='Octagon Side', - description='One length of the octagon side' \ - ' (on the original cube edge).', - min=0.01, - max=1.98, - default=2.0 / (4.0 / sqrt(2.0) + 1.0)) - star_ngons = BoolProperty(name='Star N-Gon', - description='Create star-shaped octagons.', - default=False) - align_matrix = Matrix() - - def execute(self, context): - props = self.properties - - verts, faces = add_truncated_cuboctahedron( - props.octagon_size, - props.octagon_side, - props.star_ngons) - - if not verts: - return {'CANCELLED'} - - obj = create_mesh_object(context, verts, [], faces, - 'TrCuboctahedron', props.edit, self.align_matrix) - - # Store 'recall' properties in the object. - recall_args_list = { - 'edit': True, - 'octagon_size': props.octagon_size, - 'octagon_side': props.octagon_side, - 'star_ngons': props.star_ngons} - store_recall_properties(obj, self, recall_args_list) - - return {'FINISHED'} - - def invoke(self, context, event): - self.align_matrix = align_matrix(context) - self.execute(context) - 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" - bl_label = "Archimedean Solids" - - def draw(self, context): - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("mesh.primitive_truncated_tetrahedron_add", - text="Truncated Tetrahedron") - layout.operator("mesh.primitive_cuboctahedron_add", - text="Cuboctahedron or Truncated Cube") - layout.operator("mesh.primitive_rhombicuboctahedron_add", - text="Rhombicuboctahedron") - layout.operator("mesh.primitive_truncated_octahedron_add", - text="Truncated Octahedron") - layout.operator("mesh.primitive_truncated_cuboctahedron_add", - text="Truncated Cuboctahedron") - -######################## -import space_info - -# Define "Archimedean Solids" menu -menu_func = (lambda self, context: self.layout.menu( - "INFO_MT_mesh_archimedean_solids_add", icon="PLUGIN")) - - -def register(): - # Register the operators/menus. - bpy.types.register(AddTruncatedTetrahedron) - bpy.types.register(AddCuboctahedron) - bpy.types.register(AddRhombicuboctahedron) - bpy.types.register(AddTruncatedOctahedron) - bpy.types.register(AddTruncatedCuboctahedron) - bpy.types.register(INFO_MT_mesh_archimedean_solids_add) - - # Add "Archimedean Solids" menu to the "Add Mesh" menu - space_info.INFO_MT_mesh_add.append(menu_func) - - -def unregister(): - # Unregister the operators/menus. - bpy.types.unregister(AddTruncatedTetrahedron) - bpy.types.unregister(AddCuboctahedron) - bpy.types.unregister(AddRhombicuboctahedron) - bpy.types.unregister(AddTruncatedOctahedron) - bpy.types.unregister(AddTruncatedCuboctahedron) - bpy.types.unregister(INFO_MT_mesh_archimedean_solids_add) - - # Remove "Archimedean Solids" menu from the "Add Mesh" menu. - space_info.INFO_MT_mesh_add.remove(menu_func) - -if __name__ == "__main__": - register() |