Skip to content

Instantly share code, notes, and snippets.

@pgtwitter
Last active September 28, 2025 08:09
Show Gist options
  • Save pgtwitter/e697df75c73cc5e257b83cbf3c82de54 to your computer and use it in GitHub Desktop.
Save pgtwitter/e697df75c73cc5e257b83cbf3c82de54 to your computer and use it in GitHub Desktop.
五角形の平面充填された影を作るオブジェクトを生成するbpyコード (タイルタイプ1,3,5,7,9,11,13,15のみ) (タイル参考情報 https://tilingpackingcovering.web.fc2.com/abstract.html
import bpy
import bmesh
from mathutils import Vector
import math
# タイル参考情報 https://tilingpackingcovering.web.fc2.com/abstract.html
# code by Grok ここから
def reflect_points(points, idx1, idx2):
"""
点のリストを、指定した2点(インデックスで指定)を結ぶ直線で線対称変換する。
points: 座標リスト [(x1, y1), (x2, y2), ...]
idx1, idx2: 対称軸を定義する2点のインデックス
戻り値: 変換後の座標リスト
"""
# 対称軸の2点
x1, y1 = points[idx1]
x2, y2 = points[idx2]
# 対称軸が同一点の場合、エラー回避のため元の点を返す
if abs(x1 - x2) < 1e-6 and abs(y1 - y2) < 1e-6:
return points[:]
new_points = []
for x, y in points:
# 対称軸の直線の方程式 ax + by + c = 0 を求める
# 直線は点 (x1, y1), (x2, y2) を通る
if abs(x2 - x1) < 1e-6: # 垂直な直線(x = x1)
# 鏡像点: (x, y) -> (2*x1 - x, y)
x_new = 2 * x1 - x
y_new = y
else:
# 直線の傾き m と切片 c
m = (y2 - y1) / (x2 - x1)
c = y1 - m * x1
# 点 (x, y) から直線への垂線の交点 (xp, yp)
# 直線 ax + by + c = 0 の場合、a = m, b = -1, c = c
# 交点計算: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
denom = m**2 + 1
xp = (x + m * y - m * c) / denom
yp = (m * (x + m * y) + c) / denom
# 鏡像点: (x, y) -> (2*xp - x, 2*yp - y)
x_new = 2 * xp - x
y_new = 2 * yp - y
new_points.append((x_new, y_new))
return new_points
def rotate_points(points, theta_degrees, center=(0, 0)):
"""
点のリストを指定した角度(度)で回転させる。
points: 座標リスト [(x1, y1), (x2, y2), ...]
theta_degrees: 回転角度(度)
center: 回転中心(デフォルトは原点 (0, 0))
"""
theta = math.radians(theta_degrees)
cos_theta = math.cos(theta)
sin_theta = math.sin(theta)
new_points = []
for x, y in points:
x -= center[0]
y -= center[1]
x_new = x * cos_theta - y * sin_theta
y_new = x * sin_theta + y * cos_theta
x_new += center[0]
y_new += center[1]
new_points.append((x_new, y_new))
return new_points
def translate_points(points, tx, ty):
"""
点のリストを指定した量だけ平行移動させる。
points: 座標リスト [(x1, y1), (x2, y2), ...]
tx, ty: X方向、Y方向の移動量
"""
return [(x + tx, y + ty) for x, y in points]
def merge_graphs(graphs, threshold=1e-6):
"""
複数のグラフを一括で統合し、重なった頂点と辺をまとめた新しいグラフを返す。
graphs: グラフのリスト [(points1, edges1), (points2, edges2), ...]
threshold: 頂点が重なる判定の閾値
戻り値: (統合後のポイントリスト, 統合後の辺リスト)
"""
# 全ての頂点を収集(グラフID、頂点インデックス、座標)
vertices = []
for graph_idx, (points, _) in enumerate(graphs):
for point_idx, pos in enumerate(points):
vertices.append((graph_idx, point_idx, pos))
# 頂点を座標でグループ化(重なり判定)
vertex_groups = []
used = set()
for i, (graph_idx1, point_idx1, pos1) in enumerate(vertices):
if i in used:
continue
group = [(graph_idx1, point_idx1, pos1)]
for j, (graph_idx2, point_idx2, pos2) in enumerate(vertices[i+1:], i+1):
if j not in used:
dx = pos1[0] - pos2[0]
dy = pos1[1] - pos2[1]
if math.sqrt(dx*dx + dy*dy) < threshold:
group.append((graph_idx2, point_idx2, pos2))
used.add(j)
vertex_groups.append(group)
used.add(i)
# 新しい頂点リストを作成
new_points = [group[0][2] for group in vertex_groups] # 代表座標
# 辺を統合
node_map = {} # (graph_idx, point_idx) -> new_idx
for new_idx, group in enumerate(vertex_groups):
for graph_idx, point_idx, _ in group:
node_map[(graph_idx, point_idx)] = new_idx
new_edges = set()
for graph_idx, (_, edges) in enumerate(graphs):
for u, v in edges:
new_u = node_map.get((graph_idx, u))
new_v = node_map.get((graph_idx, v))
if new_u is not None and new_v is not None:
new_edges.add(tuple(sorted((new_u, new_v))))
return new_points, list(new_edges)
def project_to_sphere(x_Q, y_Q, R=1.0):
denom = x_Q * x_Q + y_Q * y_Q + 4 * R * R
x_P = 4 * R * R * x_Q / denom
y_P = 4 * R * R * y_Q / denom
z_P = R * (x_Q * x_Q + y_Q * y_Q - 4 * R * R) / denom
return Vector((x_P, y_P, z_P)), z_P
# code by Grok ここまで
def length(p0, p1):
return math.sqrt((p0[0]-p1[0])**2+(p0[1]-p1[1])**2)
def centering(points):
# 中心に移動
max_x, max_y = map(max, zip(*points))
min_x, min_y = map(min, zip(*points))
tx = -(max_x + min_x) / 2.0
ty = -(max_y + min_y) / 2.0
result_points = translate_points(points, tx, ty)
return result_points
def sub_p1_from_p0(p0, p1):
return [p1[0]-p0[0], p1[1]-p0[1]]
def square():
points = [
(0, 0), # A
(1, 0), # B
(1, 1), # C
(0, 1), # D
]
edges = [(0, 1), (1, 2), (2, 3), (3, 0)]
points_new = [p for p in points]
edges_new = [e for e in edges]
v0 = sub_p1_from_p0(points_new[3], points_new[2])
v1 = sub_p1_from_p0(points_new[3], points_new[0])
scale = 0.25
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 22, 22, 0
def hexagon():
c30 = math.cos(math.radians(30))
s30 = math.sin(math.radians(30))
points = [
(0, 0), # A
(c30, s30), # B
(c30, s30+1), # C
(0, 2*s30+1), # D
(-c30, s30+1), # E
(-c30, s30), # F
]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 0)]
points_new = [p for p in points]
edges_new = [e for e in edges]
v0 = sub_p1_from_p0(points_new[4], points_new[2])
v1 = sub_p1_from_p0(points_new[4], points_new[0])
scale = 0.4
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 22, 18, 0
def circle():
n = 36
delta = 2 * math.pi / n
c30 = math.cos(math.radians(30))
s30 = math.sin(math.radians(30))
points = [(math.cos(delta*i), math.sin(delta*i)) for i in range(n)]
edges = [(i, i+1) for i in range(n-1)]
edges.append((n-1, 0))
points_new = [p for p in points]
edges_new = [e for e in edges]
v0, v1 = (2*c30, 2*s30), (-2*c30, 2*s30)
scale = 0.35
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 18, 22, math.pi/6
def type1():
rt3 = math.sqrt(3)
alpha = 4/3 * rt3
# タイルを作成
points = [
(0, 0), # A
(1, rt3), # B
(0, alpha), # C
(-2, alpha), # D
(-1, 0) # E
]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
# 回転と平行移動を適用
points_rotated = rotate_points(points, 180, center=(0, 0))
points_transformed = translate_points(points_rotated, 1, rt3)
# グラフを統合
points_new, edges_new = merge_graphs([(points, edges), (points_transformed, edges)])
v0 = sub_p1_from_p0(points_new[3], points_new[7])
v1 = sub_p1_from_p0(points_new[1], points_new[5])
scale = 0.2
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 8, 26, 0
def type3():
c30 = math.cos(math.radians(30))
s30 = math.sin(math.radians(30))
cAlpha = math.cos(math.radians(79.5-30))
sAlpha = math.sin(math.radians(79.5-30))
cBeta = math.cos(math.radians(79.5-30+120))
sBeta = math.sin(math.radians(79.5-30+120))
# タイルを作成
points = [
(0, 0), # A
(c30, s30), # B
(c30-0.75*cAlpha, s30+0.75*sAlpha), # C
(c30-0.75*cAlpha+1.14*cBeta, s30+0.75*sAlpha-1.14*sBeta), # D
(-c30, s30) # E
]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
points = [(x, -y) for x, y in points]
points_reflect = rotate_points(points, 120, (0, 0))
points_new, edges_new = merge_graphs([(points, edges), (points_reflect, edges)])
points_reflect2 = rotate_points(points, 240, (0, 0))
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_reflect2, edges)])
v0 = sub_p1_from_p0(points_reflect[2], points[2])
v1 = sub_p1_from_p0(points_reflect2[2], points[2])
scale = 0.4
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 20, 20, math.pi/6
def type5():
c30 = math.cos(math.radians(30))
s30 = math.sin(math.radians(30))
c75 = math.cos(math.radians(75))
s75 = math.sin(math.radians(75))
c15 = math.cos(math.radians(15))
s15 = math.sin(math.radians(15))
points = [
(0, 0), # A
(c30, s30), # B
(c30+2*c75, s30+2*s75), # C
(c30+2*c75-2*c15, s30+2*s75-2*s15), # D
(-c30, s30) # E
]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
points_new = [p for p in points]
edges_new = [e for e in edges]
for i in range(5):
points_rotate = rotate_points(points, 60*(i+1), points[2])
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_rotate, edges_new)])
v0 = sub_p1_from_p0(points_new[18], points_new[6])
v1 = sub_p1_from_p0(points_new[16], points_new[1])
scale = 0.2
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 16, 16, math.pi/6
def type7():
c45 = math.cos(math.radians(45))
s45 = math.sin(math.radians(45))
c135 = math.cos(math.radians(135))
s135 = math.sin(math.radians(135))
points = [
(0, 0), # A
(1, 0), # B
(1+c45, s45), # C
(1+c45-c45, s45+s45), # D
(c135, s135) # E
]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
points_new = [p for p in points]
edges_new = [e for e in edges]
points_reflect = reflect_points(points, 3, 4)
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_reflect, edges)])
points_rotate = rotate_points(points_new, 180+45, points_new[2])
t = sub_p1_from_p0(points_rotate[0], points_new[2])
points_transformed = translate_points(points_rotate, t[0], t[1])
points_new2, edges_new2 = merge_graphs([(points_new, edges_new), (points_transformed, edges_new)])
points_rotate1 = rotate_points(points_new, 45, points_new[2])
t = sub_p1_from_p0(points_rotate1[2], points_new[1])
points_transformed1 = translate_points(points_rotate1, t[0], t[1])
points_new3, edges_new3 = merge_graphs([(points_new2, edges_new2), (points_transformed1, edges_new)])
points_rotate2 = rotate_points(points_new, 180, points_new[2])
t = sub_p1_from_p0(points_rotate2[2], points_new3[14])
points_transformed2 = translate_points(points_rotate2, t[0], t[1])
points_new, edges_new = merge_graphs([(points_new3, edges_new3), (points_transformed2, edges_new)], 0.1)
v0 = sub_p1_from_p0(points_new[3], points_new[16])
v1 = sub_p1_from_p0(points_new[6], points_new[12])
scale = 0.2
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 16, 12, math.pi/4
def type9():
a = 127.912
b = 72
alpha = 180-a
beta = b-alpha
gamma = 540-((360-a)+(360-b))/2-a-b
cAlpha = math.cos(math.radians(alpha))
sAlpha = math.sin(math.radians(alpha))
cBeta = math.cos(math.radians(beta))
sBeta = math.sin(math.radians(beta))
cGamma = math.cos(math.radians(gamma))
sGamma = math.sin(math.radians(gamma))
points = [
(0, 0), # A
(1, 0), # B
(1+cAlpha, sAlpha), # C
(1+cAlpha-cBeta, sAlpha+sBeta), # D
(cGamma, sGamma) # E
]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
points_new = [p for p in points]
edges_new = [e for e in edges]
points1 = reflect_points(points, 3, 4)
points_new, edges_new = merge_graphs([(points_new, edges_new), (points1, edges)])
t = sub_p1_from_p0(points[1], points_new[4])
points1 = translate_points(points, t[0], t[1])
points_rotate1 = rotate_points(points1, gamma, points1[1])
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_rotate1, edges)])
points2 = reflect_points(points_rotate1, 3, 4)
points_new, edges_new = merge_graphs([(points_new, edges_new), (points2, edges)])
points_rotate2 = rotate_points(points_new, 180, points_new[12])
t = sub_p1_from_p0(points_new[12], points_new[8])
points_transformed = translate_points(points_rotate2, t[0], t[1])
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_transformed, edges_new)])
v0 = sub_p1_from_p0(points_new[3], points_new[15])
v1 = sub_p1_from_p0(points_new[6], points_new[9])
scale = 0.4
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 6, 16, beta/2
def type11():
alpha = 180-150
cAlpha = math.cos(math.radians(alpha))
sAlpha = math.sin(math.radians(alpha))
beta = 60-alpha
cBeta = math.cos(math.radians(beta))
sBeta = math.sin(math.radians(beta))
b = 3*math.sqrt(3)
c = 2
d = 4
points = [
(0, 0), # A
(b, 0), # B
(b+c*cAlpha, c*sAlpha), # C
(b+c*cAlpha-d*cBeta, c*sAlpha+d*sBeta), # D
(0, 1) # E
]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
points_new = [p for p in points]
edges_new = [e for e in edges]
points1 = reflect_points(points, 0, 1)
points_new, edges_new = merge_graphs([(points_new, edges_new), (points1, edges)])
points_rotate = rotate_points(points_new, 60, points_new[3])
t = sub_p1_from_p0(points_rotate[4], points_new[3])
points_transformed = translate_points(points_rotate, t[0], t[1])
points_rotate1 = rotate_points(points_new, 180, points_new[1])
t = sub_p1_from_p0(points_rotate1[1], points_new[2])
points_transformed1 = translate_points(points_rotate1, t[0], t[1])
points_rotate2 = rotate_points(points_transformed1, 60, points_transformed1[3])
t = sub_p1_from_p0(points_rotate2[7], points_new[5])
points_transformed2 = translate_points(points_rotate2, t[0], t[1])
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_transformed, edges_new)])
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_transformed1, edges_new)])
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_transformed2, edges_new)])
v0 = sub_p1_from_p0(points_new[11], points_new[16])
v1 = sub_p1_from_p0(points_new[18], points_new[6])
scale = 0.2
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 10, 10, math.pi/3
def type13():
alpha = 180-110
cAlpha = math.cos(math.radians(alpha))
sAlpha = math.sin(math.radians(alpha))
cBeta = math.cos(math.radians(90-alpha))
sBeta = math.sin(math.radians(90-alpha))
b = 4.15
c = 1.68
points = [
(0, 0), # A
(b, 0), # B
(b+c*cAlpha, c*sAlpha), # C
(b+c*cAlpha-c*cBeta, c*sAlpha+c*sBeta), # D
(0, 1) # E
]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
points_reflect = reflect_points(points, 0, 1)
points, edges = merge_graphs([(points, edges), (points_reflect, edges)])
points_new = [p for p in points]
edges_new = [e for e in edges]
points_reflect2 = reflect_points(points_new, 4, 0)
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_reflect2, edges_new)])
points_rotate = rotate_points(points, -90, (0, 0))
t = sub_p1_from_p0(points_rotate[1], points_new[3])
points_transformed = translate_points(points_rotate, t[0], t[1])
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_transformed, edges_new)])
points_rotate2 = rotate_points(points, 90, (0, 0))
t = sub_p1_from_p0(points_rotate2[1], points_reflect2[6])
points_transformed2 = translate_points(points_rotate2, t[0], t[1])
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_transformed2, edges_new)])
v0 = sub_p1_from_p0(points_new[10], points_new[7])
v1 = sub_p1_from_p0(points_new[15], points_new[20])
scale = .1
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 24, 8, math.pi/4
def type15():
rt2 = math.sqrt(2)
rt3 = math.sqrt(3)
c15 = math.cos(math.pi/12)
s15 = math.sin(math.pi/12)
c30 = math.cos(math.pi/6)
s30 = math.sin(math.pi/6)
points = [
(0, 0), # A
(1, 0), # B
(1+2*c30, 2*s30), # C
(1+c30, 3*s30), # D
(0, 1) # E
]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0)]
points_reflect = reflect_points(points, 1, 2)
points_reflect2 = reflect_points(points_reflect, 3, 4)
points1, edges1 = merge_graphs([(points, edges), (points_reflect, edges)])
points2, edges2 = merge_graphs([(points1, edges1), (points_reflect2, edges)])
points_rotated = rotate_points(points2, 180, center=(0, 0))
points_transformed = translate_points(points_rotated, (1+c30)+(1+2*c30), 2+s30)
points_new, edges_new = merge_graphs([(points2, edges2), (points_transformed, edges2)])
points_reflect3 = reflect_points(points2, 0, 4)
points_transformed1 = translate_points(points_reflect3, (1+rt2*s15)+(1+c30), (rt2*c15)+(3*s30+1+2*c30))
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_transformed1, edges2)])
l = length(points[3], points[4])
points_reflect4 = reflect_points(points2, 0, 1)
points_transformed2 = translate_points(points_reflect4, (-l/rt2)+(1+2*c30), (-l/rt2)+(-2*c30))
points_new, edges_new = merge_graphs([(points_new, edges_new), (points_transformed2, edges2)])
v0 = sub_p1_from_p0(points_new[28], points_new[21])
v1 = sub_p1_from_p0(points_new[23], points_new[33])
scale = .2
points_new = [(x*scale, y*scale) for x, y in points_new]
v = [(x*scale, y*scale) for x, y in [v0, v1]]
return points_new, edges_new, v[0], v[1], 20, 8, 0
def translationalUnits(n):
if n == 1:
return type1()
elif n == 3:
return type3()
elif n == 5:
return type5()
elif n == 7:
return type7()
elif n == 9:
return type9()
elif n == 11:
return type11()
elif n == 13:
return type13()
elif n == 15:
return type15()
elif n == 'square':
return square()
elif n == 'hexagon':
return hexagon()
elif n == 'circle':
return circle()
raise Exception("未実装")
def create_curve(R, t=1):
points_new, edges_new, v0, v1, ny, nx, rz = translationalUnits(t)
graphs = []
for i in range(ny):
for j in range(nx):
x = i * v0[0] + j * v1[0]
y = i * v0[1] + j * v1[1]
graphs.append((translate_points(points_new, x, y), edges_new))
tmp_points, tmp_edges = merge_graphs(graphs)
tmp_points = centering(tmp_points)
vertices = []
edges = []
for po in centering(tmp_points):
P, z_P = project_to_sphere(po[0], po[1], R)
vertices.append(P)
for e in tmp_edges:
edges.append((e[0], e[1]))
mesh = bpy.data.meshes.new("Curves")
obj = bpy.data.objects.new("Curves", mesh)
obj.rotation_euler = (0, 0, rz)
bpy.context.collection.objects.link(obj)
bpy.context.view_layer.objects.active = obj
bm = bmesh.new()
bm_verts = [bm.verts.new(v) for v in vertices]
for i, j in edges:
bm.edges.new((bm_verts[i], bm_verts[j]))
bm.to_mesh(mesh)
bm.free()
bpy.ops.object.convert(target='CURVE')
return obj
def curve2mesh(obj, R):
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.convert(target='CURVE')
bpy.context.view_layer.objects.active = obj
bpy.ops.object.modifier_add(type='NODES')
mod = obj.modifiers.active
bpy.ops.node.new_geometry_node_group_assign()
nodes = mod.node_group.nodes
links = mod.node_group.links
gid = nodes['Group Input']
gout = nodes['Group Output']
ctm = nodes.new(type='GeometryNodeCurveToMesh')
if True:
resample = nodes.new(type='GeometryNodeResampleCurve')
resample.mode = 'LENGTH'
resample.inputs['Length'].default_value = 0.005
links.new(gid.outputs['Geometry'], resample.inputs['Curve'])
setPos = nodes.new(type='GeometryNodeSetPosition')
links.new(resample.outputs['Curve'], setPos.inputs['Geometry'])
pos = nodes.new(type='GeometryNodeInputPosition')
subtract = nodes.new(type='ShaderNodeVectorMath')
subtract.operation = 'SUBTRACT'
subtract.inputs[1].default_value = (0, 0, R)
links.new(pos.outputs['Position'], subtract.inputs[0])
normalize = nodes.new(type='ShaderNodeVectorMath')
normalize.operation = 'NORMALIZE'
links.new(subtract.outputs['Vector'], normalize.inputs['Vector'])
sphere = nodes.new(type='GeometryNodeMeshUVSphere')
raycast = nodes.new(type='GeometryNodeRaycast')
raycast.inputs['Ray Length'].default_value = 100
links.new(sphere.outputs['Mesh'], raycast.inputs['Target Geometry'])
links.new(pos.outputs['Position'], raycast.inputs['Source Position'])
links.new(normalize.outputs['Vector'], raycast.inputs['Ray Direction'])
links.new(raycast.outputs['Is Hit'], setPos.inputs['Selection'])
links.new(raycast.outputs['Hit Position'], setPos.inputs['Position'])
links.new(setPos.outputs['Geometry'], ctm.inputs['Curve'])
else:
links.new(gid.outputs['Geometry'], ctm.inputs['Curve'])
pos2 = nodes.new(type='GeometryNodeInputPosition')
sep = nodes.new(type='ShaderNodeSeparateXYZ')
links.new(pos2.outputs['Position'], sep.inputs['Vector'])
range = nodes.new(type='ShaderNodeMapRange')
range.inputs['From Min'].default_value = -1
range.inputs['From Max'].default_value = 1
range.inputs['To Min'].default_value = 0.01
range.inputs['To Max'].default_value = 0.0001
links.new(sep.outputs['Z'], range.inputs['Value'])
links.new(ctm.outputs['Mesh'], gout.inputs['Geometry'])
links.new(range.outputs['Result'], ctm.inputs['Scale'])
cc = nodes.new(type='GeometryNodeCurvePrimitiveCircle')
cc.inputs['Resolution'].default_value = 8
cc.inputs['Radius'].default_value = 1
links.new(cc.outputs['Curve'], ctm.inputs['Profile Curve'])
return obj
def add_light(R, curves):
bpy.ops.object.light_add(type='SPOT', location=(0, 0, R))
light = bpy.context.object
light.data.energy = 100
light.data.spot_size = math.pi
light.data.spot_blend = 0.0
light.parent = curves
def add_plane(R):
bpy.ops.mesh.primitive_plane_add(size=10, location=(0, 0, -R))
def mod_world_shader():
world = bpy.context.scene.world
nodes = world.node_tree.nodes
links = world.node_tree.links
gout = nodes['World Output']
vs = nodes.new(type='ShaderNodeVolumeScatter')
vs.inputs['Density'].default_value = 0.1
links.new(vs.outputs['Volume'], gout.inputs['Volume'])
def add_camera():
scene = bpy.context.scene
bpy.ops.object.camera_add(location=(0, -8, 0.22), rotation=(math.radians(88), 0, 0))
scene.camera = bpy.context.object
scene.camera.data.lens = 66
scene.render.resolution_x = 1080
scene.render.resolution_y = 1920
def add_camera_top(R):
scene = bpy.context.scene
bpy.ops.object.camera_add(location=(0, 0, 2*R), rotation=(0, 0, 0))
scene.camera = bpy.context.object
scene.camera.data.lens = 15
scene.render.resolution_x = 1080
scene.render.resolution_y = 1920
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
R = 1
tileType = 9 # 'square'
obj = curve2mesh(create_curve(R, tileType), R)
add_light(R, obj)
add_plane(R)
mod_world_shader()
add_camera_top(R)
add_camera()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment