参考サイト
上記、サンプルコードを参考に、PythonSCADのGUI版を使って、実行できるように変換しました。
PythonSCADコミュニティ、OpenSCADコミュニティ、開発者、記事執筆者の方々に感謝申し上げます。
ありがとうございます。
1. 完成コード(PythonSCAD)
# ==========================================
# OpenSCAD → PythonSCAD 変換サンプル
# 作成日: 2026/08/13
# ==========================================
from pythonscad import *
# --- パラメータ設定 (単位: mm) ---
cyl_h = 20.0
cyl_r = 8.0
cone_r1 = 10.0
sphere_r = 10.0
cube1_size = 10.0
cube2_size = [8.0, 15.0, 20.0]
fn_tri = 3
fn_smooth = 60
# --- 各パーツ(OpenSCADの配置をそのまま再現:center=False) ---
obj1 = translate(
cylinder(h=cyl_h, r1=cyl_r, r2=cyl_r, center=False, fn=fn_tri),
[-40.0, 0.0, 0.0]
)
obj2 = translate(
cylinder(h=cyl_h, r1=cone_r1, r2=0.0, center=False, fn=fn_smooth),
[-20.0, 0.0, 0.0]
)
obj3 = translate(
sphere(r=sphere_r, fn=fn_smooth),
[0.0, 0.0, 10.0]
)
obj4 = translate(
cube([cube1_size, cube1_size, cube1_size], center=False),
[20.0, 0.0, 0.0]
)
obj5 = translate(
cube(cube2_size, center=False),
[40.0, 0.0, 0.0]
)
result = obj1 + obj2 + obj3 + obj4 + obj5
show(result)
※ OpenSCAD の $fn=3 は PythonSCAD では fn=3 として各形状の引数に入れます($fn=... の単独行はPythonでエラーになるため)。
※ 今回は「OpenSCADと同じ見た目配置」を優先して、center=False のまま変換しています。必要なら「原点中心(center=True)で設計し直す版」も作れます。
2. 完成コード(PythonSCAD)
# ==========================================
# OpenSCAD -> PythonSCAD 変換: 交互に向きが違う直方体列
# 作成日: 2026/08/13
# ==========================================
from pythonscad import *
# --- パラメータ設定 (単位: mm) ---
x_margin = 20.0
cube_even = [10.0, 50.0, 10.0] # i が偶数のとき
cube_odd = [10.0, 10.0, 50.0] # i が奇数のとき
i_min = -10
i_max = 10
# --- 関数(モジュール)定義 ---
def create_piece(i, margin):
"""i番目の直方体(偶数/奇数でサイズ切替)を作ってX方向に配置する"""
size = cube_even if (i % 2 == 0) else cube_odd
part = cube(size, center=True)
return translate(part, [margin * i, 0.0, 0.0])
# --- メイン処理 ---
result = None
for i in range(i_min, i_max + 1):
part = create_piece(i, x_margin)
result = part if result is None else (result + part)
show(result)
3. 完成コード(PythonSCAD)
# ==========================================
# OpenSCAD: ring(), magcup() 変換
# 作成日: 2026/08/13
# ==========================================
from pythonscad import *
# --- パラメータ設定 (単位: mm) ---
fn_val = 80 # 円柱の分割数
eps = 0.1 # チラつき防止用
# OpenSCAD:
# module ring(r1, r2, h) { difference(){ cylinder(r=r1,h=h); translate([0,0,-1]) cylinder(r=r2,h=h+2);} }
def ring(r_outer, r_inner, h, fn):
"""輪っか(足す形状ではなく、差分で作る単体リング)"""
outer_cyl = cylinder(h=h, r=r_outer, center=False, fn=fn)
# OpenSCAD の -1 / +2 は「確実に貫通させるためのマージン」
inner_cut = translate(
cylinder(h=h + 2 * eps, r=r_inner, center=False, fn=fn),
[0, 0, -eps]
)
return outer_cyl - inner_cut
# OpenSCAD:
# module magcup(height, outer, tickness) { ... }
def magcup(height, outer_r, thickness, fn):
"""マグカップ形状(本体 + 取っ手 を作り、内側を一括でくり抜く)"""
inner_r = outer_r - thickness
handle_r = height / 4.0
# --- 本体(足す形状)---
body_outer = cylinder(h=height, r=outer_r, center=True, fn=fn)
# 取っ手(リング): translate -> rotate の順(OpenSCADの入れ子と同じ意味)
handle_ring = ring(handle_r, handle_r - thickness, thickness, fn)
handle_ring = translate(handle_ring, [outer_r, 0, -(thickness / 2.0)])
handle_ring = rotate(handle_ring, [90, 0, 0])
body = body_outer + handle_ring
# --- カッター(引く形状)---
# 上側にずらして「底厚=thickness」「上は開口」になるようにする
inner_cavity = cylinder(h=height + 2 * eps, r=inner_r, center=True, fn=fn)
inner_cavity = translate(inner_cavity, [0, 0, thickness + eps])
cutter = inner_cavity
return body - cutter
# --- メイン処理 ---
cup1 = translate(magcup(100.0, 40.0, 5.0, fn_val), [100.0, 0.0, 0.0])
cup2 = translate(magcup(150.0, 60.0, 5.0, fn_val), [-100.0, 0.0, 0.0])
result = cup1 + cup2
show(result)
必要なら「カップ底をもう少し厚くしたい」「取っ手をもっと上に付けたい(Z方向位置)」みたいな設計変更も、パラメータと translate の値を整理してみてください。
4. 完成コード(PythonSCAD)
# ==========================================
# マグカップ(OpenSCAD → PythonSCAD 変換)
# 作成日: 2026/08/13
# ==========================================
from pythonscad import *
# --- パラメータ設定 (単位: mm) ---
fn_val = 80 # 円の滑らかさ
eps = 0.1 # 差分演算のチラつき防止
# OpenSCAD: ring(r1, r2, h)
def ring(r_outer, r_inner, h, fn):
"""
輪っか(中空円柱)
OpenSCAD版は center=false 相当で、内側カッターを少しはみ出させて確実に抜く構造。
"""
body = cylinder(h=h, r=r_outer, center=False, fn=fn)
cutter = cylinder(h=h + 2 * eps, r=r_inner, center=False, fn=fn)
cutter = translate(cutter, [0, 0, -eps]) # 下方向にepsだけ逃がす
return body - cutter
# OpenSCAD: magcup(height, outer, tickness)
def magcup(height, outer, thickness, fn):
"""
中空カップ + 取っ手リング
OpenSCADのcenter=true構造をそのまま再現。
"""
inner = outer - thickness
handle_r = height / 4.0
# --- カップ本体(足す形状) ---
outer_cyl = cylinder(h=height, r=outer, center=True, fn=fn)
# --- カップ内側(引く形状) ---
inner_cyl = cylinder(h=height, r=inner, center=True, fn=fn)
inner_cyl = translate(inner_cyl, [0, 0, thickness]) # 上にずらして上面を開口
cup_shell = outer_cyl - inner_cyl
# --- 取っ手(足す形状) ---
handle = ring(handle_r, handle_r - thickness, thickness, fn=fn)
handle = translate(handle, [outer, 0, -(thickness / 2.0)])
handle = rotate(handle, [90, 0, 0])
# OpenSCAD union() → PythonSCADは + で結合
return cup_shell + handle
# --- メイン処理 ---
result = magcup(height=100.0, outer=40.0, thickness=5.0, fn=fn_val)
show(result)
5. 完成コード(PythonSCAD)— 正六角形の2D描画
# ==========================================
# 2D: 正六角形(polygonで描画)
# 作成日: 2026/08/15
# ==========================================
from pythonscad import *
# --- パラメータ設定 (単位: mm) ---
radius = 10.0 # 原点から頂点までの距離(外接円半径)
fn_val = 60 # 今回 polygon には直接不要(円などで使用する値)
# --- 関数(モジュール)定義 ---
def make_model(r):
"""
正六角形の2Dポリゴンを作る
※ polygon に渡す点は「[x, y] のリスト」を並べたものにする。Cos(deg), Sin(deg)使用。
"""
pts = []
for i in range(6):
deg = 360 * i / 6.0
x = r * Cos(deg)
y = r * Sin(deg)
pts.append([x, y]) # ← (x, y) タプルではなく [x, y] リスト
hexagon = polygon(pts)
return hexagon
# --- メイン処理 ---
result = make_model(radius)
show(result)
ポイント
- PythonSCADの
polygon()は 「点のリスト(各点は [x, y])」 を安全に渡します - 正六角形を“寸法で確実に”作るなら、
sin/cosで角度から座標を作る方法がズレにくいです
6. 完成コード(PythonSCAD)
# ==========================================
# 六角タイルをくり抜いたプレート(linear_extrude版)
# 作成日: 2026/08/13
# ==========================================
from pythonscad import *
from math import sqrt
# --- パラメータ設定 (単位: mm) ---
hex_r = 10.0 # 六角形の外接円半径(中心→頂点)
rows = 5 # 縦方向の個数
cols = 5 # 横方向の個数
plate_w = 140.0 # 外形プレート幅(X方向)
plate_h = 140.0 # 外形プレート奥行(Y方向)
thickness = 1.0 # 押し出し厚み(Z方向)
fn_val = 60
eps = 0.1
# --- 関数(モジュール)定義 ---
def add_all(shapes):
"""shape1 + shape2 + ... を安全に作る(sum() は start=0 で壊れやすいので使わない)"""
result = None
for s in shapes:
result = s if result is None else (result + s)
return result
def make_hexagon(r):
"""2Dの正六角形(中心は原点)"""
base = [
[ 1.0, 0.0],
[ 0.5, -0.8660254038],
[-0.5, -0.8660254038],
[-1.0, 0.0],
[-0.5, 0.8660254038],
[ 0.5, 0.8660254038],
]
pts = [[r * x, r * y] for x, y in base]
return polygon(pts)
def make_hex_tile(r, n_rows, n_cols):
"""六角形を並べた2Dタイル(原点付近に配置)"""
hex2d = make_hexagon(r)
dx = sqrt(3) * r # ≒ 1.732 * r(横方向ピッチ)
dy = 2.0 * r # 縦方向ピッチ
yoff = 1.0 * r # 偶奇列でのずらし量
cols_shapes = []
for i in range(n_cols):
# 1列(縦に積む)
col_shapes = [translate(hex2d, [0.0, dy * j]) for j in range(n_rows)]
one_col = add_all(col_shapes)
# 列ごとの配置(偶奇でYをずらす)
one_col = translate(one_col, [dx * i, yoff * (i % 2)])
cols_shapes.append(one_col)
tile = add_all(cols_shapes)
# だいたい中央に寄せる(外形プレートを center=True にするので、くり抜きも中心寄せすると扱いやすい)
tile = translate(tile, [-dx * (n_cols - 1) / 2.0, -dy * (n_rows - 1) / 2.0])
return tile
# --- メイン処理 ---
hex_tile_2d = make_hex_tile(hex_r, rows, cols)
# 外形プレート(2D):中心基準
plate_2d = square([plate_w, plate_h], center=True)
# くり抜き(2D差分)→ その後に押し出し
outline_2d = plate_2d - hex_tile_2d
solid = linear_extrude(outline_2d, height=thickness)
result = color(solid, "yellow")
show(result)
修正点(PythonSCADの作法)
-
translate([x,y])(obj)は禁止 →translate(obj, [x, y]) -
linear_extrude(0.1)(shape)は禁止 →linear_extrude(shape, height=0.1) -
color("yellow")(obj)は禁止 →color(obj, "yellow") -
sum([...])は環境によって壊れるので、+で確実に結合(上のadd_all()を使用)
7. 完成コード(PythonSCAD)— 円周上に複数配置
# ==========================================
# OpenSCAD -> PythonSCAD 変換例(円周配置)
# 作成日: 2026/08/14
# ==========================================
from pythonscad import *
from math import sqrt
# --- パラメータ設定 (単位: mm) ---
size = 10.0 # 元モデルの基準サイズ
count = 12 # 円周上に並べる個数
radius = 35.0 # 円周配置の半径(中心からの距離)
start_angle = 0.0 # 開始角度(度)
eps = 0.1 # ここでは未使用(ブーリアンなしのため)
# --- 関数定義 ---
def create_unit(s):
"""
質問文の「base + tilted」を1個分として生成する
※OpenSCADの cube(10) と同様に center=False(原点に角が来る)
"""
base = cube([s, s, s], center=False)
tilted = cube([s, s / sqrt(2), s / sqrt(2)], center=False)
tilted = rotate(tilted, [-45, 0, 0])
tilted = translate(tilted, [0, 0, s])
return base + tilted
def place_on_circle(obj, n, r, ang0_deg=0.0):
"""
obj をZ軸回りに等間隔で回転し、半径 r の円周上に n 個配置して足し合わせる。
配置手順:
1) まず +X方向へ r 平行移動
2) 次に Z軸回りに回転(これで円周上へ回り込み)
"""
result = None
for i in range(n):
ang = ang0_deg + 360.0 * i / n
placed = rotate(translate(obj, [r, 0, 0]), [0, 0, ang])
result = placed if result is None else (result + placed)
return result
# --- メイン処理 ---
unit = create_unit(size)
result = place_on_circle(unit, count, radius, start_angle)
show(result)
調整ポイント
-
countを増やすと個数が増えて密になります(干渉するならradiusも増やす)。 -
start_angleを変えると、並びの開始位置(回転)が変わります。
「円周上に置いたあと、個々の部品も外向きに回したい(放射状に向けたい)」など工夫してみましょう。
参考資料






