Skip to content

Instantly share code, notes, and snippets.

@eyemono-moe
Last active April 29, 2022 07:13
Show Gist options
  • Save eyemono-moe/45d3d8c92ed5bc86878d0bbd86f2f588 to your computer and use it in GitHub Desktop.
Save eyemono-moe/45d3d8c92ed5bc86878d0bbd86f2f588 to your computer and use it in GitHub Desktop.
Script to create an Ico Sphere in Blender.
import bpy
def icosphere(recursion_leve=0):
# create 12 vertices of a icosahedron
t = (1 + 5**0.5)/2
verts = [
[-1, t, 0], [1, t, 0], [-1, -t, 0], [1, -t, 0],
[0, -1, t], [0, 1, t], [0, -1, -t], [0, 1, -t],
[t, 0, -1], [t, 0, 1], [-t, 0, -1], [-t, 0, 1]
]
# create 20 triangles of the icosahedron
faces = [
[0, 1, 7], [0, 5, 1], [0, 7, 10], [0, 10, 11],
[0, 11, 5], [1, 5, 9], [2, 4, 11], [3, 2, 6],
[3, 4, 2], [3, 6, 8], [3, 8, 9], [3, 9, 4],
[4, 9, 5], [5, 11, 4], [6, 2, 10], [7, 1, 8],
[8, 6, 7], [9, 8, 1], [10, 7, 6], [11, 10, 2]
]
# midpoint vertices cache to avoid duplicating shared vertices
mid_cache = {}
def get_mid_point(a, b):
'''return index of vertex in the middle of a and b'''
key = (a+b)*(a+b+1)//2 + min(a, b) # Cantor's pairing function
if(key in mid_cache):
return mid_cache.pop(key)
v_a = verts[a]
v_b = verts[b]
mid = [(v_a[0]+v_b[0])/2, (v_a[1]+v_b[1])/2, (v_a[2]+v_b[2])/2]
verts.append(mid)
i = len(verts)-1
mid_cache.update([(key, i)])
return i
faces_prev = faces
for i in range(recursion_leve):
# subdivide each triangle into 4 triangles
faces = []
for j in range(len(faces_prev)):
v1, v2, v3 = faces_prev[j]
a = get_mid_point(v1, v2)
b = get_mid_point(v2, v3)
c = get_mid_point(v3, v1)
faces.append([v1, a, c])
faces.append([v2, b, a])
faces.append([v3, c, b])
faces.append([a, b, c])
faces_prev = faces
# normalize vertices
for i in range(len(verts)):
x, y, z = verts[i]
length = 1/(x**2+y**2+z**2)**0.5
verts[i] = list(map(lambda p: p*length, verts[i]))
msh = bpy.data.meshes.new("IcosphereMesh") # Meshデータの宣言
msh.from_pydata(verts, [], faces) # 頂点座標と各面の頂点の情報でメッシュを作成
obj = bpy.data.objects.new("Icosphere", msh) # メッシュデータでオブジェクトを作成
bpy.context.scene.collection.objects.link(obj) # シーンにオブジェクトを配置
# delete existing meshs
for item in bpy.data.meshes:
bpy.data.meshes.remove(item)
icosphere(2)
@eyemono-moe
Copy link
Author

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment