Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import bpy
- import bmesh
- import math
- '''
- - Version 1: First release
- - Version 2: Changed from Lattice deform to Mesh Deform due to some strange non linear characteristics
- '''
- clear_first = True # clearing all existing torus objects first
- smoothing = 0 # set to 0 for default torus geometry, set to > 0 for subdivision multiple
- # progressive radii of torus, radius_1 is the minor radius and radius_2 is major radius of first torus
- radius_1 = 0.5
- radius_2 = 2.0
- radius_3 = 8.0
- radius_4 = 32.0
- radius_5 = 128.0
- # pregressive number of sections on each torus (smallest to largest)
- sections_1 = 32
- sections_2 = 32
- sections_3 = 32
- # whether or not to stretch the outer edge of the torus to attempt to fill the parent torus volume (smallest to largest)
- # be awre that using stretch on more than one level will result in non symetric torus on the lower levels.
- stretch_1 = True
- stretch_2 = True
- stretch_3 = True
- level = 4 # level of torus to render up to
- from bpy import context
- import builtins as __builtin__
- def console_print(*args, **kwargs):
- for a in context.screen.areas:
- if a.type == 'CONSOLE':
- c = {}
- c['area'] = a
- c['space_data'] = a.spaces.active
- c['region'] = a.regions[-1]
- c['window'] = context.window
- c['screen'] = context.screen
- s = " ".join([str(arg) for arg in args])
- for line in s.split("\n"):
- bpy.ops.console.scrollback_append(c, text=line)
- def print(*args, **kwargs):
- """Console print() function."""
- console_print(*args, **kwargs) # to py consoles
- __builtin__.print(*args, **kwargs) # to system console
- #bpy.ops.object.mode_set(mode='OBJECT')
- bpy.ops.object.select_all(action='DESELECT')
- if clear_first:
- for obj in bpy.context.scene.objects:
- if obj.name.startswith('Torus'):
- bpy.data.objects.remove(obj, do_unlink = True)
- #bpy.ops.object.select_all(action='SELECT')
- #bpy.ops.object.delete(use_global=False, confirm=False)
- #bpy.ops.mesh.primitive_uv_sphere_add(radius=radius_4, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
- if level > 0:
- # first torus level
- bpy.ops.mesh.primitive_torus_add(align='WORLD', location=(0, 0, 0), rotation=(0, 0, 0), major_radius=radius_2-radius_1, minor_radius=radius_1, abso_major_rad=radius_2, abso_minor_rad=radius_1)
- torus_1 = bpy.context.selected_objects[0]
- if level > 1:
- # second torus level
- bpy.ops.transform.translate(value=(radius_3-radius_2, 0, 0), orient_axis_ortho='X', orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
- bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN')
- bpy.ops.mesh.primitive_uv_sphere_add(radius=1, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
- origin_1 = bpy.context.selected_objects[0]
- bpy.ops.mesh.primitive_cube_add(enter_editmode=False, align='WORLD', location=(radius_3/2, 0, 0), scale=(1,1,1))
- bpy.ops.transform.resize(value=(radius_3/2, radius_2, radius_1), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
- lattice_1 = bpy.context.selected_objects[0]
- # https://blender.stackexchange.com/questions/163855/how-to-subdivide-mesh-with-python-and-blender-2-8
- bm = bmesh.new()
- bm.from_mesh(lattice_1.data)
- #bm = bmesh.from_edit_mesh(lattice_1.data)
- edges_to_split = [edge for edge in bm.edges if edge.verts[0].co.z == -1 * edge.verts[1].co.z]
- bmesh.ops.subdivide_edges(bm, edges=edges_to_split, cuts=1, use_grid_fill=True)
- bm.to_mesh(lattice_1.data)
- bm.free()
- lattice_1.data.update()
- #bmesh.update_edit_mesh(lattice_1.data)
- if smoothing > 0:
- modifier_subd = torus_1.modifiers.new("Subdivision", 'SUBSURF')
- modifier_subd.levels = smoothing
- modifier_latt = torus_1.modifiers.new("MeshDeform", 'MESH_DEFORM')
- modifier_latt.object = lattice_1
- modifier_latt.precision = 3
- bpy.ops.object.select_all(action='DESELECT')
- bpy.context.view_layer.objects.active = torus_1
- torus_1.select_set(True)
- bpy.ops.object.meshdeform_bind(modifier="MeshDeform")
- bm = bmesh.new()
- bm.from_mesh(lattice_1.data)
- for p in bm.verts:
- #print(p.co)
- if p.co.x == -1.0:
- p.co.z = 0.0
- if stretch_1 and p.co.x == 1.0 and p.co.z != 0.0:
- #print(math.cos((2*math.pi)/(sections_1*2)))
- #print(radius_3*math.sin((2*math.pi)/(sections_1*2))/radius_1)
- p.co.x = math.cos((2*math.pi)/(sections_1*2))
- if p.co.z == 1.0:
- p.co.z = radius_3*math.sin((2*math.pi)/(sections_1*2))/radius_1
- if p.co.z == -1.0:
- p.co.z = -radius_3*math.sin((2*math.pi)/(sections_1*2))/radius_1
- bm.to_mesh(lattice_1.data)
- bm.free()
- lattice_1.data.update()
- modifier_arr = torus_1.modifiers.new("Array", 'ARRAY')
- modifier_arr.count = sections_1
- modifier_arr.use_relative_offset = False
- modifier_arr.use_constant_offset = True
- modifier_arr.constant_offset_displace[0] = 0
- modifier_arr.use_object_offset = True
- modifier_arr.offset_object = origin_1
- bpy.ops.object.select_all(action='DESELECT')
- bpy.context.view_layer.objects.active = origin_1
- origin_1.select_set(True)
- bpy.ops.transform.rotate(value=(2*math.pi)/sections_1, orient_axis='Y', orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(False, True, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
- bpy.ops.object.select_all(action='DESELECT')
- context.view_layer.objects.active = torus_1
- torus_1.select_set(True)
- if smoothing > 0:
- bpy.ops.object.modifier_apply(modifier="Subdivision")
- bpy.ops.object.modifier_apply(modifier="MeshDeform")
- bpy.ops.object.modifier_apply(modifier="Array")
- bpy.ops.object.select_all(action='DESELECT')
- context.view_layer.objects.active = lattice_1
- lattice_1.select_set(True)
- origin_1.select_set(True)
- bpy.ops.object.delete(use_global=False, confirm=False)
- if level > 2:
- # third level torus
- bpy.ops.mesh.primitive_uv_sphere_add(radius=1, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
- origin_1 = bpy.context.selected_objects[0]
- bpy.ops.object.select_all(action='DESELECT')
- context.view_layer.objects.active = torus_1
- torus_1.select_set(True)
- bpy.ops.transform.translate(value=(radius_4-radius_3, 0, 0), orient_axis_ortho='X', orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
- bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN')
- bpy.ops.mesh.primitive_cube_add(enter_editmode=False, align='WORLD', location=(radius_4/2, 0, 0), scale=(1,1,1))
- bpy.ops.transform.resize(value=(radius_4/2, radius_2, radius_3), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
- lattice_1 = bpy.context.selected_objects[0]
- # https://blender.stackexchange.com/questions/163855/how-to-subdivide-mesh-with-python-and-blender-2-8
- bm = bmesh.new()
- bm.from_mesh(lattice_1.data)
- #bm = bmesh.from_edit_mesh(lattice_1.data)
- edges_to_split = [edge for edge in bm.edges if edge.verts[0].co.y == -1 * edge.verts[1].co.y]
- bmesh.ops.subdivide_edges(bm, edges=edges_to_split, cuts=1, use_grid_fill=True)
- bm.to_mesh(lattice_1.data)
- bm.free()
- lattice_1.data.update()
- #bmesh.update_edit_mesh(lattice_1.data)
- modifier_latt = torus_1.modifiers.new("MeshDeform", 'MESH_DEFORM')
- modifier_latt.object = lattice_1
- modifier_latt.precision = 3
- bpy.ops.object.select_all(action='DESELECT')
- bpy.context.view_layer.objects.active = torus_1
- torus_1.select_set(True)
- bpy.ops.object.meshdeform_bind(modifier="MeshDeform")
- bm = bmesh.new()
- bm.from_mesh(lattice_1.data)
- for p in bm.verts:
- print(p.co)
- if p.co.x == -1.0:
- p.co.y = 0.0
- if stretch_2 and p.co.x == 1.0 and p.co.y != 0.0:
- #print(math.cos((2*math.pi)/(sections_2*2)))
- #print(radius_4*math.sin((2*math.pi)/(sections_2*2))/radius_2)
- p.co.x = math.cos((2*math.pi)/(sections_2*2))
- if p.co.y == 1.0:
- p.co.y = radius_4*math.sin((2*math.pi)/(sections_2*2))/radius_2
- if p.co.y == -1.0:
- p.co.y = -radius_4*math.sin((2*math.pi)/(sections_2*2))/radius_2
- bm.to_mesh(lattice_1.data)
- bm.free()
- lattice_1.data.update()
- modifier_arr = torus_1.modifiers.new("Array", 'ARRAY')
- modifier_arr.count = sections_2
- modifier_arr.use_relative_offset = False
- modifier_arr.use_constant_offset = True
- modifier_arr.constant_offset_displace[0] = 0
- modifier_arr.use_object_offset = True
- modifier_arr.offset_object = origin_1
- bpy.ops.object.select_all(action='DESELECT')
- bpy.context.view_layer.objects.active = origin_1
- origin_1.select_set(True)
- bpy.ops.transform.rotate(value=(2*math.pi)/sections_2, orient_axis='Y', orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(False, False, True), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
- bpy.ops.object.select_all(action='DESELECT')
- context.view_layer.objects.active = torus_1
- torus_1.select_set(True)
- bpy.ops.object.modifier_apply(modifier="MeshDeform")
- bpy.ops.object.modifier_apply(modifier="Array")
- bpy.ops.object.select_all(action='DESELECT')
- context.view_layer.objects.active = lattice_1
- lattice_1.select_set(True)
- origin_1.select_set(True)
- bpy.ops.object.delete(use_global=False, confirm=False)
- if level > 3:
- # fourth level torus
- bpy.ops.mesh.primitive_uv_sphere_add(radius=1, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
- origin_1 = bpy.context.selected_objects[0]
- bpy.ops.object.select_all(action='DESELECT')
- context.view_layer.objects.active = torus_1
- torus_1.select_set(True)
- bpy.ops.transform.translate(value=(radius_5-radius_4, 0, 0), orient_axis_ortho='X', orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
- bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN')
- bpy.ops.mesh.primitive_cube_add(enter_editmode=False, align='WORLD', location=(radius_5/2, 0, 0), scale=(1,1,1))
- bpy.ops.transform.resize(value=(radius_5/2, radius_4, radius_3), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(True, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
- lattice_1 = bpy.context.selected_objects[0]
- # https://blender.stackexchange.com/questions/163855/how-to-subdivide-mesh-with-python-and-blender-2-8
- bm = bmesh.new()
- bm.from_mesh(lattice_1.data)
- #bm = bmesh.from_edit_mesh(lattice_1.data)
- edges_to_split = [edge for edge in bm.edges if edge.verts[0].co.z == -1 * edge.verts[1].co.z]
- bmesh.ops.subdivide_edges(bm, edges=edges_to_split, cuts=1, use_grid_fill=True)
- bm.to_mesh(lattice_1.data)
- bm.free()
- lattice_1.data.update()
- #bmesh.update_edit_mesh(lattice_1.data)
- modifier_latt = torus_1.modifiers.new("MeshDeform", 'MESH_DEFORM')
- modifier_latt.object = lattice_1
- modifier_latt.precision = 3
- bpy.ops.object.select_all(action='DESELECT')
- bpy.context.view_layer.objects.active = torus_1
- torus_1.select_set(True)
- bpy.ops.object.meshdeform_bind(modifier="MeshDeform")
- bm = bmesh.new()
- bm.from_mesh(lattice_1.data)
- for p in bm.verts:
- #print(p.co)
- if p.co.x == -1.0:
- p.co.z = 0.0
- if stretch_3 and p.co.x == 1.0 and p.co.z != 0.0:
- #print(math.cos((2*math.pi)/(sections_3*2)))
- #print(radius_5*math.sin((2*math.pi)/(sections_3*2))/radius_3)
- p.co.x = math.cos((2*math.pi)/(sections_3*2))
- if p.co.z == 1.0:
- p.co.z = radius_5*math.sin((2*math.pi)/(sections_3*2))/radius_3
- if p.co.z == -1.0:
- p.co.z = -radius_5*math.sin((2*math.pi)/(sections_3*2))/radius_3
- bm.to_mesh(lattice_1.data)
- bm.free()
- lattice_1.data.update()
- modifier_arr = torus_1.modifiers.new("Array", 'ARRAY')
- modifier_arr.count = sections_3
- modifier_arr.use_relative_offset = False
- modifier_arr.use_constant_offset = True
- modifier_arr.constant_offset_displace[0] = 0
- modifier_arr.use_object_offset = True
- modifier_arr.offset_object = origin_1
- bpy.ops.object.select_all(action='DESELECT')
- bpy.context.view_layer.objects.active = origin_1
- origin_1.select_set(True)
- bpy.ops.transform.rotate(value=(2*math.pi)/sections_3, orient_axis='Y', orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', constraint_axis=(False, True, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
- bpy.ops.object.select_all(action='DESELECT')
- context.view_layer.objects.active = torus_1
- torus_1.select_set(True)
- bpy.ops.object.modifier_apply(modifier="MeshDeform")
- bpy.ops.object.modifier_apply(modifier="Array")
- bpy.ops.object.select_all(action='DESELECT')
- context.view_layer.objects.active = lattice_1
- lattice_1.select_set(True)
- origin_1.select_set(True)
- bpy.ops.object.delete(use_global=False, confirm=False)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement