FBX: reformat props.
[blender-addons.git] / add_mesh_extra_objects / add_mesh_pyramid.py
blob8ca6850359b0695fc7e138fa8b85a3c7a6e83074
1 # ***** BEGIN GPL LICENSE BLOCK *****
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # ***** END GPL LICENCE BLOCK *****
20 # (c) 2011 Phil Cote (cotejrp1)
21 '''
22 bl_info = {
23 "name": "Mesh Pyramid",
24 "author": "Phil Cote, cotejrp1, (http://www.blenderaddons.com)",
25 "version": (0, 5),
26 "blender": (2, 63, 0),
27 "location": "View3D > Add > Mesh",
28 "description": "Create an egyption-style step pyramid",
29 "warning": "", # used for warning icon and text in addons panel
30 "category": "Add Mesh",
32 '''
34 import bpy
35 import bmesh
36 from bpy.props import FloatProperty, IntProperty
37 from math import pi
38 from mathutils import Quaternion, Vector
39 from bpy_extras.object_utils import AddObjectHelper, object_data_add
42 def create_step(width, base_level, step_height, num_sides):
44 axis = [0,0,-1]
45 PI2 = pi * 2
46 rad = width / 2
48 quat_angles = [(cur_side/num_sides) * PI2
49 for cur_side in range(num_sides)]
51 quaternions = [Quaternion(axis, quat_angle)
52 for quat_angle in quat_angles]
54 init_vectors = [Vector([rad, 0, base_level])] * len(quaternions)
56 quat_vector_pairs = list(zip(quaternions, init_vectors))
57 vectors = [quaternion * vec for quaternion, vec in quat_vector_pairs]
58 bottom_list = [(vec.x, vec.y, vec.z) for vec in vectors]
59 top_list = [(vec.x, vec.y, vec.z+step_height) for vec in vectors]
60 full_list = bottom_list + top_list
61 return full_list
64 def split_list(l, n):
65 """
66 split the blocks up. Credit to oremj for this one.
67 http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python
68 """
69 n *= 2
70 returned_list = [l[i:i+n] for i in range(0, len(l), n)]
71 return returned_list
75 def get_connector_pairs(lst, n_sides):
76 # chop off the verts that get used for the base and top
77 lst = lst[n_sides:]
78 lst = lst[:-n_sides]
79 lst = split_list(lst, n_sides)
80 return lst
82 def add_pyramid_object(self, context):
83 all_verts = []
85 height_offset = 0
86 cur_width = self.width
88 for i in range(self.num_steps):
89 verts_loc = create_step(cur_width, height_offset, self.height,
90 self.num_sides)
91 height_offset += self.height
92 cur_width -= self.reduce_by
93 all_verts.extend(verts_loc)
95 mesh = bpy.data.meshes.new("Pyramid")
96 bm = bmesh.new()
98 for v_co in all_verts:
99 bm.verts.new(v_co)
102 # do the sides.
103 n = self.num_sides
105 def add_faces(n, block_vert_sets):
106 for bvs in block_vert_sets:
107 for i in range(self.num_sides-1):
108 bm.faces.new([bvs[i], bvs[i+n], bvs[i+n+1], bvs[i+1]])
109 bm.faces.new([bvs[n-1], bvs[(n*2)-1], bvs[n], bvs[0]])
112 # get the base and cap faces done.
113 bm.faces.new(bm.verts[0:self.num_sides])
114 bm.faces.new(bm.verts[-self.num_sides:])
116 # side faces
117 block_vert_sets = split_list(bm.verts, self.num_sides)
118 add_faces(self.num_sides, block_vert_sets)
120 # connector faces between faces and faces of the block above it.
121 connector_pairs = get_connector_pairs(bm.verts, self.num_sides)
122 add_faces(self.num_sides, connector_pairs)
124 bm.to_mesh(mesh)
125 mesh.update()
126 res = object_data_add(context, mesh, operator=self)
129 class AddPyramid(bpy.types.Operator, AddObjectHelper):
130 '''Add a mesh pyramid'''
131 bl_idname = "mesh.primitive_steppyramid_add"
132 bl_label = "Pyramid"
133 bl_options = {'REGISTER', 'UNDO', 'PRESET'}
136 num_sides = IntProperty(
137 name="Number Sides",
138 description = "How many sides each step will have",
139 min = 3, max = 20, default=4)
140 num_steps = IntProperty(
141 name="Number of Steps",
142 description="How many steps for the overall pyramid",
143 min=1, max=20, default=10)
145 width = FloatProperty(
146 name="Initial Width",
147 description="Initial base step width",
148 min=0.01, max=100.0,
149 default=2)
151 height = FloatProperty(
152 name="Height",
153 description="How tall each step will be",
154 min=0.01, max=100.0,
155 default=0.1)
157 reduce_by = FloatProperty(
158 name="Reduce Step By",
159 description = "How much to reduce each succeeding step by",
160 min=.01, max = 2.0, default= .20)
163 def execute(self, context):
164 add_pyramid_object(self, context)
165 return {'FINISHED'}
168 def menu_func(self, context):
169 self.layout.operator(AddPyramid.bl_idname, icon='PLUGIN')
172 def register():
173 bpy.utils.register_class(AddPyramid)
174 bpy.types.INFO_MT_mesh_add.append(menu_func)
177 def unregister():
178 bpy.utils.unregister_class(AddPyramid)
179 bpy.types.INFO_MT_mesh_add.remove(menu_func)
181 if __name__ == "__main__":
182 register()