diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py index feca76124e4b46b63a80026b89432581c7d19c78..fcb02a5611a2bd9de94d9bfc15c7e57b7694ef46 100644 --- a/add_mesh_extra_objects/__init__.py +++ b/add_mesh_extra_objects/__init__.py @@ -17,6 +17,7 @@ # ##### END GPL LICENSE BLOCK ##### # Contributed to by # Pontiac, Fourmadmen, varkenvarken, tuga3d, meta-androcto, metalliandy, dreampainter & cotejrp1# +# Kayo Phoenix, Anthony D'Agostino# bl_info = { "name": "Extra Objects", @@ -43,6 +44,8 @@ if "bpy" in locals(): imp.reload(add_mesh_polysphere) imp.reload(add_mesh_supertoroid) imp.reload(add_mesh_pyramid) + imp.reload(add_mesh_torusknot) + imp.reload(add_mesh_honeycomb) else: from . import add_mesh_extra_objects from . import add_mesh_twisted_torus @@ -52,6 +55,8 @@ else: from . import add_mesh_polysphere from . import add_mesh_supertoroid from . import add_mesh_pyramid + from . import add_mesh_torusknot + from . import add_mesh_honeycomb import bpy @@ -68,8 +73,7 @@ class INFO_MT_mesh_extras_add(bpy.types.Menu): layout.menu("INFO_MT_mesh_math_add", text="Math Function") layout.menu("INFO_MT_mesh_basic_add", text="Basic Objects") layout.menu("INFO_MT_mesh_torus_add", text="Torus Objects") - layout.operator("mesh.primitive_steppyramid_add", - text="Step Pyramid") + layout.menu("INFO_MT_mesh_misc_add", text="Misc Objects") class INFO_MT_mesh_gemstones_add(bpy.types.Menu): # Define the "Gemstones" menu @@ -141,7 +145,21 @@ class INFO_MT_mesh_torus_add(bpy.types.Menu): text="Twisted Torus") layout.operator("mesh.primitive_supertoroid_add", text="Supertoroid") + layout.operator("mesh.primitive_torusknot_add", + text="Torus Knot") +class INFO_MT_mesh_misc_add(bpy.types.Menu): + # Define the "Simple Objects" menu + bl_idname = "INFO_MT_mesh_misc_add" + bl_label = "Misc Objects" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("mesh.primitive_steppyramid_add", + text="Step Pyramid") + layout.operator("mesh.honeycomb_add", + text="Honeycomb") # Register all operators and panels # Define "Extras" menu diff --git a/add_mesh_extra_objects/add_mesh_honeycomb.py b/add_mesh_extra_objects/add_mesh_honeycomb.py new file mode 100644 index 0000000000000000000000000000000000000000..ad2ee3d7a2ef1e138e497fcc404d5eebe0eb76b3 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_honeycomb.py @@ -0,0 +1,284 @@ +'''# ##### 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_info = { + "name": "HoneyComb", + "author": "Kayo Phoenix <kayo@illumium.org>", + "version": (0, 1), + "blender": (2, 5, 7), + "api": 35853, + "location": "View3D > Add > Mesh > HoneyComb", + "description": "Adds HoneyComb Mesh", + "warning": "", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_Mesh/HoneyComb", + "category": "Add Mesh" + } +''' +from math import pi, sin, cos + +class honeycomb_geometry(): + def __init__(self, rows, cols, D, E): + self.rows = rows + self.cols = cols + self.D = D + self.E = E + + self.hE = 0.5 * self.E + self.R = 0.5 * self.D + + self.a = sin(pi / 3) + + self.d = self.a * self.D + self.hd = 0.5 * self.d + self.e = self.hE / self.a + self.he = 0.5 * self.e + self.r = self.R - self.e + self.hr = 0.5 * self.r + + + self.H = self.R * (1.5 * self.rows + 0.5) + self.e + if self.rows > 1: + self.W = self.d * (self.cols + 0.5) + self.E + else: + self.W = self.d * self.cols + self.E + + self.hH = 0.5 * self.H + self.hW = 0.5 * self.W + + self.sy = -self.hH + self.he + self.R + self.sx = -self.hW + self.hE + self.hd + + self.gx = self.hd + + self.dy = 1.5 * self.R + self.dx = self.d + + def vert(self, row, col): + # full cell + if row >= 0 and row < self.rows and col >= 0 and col < self.cols: return [0, 1, 2, 3, 4, 5] + # right down corner + if row == -1 and col == self.cols - 1: return [1, 2] + if row == 0 and self.rows > 1 and col == self.cols: return [1, 2, 3] + # left down corner + if row == -1 and col == -1: return [0, 1] + if self.rows % 2: + # left up corner + if row == self.rows and col == -1: return [4, 5] + # right up corner + if row == self.rows and col == self.cols - 1: return [3, 4] + if row == self.rows - 1 and self.rows > 1 and col == self.cols: return [2, 3, 4] + else: + # left up corner + if row == self.rows and col == 0: return [4, 5] + if row == self.rows - 1 and self.rows > 1 and col == -1: return [0, 4, 5] + # right up corner + if row == self.rows and col == self.cols: return [3, 4] + # horizontal lines + if col >= 0 and col < self.cols: + if row == -1: return [0, 1, 2] + if row == self.rows: return [3, 4, 5] + # vertical lines + if row >= 0 and row < self.rows: + if col == -1: + if row % 2: return [0, 1, 4, 5] + else: return [0, 5] + if col == self.cols: + if row % 2 or self.rows == 1: return [2, 3] + else: return [1, 2, 3, 4] + return [] + + def cell(self, row, col, idx): + cp = [self.sx + self.dx * col, self.sy + self.dy * row, 0] # central point + if row % 2: cp[0] += self.gx + co = [] # vertexes coords + vi = self.vert(row, col) + ap = {} + + for i in vi: + a = pi / 6 + i * pi / 3 # angle + ap[i] = idx + len(co) + co.append((cp[0] + cos(a) * self.r, cp[1] + sin(a) * self.r, cp[2])) + return co, ap + + def generate(self): + ar = 1 + ac = 1 + + cells = [] + verts = [] + faces = [] + + for row in range(-ar, self.rows + ar): + level = [] + for col in range(-ac, self.cols + ac): + co, ap = self.cell(row, col, len(verts)) + verts += co + level.append(ap) + cells.append(level) + + # bottom row + row = 0 + for col in range(1, len(cells[row]) - 1): + s = cells[row][col] + l = cells[row][col - 1] + u = cells[row + 1][col] + + faces.append((s[1], u[5], u[4], s[2])) + faces.append((s[2], u[4], l[0])) + + # top row + row = len(cells) - 1 + cs = 0 + if row % 2: cs += 1 + for col in range(1 + cs, len(cells[row]) - 1): + s = cells[row][col] + l = cells[row][col - 1] + d = cells[row - 1][col - cs] + faces.append((s[3], l[5], d[1])) + faces.append([s[3], d[1], d[0], s[4]]) + + # middle rows + for row in range(1, len(cells) - 1): + cs = 0 + if row % 2: cs += 1 + for col in range(1, len(cells[row]) - 1): + s = cells[row][col] + l = cells[row][col - 1] + u = cells[row + 1][col - cs] + d = cells[row - 1][col - cs] + + faces.append((s[1], u[5], u[4], s[2])) + faces.append((s[2], u[4], l[0])) + faces.append([s[2], l[0], l[5], s[3]]) + faces.append((s[3], l[5], d[1])) + faces.append([s[3], d[1], d[0], s[4]]) + + # right column + row = 0 + col = len(cells[row]) - 1 + for row in range(1, len(cells) - 1): + cs = 0 + if row % 2: cs += 1 + + s = cells[row][col] + l = cells[row][col - 1] + u = cells[row + 1][col - cs] + d = cells[row - 1][col - cs] + + if row % 2 and row < len(cells) - 2: + faces.append((s[1], u[5], u[4], s[2])) + faces.append((s[2], u[4], l[0])) + faces.append([s[2], l[0], l[5], s[3]]) + faces.append((s[3], l[5], d[1])) + if row % 2 and row > 1: + faces.append([s[3], d[1], d[0], s[4]]) + + # final fix + if not self.rows % 2: + row = len(cells) - 1 + s = cells[row][col] + l = cells[row][col - 1] + d = cells[row - 1][col - 1] + faces.append((s[3], l[5], d[1])) + faces.append([s[3], d[1], d[0], s[4]]) + + return verts, faces + +import bpy +from bpy.props import * +from bpy_extras import object_utils + +def edge_max(diam): + return diam * sin(pi / 3) + +class add_mesh_honeycomb(bpy.types.Operator): + '''Simple honeycomb mesh generator''' + bl_idname = 'mesh.honeycomb_add' + bl_label = 'Add HoneyComb' + bl_options = {'REGISTER', 'UNDO'} + + rows = IntProperty( + name = 'Num of rows', default = 2, + min = 1, max = 100, + description='Number of the rows') + + cols = IntProperty( + name = 'Num of cols', default = 2, + min = 1, max = 100, + description='Number of the columns') + + def fix_edge(self, context): + m = edge_max(self.diam) + if self.edge > m: self.edge = m + + diam = FloatProperty( + name = 'Cell Diameter', default = 1.0, + min = 0.0, update = fix_edge, + description='Diameter of the cell') + + edge = FloatProperty( + name = 'Edge Width', default = 0.1, + min = 0.0, update = fix_edge, + description='Width of the edge') + + # generic transform props + view_align = BoolProperty( + name="Align to View", + default=False) + location = FloatVectorProperty( + name="Location", + subtype='TRANSLATION') + rotation = FloatVectorProperty( + name="Rotation", + subtype='EULER') + + ##### POLL ##### + @classmethod + def poll(cls, context): + return context.scene is not None + + ##### EXECUTE ##### + def execute(self, context): + mesh = bpy.data.meshes.new(name='honeycomb') + + comb = honeycomb_geometry(self.rows, self.cols, self.diam, self.edge) + verts, faces = comb.generate() + + mesh.from_pydata(vertices = verts, edges = [], faces = faces) + mesh.update() + + object_utils.object_data_add(context, mesh, operator=self) + + return {'FINISHED'} +''' +def menu_func(self, context): + self.layout.operator(add_mesh_honeycomb.bl_idname, text = bl_info['name'], icon="PLUGIN") + +def register(): + bpy.utils.register_module(__name__) + + bpy.types.INFO_MT_mesh_add.append(menu_func) + +def unregister(): + bpy.utils.unregister_module(__name__) + + bpy.types.INFO_MT_mesh_add.remove(menu_func) + +if __name__ == "__main__": + register() +''' \ No newline at end of file diff --git a/add_mesh_extra_objects/add_mesh_torusknot.py b/add_mesh_extra_objects/add_mesh_torusknot.py new file mode 100644 index 0000000000000000000000000000000000000000..15f91f53a78867117480e380ed488c02bc66d677 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_torusknot.py @@ -0,0 +1,150 @@ +'''# +---------------------------------------------------------+ +# | Copyright (c) 2005-2010 Anthony D'Agostino | +# | http://home.comcast.net/~chronosphere | +# | scorpius@netzero.com | +# | February 12, 2005 | +# | Torus Knot Generator | +# | Adds the famous missing primitive to Blender | +# +---------------------------------------------------------+ + +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ***** END GPL LICENCE BLOCK ***** + +bl_info = { + "name": "Torus Knot", + "author": "Anthony D'Agostino", + "version": (1, 0), + "blender": (2, 5, 7), + "location": "View3D > Add > Mesh ", + "url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_TorusKnot", + "category": "Add Mesh"} +''' +import bpy, mathutils, math + +def create_mesh_object(context, verts, edges, faces, name): + # 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() + from bpy_extras import object_utils + return object_utils.object_data_add(context, mesh, operator=None) + +# ======================== +# === Torus Knot Block === +# ======================== +def k1(t): + x = math.cos(t) - 2*math.cos(2*t) + y = math.sin(t) + 2*math.sin(2*t) + z = math.sin(3*t) + return mathutils.Vector([x,y,z]) + +def k2(t): + x = 10 * (math.cos(t) + math.cos(3*t)) + math.cos(2*t) + math.cos(4*t) + y = 6 * math.sin(t) + 10 * math.sin(3*t) + z = 4 * math.sin(3*t) * math.sin(5*t/2) + 4*math.sin(4*t) - 2*math.sin(6*t) + return mathutils.Vector([x,y,z]) * 0.2 + +def k3(t): + x = 2.5*math.cos(t+math.pi)/3 + 2*math.cos(3*t) + y = 2.5*math.sin(t)/3 + 2*math.sin(3*t) + z = 1.5*math.sin(4*t) + math.sin(2*t)/3 + return mathutils.Vector([x,y,z]) + +def make_verts(ures, vres, r2, knotfunc): + verts = [] + for i in range(ures): + t1 = (i+0) * 2*math.pi/ures + t2 = (i+1) * 2*math.pi/ures + a = knotfunc(t1) # curr point + b = knotfunc(t2) # next point + a,b = map(mathutils.Vector, (a,b)) + e = a-b + f = a+b + g = e.cross(f) + h = e.cross(g) + g.normalize() + h.normalize() + for j in range(vres): + k = j * 2*math.pi/vres + l = (math.cos(k),0.0,math.sin(k)) + l = mathutils.Vector(l) + m = l * r2 + x,y,z = m + n = h*x + o = g*z + p = n+o + q = a+p + verts.append(q) + return verts + +def make_faces(ures, vres): + faces = [] + for u in range(0, ures): + for v in range(0, vres): + p1 = v + u*vres + p2 = v + ((u+1)%ures)*vres + p4 = (v+1)%vres + u*vres + p3 = (v+1)%vres + ((u+1)%ures)*vres + faces.append([p4, p3, p2, p1]) + return faces + +def make_knot(knotidx, ures): + knots = [k1,k2,k3] + knotfunc = knots[knotidx-1] + vres = ures//10 + r2 = 0.5 + verts = make_verts(ures, vres, r2, knotfunc) + faces = make_faces(ures, vres) + return (verts, faces) + +class AddTorusKnot(bpy.types.Operator): + '''Add a torus-knot mesh.''' + bl_idname = "mesh.primitive_torusknot_add" + bl_label = "Add Torus Knot" + bl_options = {"REGISTER", "UNDO"} + + resolution = bpy.props.IntProperty(name="Resolution", + description="Resolution of the Torus Knot", + default=80, min=30, max=256) + + objecttype = bpy.props.IntProperty(name="Knot Type", + description="Type of Knot", + default=1, min=1, max=3) + + def execute(self, context): + verts, faces = make_knot(self.objecttype, + self.resolution) + obj = create_mesh_object(context, verts, [], faces, "Torus Knot") + return {"FINISHED"} +''' +def menu_func(self, context): + self.layout.operator(AddTorusKnot.bl_idname, text="Torus Knot", icon="MESH_CUBE") + +def register(): + bpy.utils.register_module(__name__) + bpy.types.INFO_MT_mesh_add.append(menu_func) + +def unregister(): + bpy.utils.unregister_module(__name__) + bpy.types.INFO_MT_mesh_add.remove(menu_func) + +if __name__ == "__main__": + register() +''' \ No newline at end of file