Instantly share code, notes, and snippets.

eyemono-moe/icosphere.py

Last active April 29, 2022 07:13
Show Gist options
• Save eyemono-moe/45d3d8c92ed5bc86878d0bbd86f2f588 to your computer and use it in GitHub Desktop.
Script to create an Ico Sphere in Blender.
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 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 commented Sep 23, 2021

I refer to the following sites.