Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrendon Murphy <meta.androcto1@gmail.com>2010-05-23 12:36:04 +0400
committerBrendon Murphy <meta.androcto1@gmail.com>2010-05-23 12:36:04 +0400
commit1ac918d53efc292f4826486dda3ece8a599911ac (patch)
tree393991f96aed7d5dbcaa46c13103fe87f62428cf
parent2a7db02d70385df24995a7647706b82335ffd4d7 (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.py1468
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()