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:
authorPhilip Cote <cotejrp@gmail.com>2012-07-20 03:07:39 +0400
committerPhilip Cote <cotejrp@gmail.com>2012-07-20 03:07:39 +0400
commit6c19e6cf0bc030b4c4e202cb78b74505acb7079b (patch)
tree5e24e9ebfd825bd57c9998366b379c446d3d65f9
parenta6689e08452cfd444a6c6f3e07f875209195a490 (diff)
Allow for anywhere from a 3 sided pyramid to 20 sided pyramid.
-rw-r--r--add_mesh_extra_objects/add_mesh_pyramid.py213
1 files changed, 117 insertions, 96 deletions
diff --git a/add_mesh_extra_objects/add_mesh_pyramid.py b/add_mesh_extra_objects/add_mesh_pyramid.py
index da14e998..e99ffd9a 100644
--- a/add_mesh_extra_objects/add_mesh_pyramid.py
+++ b/add_mesh_extra_objects/add_mesh_pyramid.py
@@ -22,7 +22,7 @@
bl_info = {
'name': 'Mesh Pyramid',
'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
- 'version': (0, 4),
+ 'version': (0, 5),
"blender": (2, 6, 3),
'location': 'View3D > Add > Mesh',
'description': 'Create an egyption-style step pyramid',
@@ -32,111 +32,133 @@ bl_info = {
import bpy
import bmesh
-
-from bpy.props import IntProperty, FloatProperty
+from bpy.props import FloatProperty, IntProperty
+from math import pi
+from mathutils import Quaternion, Vector
from bpy_extras.object_utils import AddObjectHelper, object_data_add
-def makePyramid(initial_size, step_height, step_width, number_steps):
-
- vert_list = []
- face_list = []
-
- cur_size = initial_size # how large each step will be overall
-
- # b = buttom, t = top, f = front, b = back, l = left, r = right
- x = y = z = 0
- voffset = 0 # relative vert indices to help make faces fo each step
- sn = 0 # step number
-
- while sn < number_steps:
- # bottom verts for this iteration
- bfl = (x, y, z)
- bfr = (x + cur_size, y, z)
- bbl = (x, y + cur_size, z)
- bbr = (x + cur_size, y + cur_size, z)
-
- # top verts for this iteration.
- tfl = (x, y, z + step_height)
- tfr = (x + cur_size, y, z + step_height)
- tbl = (x, y + cur_size, z + step_height)
- tbr = (x + cur_size, y + cur_size, z + step_height)
-
- # add to the vert buffer
- vert_list.extend((bfl, bfr, bbl, bbr, tfl, tfr, tbl, tbr,))
+def create_step(width, base_level, step_height, num_sides):
+
+ axis = [0,0,-1]
+ PI2 = pi * 2
+ rad = width / 2
+
+ quat_angles = [(cur_side/num_sides) * PI2
+ for cur_side in range(num_sides)]
+
+ quaternions = [Quaternion(axis, quat_angle)
+ for quat_angle in quat_angles]
+
+ init_vectors = [Vector([rad, 0, base_level])
+ for quat in quaternions]
+
+ quat_vector_pairs = list(zip(quaternions, init_vectors))
+ vectors = [quaternion * vec for quaternion, vec in quat_vector_pairs]
+ bottom_list = [(vec.x, vec.y, vec.z) for vec in vectors]
+ top_list = [(vec.x, vec.y, vec.z+step_height) for vec in vectors]
+ full_list = bottom_list + top_list
+ return full_list
+
+
+def split_list(l, n):
+ """
+ split the blocks up. Credit to oremj for this one.
+ http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python
+ """
+ n *= 2
+ returned_list = [l[i:i+n] for i in range(0, len(l), n)]
+ return returned_list
+
- # side faces
- face_list.extend((
- (voffset + 4, voffset + 5, voffset + 1, voffset + 0), # back
- (voffset + 6, voffset + 7, voffset + 3, voffset + 2), # front
- (voffset + 2, voffset + 6, voffset + 4, voffset + 0), # left
- (voffset + 3, voffset + 7, voffset + 5, voffset + 1), # right
- ))
-
- # horizontal connecting faces ( note: n/a for the first iteration ).
- if voffset > 0:
- face_list.extend((
- (voffset - 4, voffset - 3, voffset + 1, voffset + 0), # connector front
- (voffset - 2, voffset - 1, voffset + 3, voffset + 2), # back
- (voffset - 4, voffset - 2, voffset + 2, voffset + 0), # left
- (voffset - 3, voffset - 1, voffset + 3, voffset + 1), # right
- ))
-
- # set up parameters for the next iteration
- cur_size = cur_size - (step_width * 2)
- x = x + step_width
- y = y + step_width
- z = z + step_height
- sn = sn + 1
- voffset = voffset + 8
-
- voffset = voffset - 8 # remove extra voffset done on final iteration
- face_list.extend((
- (voffset + 6, voffset + 7, voffset + 5, voffset + 4), # cap the top.
- (2, 3, 1, 0), # cap the bottom.
- ))
-
- return vert_list, face_list
+def get_connector_pairs(lst, n_sides):
+ # chop off the verts that get used for the base and top
+ lst = lst[n_sides:]
+ lst = lst[:-n_sides]
+ lst = split_list(lst, n_sides)
+ return lst
def add_pyramid_object(self, context):
- verts, faces = makePyramid(self.initial_size, self.step_height,
- self.step_width, self.number_steps)
- bm = bmesh.new()
- mesh = bpy.data.meshes.new(name="Pyramid")
-
- for vert in verts:
- bm.verts.new(vert)
-
- for face in faces:
- bm.faces.new([bm.verts[i] for i in face])
+ all_verts = []
+
+ height_offset = 0
+ cur_width = self.width
+
+ for i in range(self.num_steps):
+ verts_loc = create_step(cur_width, height_offset, self.height,
+ self.num_sides)
+ height_offset += self.height
+ cur_width -= self.reduce_by
+ all_verts.extend(verts_loc)
+
+ mesh = bpy.data.meshes.new("Pyramid")
+ bm = bmesh.new()
+
+ for v_co in all_verts:
+ bm.verts.new(v_co)
+
+
+ # do the sides.
+ n = self.num_sides
+
+ def add_faces(n, block_vert_sets):
+ for bvs in block_vert_sets:
+ for i in range(self.num_sides-1):
+ bm.faces.new([bvs[i], bvs[i+n], bvs[i+n+1], bvs[i+1]])
+ bm.faces.new([bvs[n-1], bvs[(n*2)-1], bvs[n], bvs[0]])
+
+
+ # get the base and cap faces done.
+ bm.faces.new(bm.verts[0:self.num_sides])
+ bm.faces.new(bm.verts[-self.num_sides:])
+
+ # side faces
+ block_vert_sets = split_list(bm.verts, self.num_sides)
+ add_faces(self.num_sides, block_vert_sets)
+
+ # connector faces between faces and faces of the block above it.
+ connector_pairs = get_connector_pairs(bm.verts, self.num_sides)
+ add_faces(self.num_sides, connector_pairs)
+
+ bm.to_mesh(mesh)
+ mesh.update()
+ res = object_data_add(context, mesh, operator=self)
- bm.to_mesh(mesh)
- mesh.update()
- res = object_data_add(context, mesh, operator=self)
-
class AddPyramid(bpy.types.Operator, AddObjectHelper):
- """Add a Mesh Object"""
+ '''Add a mesh pyramid'''
bl_idname = "mesh.primitive_steppyramid_add"
bl_label = "Pyramid"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
- initial_size = FloatProperty(name="Initial Size", default=2.0,
- min=0.0, max=20.0,
- description="Set the initial size at the pyramid base")
-
- step_height = FloatProperty(name="Step Height", default=0.1,
- min=0.0, max=10.0,
- description="How tall each of the steps will be")
-
- step_width = FloatProperty(name="Step Width", default=0.1,
- min=0.0, max=10.0,
- description="How wide each step will be")
-
- number_steps = IntProperty(name="Number Steps", default=10,
- min=1, max=20,
- description="Total number of steps")
+
+ num_sides = IntProperty(
+ name="Number Sides",
+ description = "How many sides each step will have",
+ min = 3, max = 20, default=4)
+ num_steps = IntProperty(
+ name="Number of Steps",
+ description="How many steps for the overall pyramid",
+ min=1, max=20, default=10)
+
+ width = FloatProperty(
+ name="Initial Width",
+ description="Initial base step width",
+ min=0.01, max=100.0,
+ default=2)
+
+ height = FloatProperty(
+ name="Height",
+ description="How tall each step will be",
+ min=0.01, max=100.0,
+ default=0.1)
+
+ reduce_by = FloatProperty(
+ name="Reduce Step By",
+ description = "How much to reduce each succeeding step by",
+ min=.01, max = 2.0, default= .20)
+
def execute(self, context):
add_pyramid_object(self, context)
@@ -144,17 +166,16 @@ class AddPyramid(bpy.types.Operator, AddObjectHelper):
'''
def menu_func(self, context):
- self.layout.operator(OBJECT_OT_add_pyramid.bl_idname,
- text="Pyramid", icon="PLUGIN")
+ self.layout.operator(AddPyramid.bl_idname, icon='PLUGIN')
def register():
- bpy.utils.register_class(OBJECT_OT_add_pyramid)
+ bpy.utils.register_class(AddPyramid)
bpy.types.INFO_MT_mesh_add.append(menu_func)
def unregister():
- bpy.utils.unregister_class(OBJECT_OT_add_pyramid)
+ bpy.utils.unregister_class(AddPyramid)
bpy.types.INFO_MT_mesh_add.remove(menu_func)
if __name__ == "__main__":