0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

参考サイト

上記、サンプルコードを参考に、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)で設計し直す版」も作れます。

スクリーンショット 2026-08-15 155242.png

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)

スクリーンショット 2026-08-15 155413.png

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 の値を整理してみてください。

スクリーンショット 2026-08-15 155708.png

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)

スクリーンショット 2026-08-15 160018.png

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 で角度から座標を作る方法がズレにくいです

スクリーンショット 2026-08-15 160137.png

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() を使用)

スクリーンショット 2026-08-15 160422.png

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 を変えると、並びの開始位置(回転)が変わります。

「円周上に置いたあと、個々の部品も外向きに回したい(放射状に向けたい)」など工夫してみましょう。

スクリーンショット 2026-08-15 160850.png

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?