Last active
April 29, 2022 07:13
-
-
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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I refer to the following sites.