Newer
Older
'''# ##### 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),
"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",
CoDEmanX
committed
"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
CoDEmanX
committed
CoDEmanX
committed
CoDEmanX
committed
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
CoDEmanX
committed
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
CoDEmanX
committed
CoDEmanX
committed
self.sy = -self.hH + self.he + self.R
self.sx = -self.hW + self.hE + self.hd
CoDEmanX
committed
CoDEmanX
committed
CoDEmanX
committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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 []
CoDEmanX
committed
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 = {}
CoDEmanX
committed
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
CoDEmanX
committed
def generate(self):
ar = 1
ac = 1
cells = []
verts = []
faces = []
CoDEmanX
committed
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)
CoDEmanX
committed
# 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]
CoDEmanX
committed
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]])
CoDEmanX
committed
# 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]
CoDEmanX
committed
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]])
CoDEmanX
committed
# right column
row = 0
col = len(cells[row]) - 1
for row in range(1, len(cells) - 1):
cs = 0
if row % 2: cs += 1
CoDEmanX
committed
s = cells[row][col]
l = cells[row][col - 1]
u = cells[row + 1][col - cs]
d = cells[row - 1][col - cs]
CoDEmanX
committed
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]])
CoDEmanX
committed
# 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]])
CoDEmanX
committed
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'}
CoDEmanX
committed
rows = IntProperty(
name = 'Num of rows', default = 2,
min = 1, max = 100,
description='Number of the rows')
CoDEmanX
committed
cols = IntProperty(
name = 'Num of cols', default = 2,
min = 1, max = 100,
description='Number of the columns')
CoDEmanX
committed
def fix_edge(self, context):
m = edge_max(self.diam)
if self.edge > m: self.edge = m
CoDEmanX
committed
diam = FloatProperty(
name = 'Cell Diameter', default = 1.0,
min = 0.0, update = fix_edge,
description='Diameter of the cell')
CoDEmanX
committed
edge = FloatProperty(
name = 'Edge Width', default = 0.1,
min = 0.0, update = fix_edge,
description='Width of the edge')
CoDEmanX
committed
# generic transform props
view_align = BoolProperty(
name="Align to View",
default=False)
location = FloatVectorProperty(
name="Location",
subtype='TRANSLATION')
rotation = FloatVectorProperty(
name="Rotation",
subtype='EULER')
CoDEmanX
committed
##### POLL #####
@classmethod
def poll(cls, context):
return context.scene is not None
CoDEmanX
committed
##### EXECUTE #####
def execute(self, context):
mesh = bpy.data.meshes.new(name='honeycomb')
CoDEmanX
committed
comb = honeycomb_geometry(self.rows, self.cols, self.diam, self.edge)
verts, faces = comb.generate()
CoDEmanX
committed
mesh.from_pydata(vertices = verts, edges = [], faces = faces)
mesh.update()
CoDEmanX
committed
object_utils.object_data_add(context, mesh, operator=self)
CoDEmanX
committed
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__)
CoDEmanX
committed
bpy.types.INFO_MT_mesh_add.append(menu_func)
def unregister():
bpy.utils.unregister_module(__name__)
CoDEmanX
committed
CoDEmanX
committed