Last active
December 23, 2015 11:11
-
-
Save zeffii/55a6c8437602b2999e37 to your computer and use it in GitHub Desktop.
cylinder grid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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