Skip to content

Instantly share code, notes, and snippets.

@zeffii
Last active December 23, 2015 11:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeffii/55a6c8437602b2999e37 to your computer and use it in GitHub Desktop.
Save zeffii/55a6c8437602b2999e37 to your computer and use it in GitHub Desktop.
cylinder grid
import bpy
import bmesh
import mathutils
from mathutils import Euler
def remove_doubles_and_recalc_normals(obj):
bm = bmesh.new() # create an empty BMesh
bm.from_mesh(obj.data) # fill it in from a Mesh
d = 0.0001
bm_verts = bm.verts[:]
bmesh.ops.remove_doubles(bm, verts=bm_verts, dist=d)
bm_faces = bm.faces[:]
bmesh.ops.recalc_face_normals(bm, faces=bm_faces)
bm.to_mesh(obj.data)
bm.free()
def add_empty(name='some_name'):
mt = objects.new(name, None)
scene.objects.link(mt)
scene.update()
return mt
scene = bpy.context.scene
objects = bpy.data.objects
num_verts_cylinder_profile = 4
''' MAKING GRID '''
thickness = 0.01
adj = 0.003 # use to manipulate radius of cylinder
main_object = objects["Suzanne"]
(x,y,z) = main_object.dimensions
xlocation = -x / 2
ylocation = -y / 2
zlocation = -z / 2
# you might arrive at the number of divisions per axis dynamically
# depending on how long each axis-extent is
num_in_y = 8
num_in_x = 10
num_in_z = 12
adjust_x = x / num_in_x
adjust_y = y / num_in_y
adjust_z = z / num_in_z
# make yx , and collector Empty
mt_yx = add_empty(name='YX_empty')
for iy in range(num_in_y+1):
for ix in range(num_in_x+1):
bpy.ops.mesh.primitive_cylinder_add(vertices=num_verts_cylinder_profile)
cylinder = bpy.context.active_object
cylinder.parent = mt_yx
cylinder.dimensions = (thickness + adj, thickness + adj, z)
cylinder.location = (
xlocation + (ix * adjust_x),
ylocation + (iy * adjust_y),
0
)
# make zx
mt_zx = add_empty(name='ZX_empty')
for iz in range(num_in_z+1):
for ix in range(num_in_x+1):
bpy.ops.mesh.primitive_cylinder_add(vertices=num_verts_cylinder_profile)
cylinder = bpy.context.active_object
cylinder.parent = mt_zx
cylinder.dimensions = (thickness - adj, thickness - adj, y)
cylinder.rotation_euler = Euler((1.57, 0, 0), 'XYZ')
cylinder.location = (
xlocation + (ix * adjust_x),
0,
zlocation + (iz * adjust_z)
)
# make zy
mt_zy = add_empty(name='ZY_empty')
for iz in range(num_in_z+1):
for iy in range(num_in_y+1):
bpy.ops.mesh.primitive_cylinder_add(vertices=num_verts_cylinder_profile)
cylinder = bpy.context.active_object
cylinder.parent = mt_zy
cylinder.dimensions = (thickness, thickness, x)
cylinder.rotation_euler = Euler((1.57, 0, 1.57), 'XYZ')
cylinder.location = (
0,
ylocation + (iy * adjust_y),
zlocation + (iz * adjust_z)
)
''' JOINING PARENTED OBJECTS '''
# get the list of empties that have children
empties = [e for e in objects if e.type == 'EMPTY' and e.children]
# we need to deselect everything first
bpy.ops.object.select_all(action='DESELECT')
for empty in empties:
for obj in empty.children:
obj.select = True
joiner = empty.children[0]
scene.objects.active = joiner
bpy.ops.object.join()
# deselect everything before the next iteration
bpy.ops.object.select_all(action='DESELECT')
''' BOOLEAN UNION GRID OBJECTS '''
if True:
# get joined axis-grid objects from remaining empties
# objs = [o.children[0] for o in objects if o.type == 'EMPTY' and o.children]
objs = [o for o in bpy.data.objects if o.name.startswith("Cyl")]
# unparent these objects
for o in objs:
o.parent = None
print(objs)
obj_collector = objs[0]
print('obj_collector', obj_collector)
for obj_to_union in objs[1:]:
print('obj_to_union', obj_to_union)
mod = obj_collector.modifiers.new(name='bool', type='BOOLEAN')
mod.object = obj_to_union
mod.operation = 'UNION'
obj_collector.data = obj_collector.to_mesh(scene, True, 'RENDER')
obj_collector.modifiers.clear()
scene.objects.active = obj_collector
bpy.ops.object.visual_transform_apply()
remove_doubles_and_recalc_normals(obj_collector)
obj_to_union.hide = True
''' DO FINAL BOOLEAN '''
if False:
mod = main_object.modifiers.new(name='final bool', type='BOOLEAN')
mod.operation = 'UNION'
mod.object = obj_collect
main_object.data = obj_collector.to_mesh(scene, True, 'RENDER')
main_object.modifiers.clear()
obj_collect.hide = True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment