構文リファレンス
概要
PolyScriptはパイプベースのパラメトリックCADモデリング言語です。プリミティブで形状を作り、パイプ操作のチェーンで変形します。
box 80 60 10 | fillet 2 | diff cylinder 10 10
複数の形状を続けて書くと、自動的に1つの形状に結合(union)されます。
box 10 10 10
sphere 8
# → 2つの形状が自動結合される
明示的に結合したい場合は union [...] を使います。
プリミティブ
3D
box width height depth
cylinder radius height
sphere radius
cone r1 r2 height
torus r1 r2
wedge dx dy dz ltx
thread r pitch h
cone r1 r2 h は截頭円錐(frustum)を作ります。r1 が底面半径、r2 が上面半径、h が高さです。r2 を0にすると完全な円錐になります。
cone 10 5 20 # 截頭円錐(底面R10、上面R5、高さ20)
cone 10 0 20 # 完全な円錐
torus r1 r2 はドーナツ形状を作ります。r1 は中心からチューブ中心までの主半径、r2 はチューブの管半径です。
torus 20 5 # 主半径20、管半径5のトーラス
wedge dx dy dz ltx はくさび形(テーパー付きボックス)を作ります。底面がdxxdz、上面がltxxdzに狭まり、dyが高さです。
wedge 20 10 15 5 # 底面20x15、上面5x15、高さ10
thread r pitch h はおねじ(右ねじ、軸はZ)を作ります。r は外径の半径(M16 なら d=16 → r=8)、pitch はピッチ、h は軸方向の長さで、cylinder と同じく原点中心です。
溝は、山の頂に平らな部分を残した鋭い谷のV字です。
| 引数 | 既定値 | 意味 |
|---|---|---|
land: |
pitch/8 | 山の頂の平らな幅(軸方向。ISO の山の切り落とし)。0 で鋭い山 |
depth: |
(pitch−land)/2×√3 | 溝の深さ(頂から谷まで、半径方向)。既定はフランク角60度 |
chamfer: |
なし | 45度面取り。値1つなら上端だけ(先端。下端はボルトの頭がつく側): true で谷径まで(ISO 4753 の先端。ナットが掛かる)、数値で量を指定。(下, 上) で両端を別々に、両端なら chamfer:(true, true) |
円柱にらせん状の溝をスイープしてブーリアンで引くより数倍速く、面も1周ごとに分かれます。
h がピッチより短いと1周に満たないねじになり、警告 thread.short が出ます(pitch と h の取り違えが多いため)。
thread 8 2 30 chamfer:true # M16 x P2 の全ねじ、長さ30、先端を谷径まで面取り
thread 8.25 2 20 # ナットの穴を切り抜くためのプラグ(はめあい +0.25)
位置規約
3Dプリミティブとextrudeでは、形状の配置ルールが異なります。混在するとズレの原因になるので要注意。
| 操作 | Z軸方向の配置 | 例: 高さ10の場合 |
|---|---|---|
box, cylinder, sphere, cone, torus, thread |
原点中心(centered) | z = -5..+5 |
extrude h |
底面合わせ(z=0から上へ) | z = 0..10 |
つまり box 10 10 10 の底面は z=-5 にあり、rect 10 10 | extrude 10 の底面は z=0 にあります。両者を同じシーンで使うとき、底面の高さが揃いません。
対処法は3つ:
| floor– 底面をz=0に揃える(一番かんたん)center:(true,true,false)– プリミティブのZ軸だけ非センタリング| translate 0 0 h/2– 手動で持ち上げる
# NG: 本体(box)の上に蓋(extrude)を乗せたいが、底面がズレる
body = box 80 60 100 # z = -50..+50
lid = rect 80 60 | extrude 20 # z = 0..20
# lid は本体の真ん中あたりに浮いてしまう
# OK: floor で本体の底面を揃えてから積む
body = box 80 60 100 | floor # z = 0..100
lid = rect 80 60 | extrude 20 # z = 0..20
body | union (lid | translate 0 0 100) # 蓋を本体の上に
2D
rect width height
circle radius
ellipse rx ry
polygon n r
polyline points
text content size
sketch [segments]
2Dプリミティブは**面(Face)**を生成します。| extrude、| cut、| revolve、| loft でソリッドにできます。
2Dの形状には2つの型があります:
| 型 | 作るコマンド | 意味 |
|---|---|---|
| Face | rect circle ellipse polygon polyline text sketch [...]、2Dブーリアン・offset の結果 |
面積を持つ領域。穴を持てる |
| Wire | wire [...] line arc bezier spline helix |
曲線。閉じていても面積は持たない |
型はコマンドで決まり、後から変わりません。extrude cut revolve loft と 2Dブーリアン(diff union inter)は Face 専用で、Wire に使うとエラーになります。Wire を Face にする唯一の方法が offset d(線に太さ 2|d| を与える)です。逆に sweep の spine や profile のように「曲線」が必要な場面では、Face はその外周として使えます。
text はテキスト文字列を2Dの面に変換します。「O」「A」などの内側の輪郭は穴になります。CLI はシステムフォントを探して使います(DejaVu Sans、Liberation Sans、Noto Sans、Roboto、Arial の順)。ブラウザではホスト側がフォントを渡します。どちらも見つからない場合、text は長方形のプレースホルダになります。
polygon n r は外接円半径 r の正n角形を作ります。polyline points は頂点リストから閉じたワイヤーを作ります。
polygon 6 10 # 正六角形(外接円半径10)
polyline [(0,0), (10,0), (5,10)] # 頂点リストから閉じたワイヤー
sketch – 複合ワイヤー
直線・円弧・ベジエ曲線を組み合わせて、自由な形の閉じた2Dプロファイルを作ります。rect や circle では表現できない形状に便利です。
sketch [
(5, 0), # 開始点(タプル)
arc (5, 0) (0, -5) (-5, 0), # 円弧: 開始点 → 通過点 → 終点
(0, 7), # 直線(タプルのみ)
(5, 0) # 直線(最初の点に戻って自動close)
]
セグメントの種類:
| 書き方 | 意味 |
|---|---|
(x, y) |
前の点からの直線 |
arc (sx, sy) (mx, my) (ex, ey) |
3点円弧(開始点・通過点・終点) |
arc (sx, sy) (ex, ey) center:(cx, cy) |
中心アーク(開始点・終点・中心) |
arc (sx, sy) (ex, ey) radius:radius |
半径アーク(開始点・終点・半径、中心は自動計算) |
bezier [(x1,y1), ...] |
ベジエ曲線(制御点リスト。開始点は前セグメント終端、末尾が終点) |
最初の要素は必ずタプル(開始点)です。最後のセグメントが開始点に戻れば自動的に閉じます。arcの開始点が前セグメントの終点と一致しない場合は、自動的に直線が挿入されて接続されます。結果はextrudeやcutでソリッドにできます。
どのアークを使えばいい?
| やりたいこと | 推奨 |
|---|---|
| 3点(始点・通過点・終点)で指定したい | arc start through end |
| 中心と終点で正確な円弧を描きたい | arc start end center:(cx,cy) |
| 半径と終点だけで角丸を作りたい | arc start end radius:radius |
# 涙形 (teardrop) を押し出す
sketch [
(5, 0),
arc (5, 0) (0, -5) (-5, 0),
(0, 7),
(5, 0)
] | extrude 10
# D字穴
r = 3
sketch [
(-r, r),
(-r, -r),
arc (-r, -r) (0, -r - 1) (r, -r),
(r, r),
(-r, r)
]
# 真の1/4円弧(中心指定)
sketch [
(r, 0),
arc (r, 0) (0, r) center:(0, 0),
(0, 0),
(r, 0)
]
# 角丸長方形(半径指定が最も簡潔)
w = 20
h = 10
cr = 2
sketch [
(w/2 - cr, -h/2),
arc (w/2 - cr, -h/2) (w/2, -h/2 + cr) radius:cr,
(w/2, h/2 - cr),
arc (w/2, h/2 - cr) (w/2 - cr, h/2) radius:cr,
(-w/2 + cr, h/2),
arc (-w/2 + cr, h/2) (-w/2, h/2 - cr) radius:cr,
(-w/2, -h/2 + cr),
arc (-w/2, -h/2 + cr) (-w/2 + cr, -h/2) radius:cr
] | extrude 5
パス
line start end
arc start through end
arc start end center:(cx,cy)
arc start end radius:radius
bezier points
helix pitch height radius
spline points
spline は指定した点を通過する滑らかなBスプライン曲線を作ります。sweep のパスとして使えます。
bezier は指定した点を制御点として扱います。曲線は制御点の近くを通りますが、始点と終点以外の点は通過しません。滑らかな曲線を描きたいが点を正確に通したい場合は spline を使ってください。
spline [(0,0,0), (10,5,5), (20,0,10)] | sweep (circle 3)
注意:
bezier/splineのリスト規約は文脈によって異なります。standaloneコマンド(bezier [...] | sweep等)ではリスト先頭に開始点を含めます。一方、sketch/wireセグメント内では開始点は前セグメント終端(current)から暗黙に引き継がれるため、リストには制御点/通過点と末尾の終点のみを指定します。これはCadQueryやSVGパスの業界標準と同じ規約です。
パイプ操作
操作は | でつなぎます:
box 50 50 10 | fillet 2 | diff cylinder 5 10
修飾
| fillet expr # 全エッジをフィレット
| chamfer expr # 全エッジを面取り
| shell expr # 薄肉化(先に面を選択すると開口面になる)
| offset d # ワイヤーまたは面の外形をオフセット(正=外側、負=内側)
box 100 60 40
| edges =Z | fillet 3
| faces >Z | shell 2
fillet は2Dワイヤーにも使えます。角丸の2Dプロファイルを作れます:
rect 40 20 | fillet 3 | extrude 10 # 角丸の四角形を押し出し
offset は3つのコンテキストで動作し、結果はいつも Face です:
- Face選択コンテキスト: 選択された面の外形を抽出し、workplaneを作成してオフセットします。→ Face
- Face: 外形を相似に拡縮します(
+外側、-内側)。穴を持つ面はオフセットできません。→ Face - Wire: 線に太さを与えます。開いた wire は幅
2|d|の帯(端は既定で丸、cap:"square"で直角)、閉じた wire は幅2|d|のリングになります。→ Face
# Face選択 → offset → cut
box 80 60 10
| faces >Z
| offset -10
| cut 3
# Face → offset
rect 80 60 | offset -10 | extrude 5
# Wire → offset: 折れ線を幅4の帯にして押し出す
wire [(0,0), (40,0), (40,30)] | offset 2 | extrude 5
色指定
形状に色を付けます。色はエクスポート時(glTF/GLB/STEP/OFF)にパーツ単位で反映されます。
| color "red" # 名前付き色
| color "#FF0000" # HEXカラー(文字列リテラル)
| color "#F00" # HEX短縮形
| color 0.8 0.2 0.1 # RGB float (0..1)
| color 255 128 0 # RGB int (0..255、自動正規化)
| color "red" alpha:0.5 # 透明度付き
色の指定方法は3種類です:
- 名前付き色:
"red","blue","steel"など - HEXカラー:
"#FF0000"または短縮形"#F00"(#はコメント記号と衝突するため、必ず文字列リテラルとして書きます) - RGB値: 3つの数値を並べます。全て1以下なら 0..1 範囲、いずれかが1を超えれば 0..255 範囲として自動的に正規化されます
alpha: キーワード引数で透明度を指定できます(0..1、デフォルト 1.0)。
パーツごとに色を分けることもできます:
union [
box 10 10 10 | color "red"
cylinder 15 3 | color "blue"
]
名前付き色パレット
3段階の色パレットを使えます:
| 階層 | 色名 |
|---|---|
| 基本色(16色) | red, green, blue, yellow, cyan, magenta, orange, purple, white, black, gray/grey, brown, pink, lime, navy, teal |
| CAD素材色 | silver, gold, steel, copper, brass, aluminum, darkgray/darkgrey, lightgray/lightgrey |
| CSS Named Colors | steelblue, coral, darkslategray など、CSS準拠の色名すべて |
未知の色名を指定するとエラーになります。
ブーリアン
| diff shape # 形状を引く
| union shape # 形状を足す
| inter shape # 形状と交差
at: で配置できます:
box 50 50 10
| diff cylinder 3 10 at:15 15
形状演算子 + - *
式の中では、形状どうしに +(union)、-(diff)、*(inter)が使えます。意味はパイプ操作の union/diff/inter と同じです(右辺がリストなら順に適用、Face どうしなら2Dブーリアン)。両辺はソリッドどうしか Face どうしでなければならず、(rect 10 10) + (box 5 5 5) のように混ぜると型エラーになります(どの書き方でも同じ)。優先順位は数値演算と同じで * が先、いずれもパイプ | より先に結合します。集合演算の優先順位はツールによって異なり、a - (b * c) と (a - b) * c は違う形になるので、* を +/- と混ぜるときは括弧を書いてください。
base = box 80 60 10
holes = [cylinder 3 20 at:(20, 15), cylinder 3 20 at:(-20, 15)]
base - holes | edges >Z | fillet 2 # (base - holes) | fillet 2
lid = (body | faces >Z | offset -2 | extrude 3) - pins
plate = (rect 40 20) - ((circle 4) * (rect 10 10)) # rect から (circle ∩ rect) を引く
演算子は変数か括弧で囲んだ式の間でだけ使えます。 コマンドの引数の直後には書けません。box 10 10 10 - x は引数の算術 box 10 10 (10 - x) と解釈されるからです。コマンドの直後に続けたいときはパイプ形を使います。
box 10 10 10 - cylinder 3 20 # ✗ パースエラー
(box 10 10 10) - (cylinder 3 20) # ✓
box 10 10 10 | diff (cylinder 3 20) # ✓ こちらが読みやすい
長い式は演算子のところで改行できます。演算子は前の行の末尾にも、次の行の先頭にも置けます。
行頭の - は1行で書いたときと同じく空白で読み方が決まるので、引き算なら - b のように後ろに空白を入れます。
body = outer
- cavity
- $hole
grip = handle *
mask
配置(Place)
変数に格納した2D形状をパイプラインで配置します。diff/union/inter と同様に、変数参照やインラインの2Dプリミティブを引数に取れます。
| place shape # 変数の2D形状を配置
| place (circle 3) # インライン2Dプリミティブ
面を選択した後、あらかじめ定義したプロファイルを置いてカットや押し出しに使えます。同じ形状を何度も使い回したいときに便利です。
s = sketch [(5,0), arc (5,0) (0,-5) (-5,0), (0,7), (5,0)]
box 10 10 10 | faces >Z | place s | cut
box 10 10 10 | faces >Z | place s | extrude 5
profile = rect 5 5
box 10 10 10 | faces >Z | place profile | cut
box 10 10 10 | faces >Z | place (circle 3) | cut
押し出し / 回転体 / スイープ / ロフト
| extrude height draft:angle
| revolve axis [deg] # axis: X/Y/Z、deg省略で360°
| sweep profile # pipeline側が spine(wire)、引数が profile(断面のwire)
| loft [sections] height
| loft [sections] [offsets]
| loft [sections] height ruled:true
rect 60 40 | extrude 15
rect 10 30 at:(15, 0) | revolve Y
circle 5 | loft [rect 8 8] 10
circle 5 | loft [rect 8 8, circle 3] [5, 15]
draft: は抜き勾配(テーパー角)を度数で指定します。正値は押し出し方向に向かって内側にすぼまり(成形品の抜き勾配と同じ向き)、負値は外側に広がります。底面は描いた寸法のままです。rect 20 20 | extrude 10 draft:10 は底が 20、上端が 16.47(20 − 2 × 10 × tan 10°)。
ruled:true を指定すると、断面間を直線で補間します(デフォルトは滑らかな曲面)。
revolve – 回転体
2Dプロファイルを指定軸まわりに回転してソリッドを作ります。
| revolve axis # 360°回転(axis: X, Y, Z のいずれか)
| revolve axis deg # 指定角度で回転
プロファイルは回転軸の片側に配置する必要があります。 軸をまたぐプロファイル(例: 原点中心の circle 20)は退化形状エラーになります。原点から離すには at:(x, y) を使うか、sketchで軸の片側にワイヤーを描きます。
# リング(トーラス様)
rect 10 30 at:(15, 0) | revolve Y
# 花瓶/お椀(半周)
sketch [(0, 0), (15, 0), (15, 3), (3, 20), (0, 20)]
| revolve Y 180
# X軸周りの回転
circle 5 at:(0, 20) | revolve X
sweep – パススイープ
パイプラインで渡したspine(軌道)に沿って、引数のprofile(断面)を掃引して3D形状を作ります。spineはWire(開いていても閉じていてもよい)で、profileはFace(閉断面)でもWire(開断面)でもかまいません。Face を渡した場合はその外周が使われます(穴を持つ面は不可)。spine/profileは「どちらの役割か」を指す呼び名で、pathという型はありません。
構文: spine | sweep profile
- 開いたwire:
line,arc,bezier,spline,helix,wire [...] - 閉じた輪郭(Face):
circle,rect,ellipse,polygon,polyline,sketch [...]
spineとprofileの開/閉の組み合わせで、生成される形状が変わります:
| spine | profile | 結果 |
|---|---|---|
| 開 | 閉 | 管状ソリッド(主ユースケース) |
| 閉 | 閉 | 閉ループ管(トーラス様) |
| 開 | 開 | 帯状サーフェス(ネジ溝等) |
# 通常の管: 曲線パスに沿って円を掃引
arc (0, -25) (25, 0) center:(0, 0) | sweep (circle 5)
# トーラス: 大半径50、小半径10
circle 50 | sweep (circle 10)
# スプラインに沿ったパイプ
spline [(0,0,0), (10,5,5), (20,0,10)] | sweep (circle 3)
注意:
sketch [...]は常に自動closeされる(閉じたwireを生成する)ため、sweepの開いたspineには使えません。開いた複数セグメントのwireが必要なら、wire [...]リテラルか、line/arc/splineなどのパスプリミティブを使ってください。
wire – open wireリテラル
sketch [...] の「開いた版」です。複数セグメントをつないだ開いたwire(auto-closeしない)を作ります。sweepのspineに複合的な経路が必要なとき、これ1つで書けます。
wire [
segment1,
segment2,
...
]
セグメントは sketch と同じ書き方が使えます(tarc を除く)。さらに2D座標だけでなく3D座標も使えます。
| 書き方 | 意味 |
|---|---|
(x, y) または (x, y, z) |
前の点からの直線 |
line (start) (end) |
直線 |
arc (start) (through) (end) |
3点円弧 |
arc (start) (end) center:(cx,cy) |
中心アーク |
arc (start) (end) radius:radius |
半径アーク |
bezier [...] |
ベジエ曲線(開始点は前セグメント終端、制御点と末尾の終点のみ指定) |
spline [...] |
Bスプライン曲線(開始点は前セグメント終端、通過点と末尾の終点のみ指定) |
sketchとの違い:
| sketch | wire | |
|---|---|---|
| auto-close | あり | なし |
| 型 | Face(面) | Wire(曲線) |
| 出力 | 面。extrude/cut できる | 開いた曲線。閉じても面にはならない |
| 座標 | 2D | 2D/3D両対応 |
| 主用途 | extrude/revolve/cut | sweepのspine |
# 基本: 直線 + 円弧を組み合わせた経路
wire [
(0, 0),
(10, 0),
arc (10, 0) (15, 5) radius:5,
(15, 20)
]
# sweepと組み合わせ: L字パイプ(wire がspine、circleがprofile)
wire [
(0, 0),
(10, 0),
arc (10, 0) (15, 5) radius:5
] | sweep (circle 5)
# 3Dパスもそのまま書ける
wire [(0, 0, 0), (10, 0, 5), (20, 10, 10)]
# workplane経由: XZ平面上にパスを描き、円断面で掃引
workplane XZ | wire [(0,0),(10,0),(10,10),(0,10),(0,0)] | sweep (circle 2)
sketchと同様に、wireもパイプでworkplaneを受け取れます。デフォルトのXY平面以外にもパスを描けます。
sweepでの使い分けガイド
| 用途 | 推奨 |
|---|---|
| spine(単純1セグメント) | line/arc/helix/spline (パスプリミティブ) |
| spine(複数セグメント) | wire [...] リテラル |
| プロファイル(閉断面) | circle/rect/… または sketch [...] |
| プロファイル(開断面) | wire [...] |
カット / 穴あけ
| cut depth # 貫通カットまたは指定深さまでカット
| hole radius depth:d # 穴あけ(半径指定、直径ではない)
hole はFaceSelectionとPointSelectionの両方から使えます。
- FaceSelectionから: 選択した面の中心に穴を開けます。
faces >Z | hole 5はfaces >Z | circle 5 | cutと同等です。複数面を選択した場合は各面の中心にそれぞれ穴が開きます。 - PointSelectionから: 各ポイントの位置に穴を開けます(従来の動作)。
深さ(depth:)を省略すると貫通穴になります。
at: で穴の位置を指定できます。origin: で座標基準を制御します(後述「座標指定の基準」参照)。
# Face選択から: 面の中心に穴
box 80 60 10 | faces >Z | hole 5
# Point選択から: 各ポイントに穴
box 80 60 10 | faces >Z | points (polar 4 15) | hole 5
# WP座標 (10,20) に穴
box 80 60 10 | faces >Z | hole 5 at: 10 20
# ワールド原点を面に投影して穴
box 80 60 10 | faces >Z | hole 5 at: 0 0 origin:"world"
# ワールド座標 (10,20,0) に穴(3成分はワールド基準)
box 80 60 10 | faces >Z | hole 5 at: 10 20 0
rect 60 40 | extrude 15
| faces top
| rect 40 20 | cut 10
面 / エッジ / 頂点選択
| faces selector # 面を選択
| edges selector # エッジを選択
| verts selector # 頂点を選択
セレクタは短い記号または名前エイリアスを使います:
| 記号 | 意味 | 名前エイリアス |
|---|---|---|
>Z |
最大(上) | top |
<Z |
最小(下) | bottom |
>X |
最大(右) | right |
<X |
最小(左) | left |
>Y |
最大(奥) | back |
<Y |
最小(前) | front |
=Z |
Z軸に平行(Z軸に沿った辺、Z軸を含む面 = 側面) | |
=X, =Y |
X軸 / Y軸に平行 | |
=XY |
XY平面に平行(水平な辺、上面と底面) | |
=YZ, =XZ |
YZ平面 / XZ平面に平行 | |
+Z |
上を向く面(法線が+Z) | |
-Z |
下を向く面(法線が-Z) | |
+X, -X, +Y, -Y |
法線がその向きの面 |
>Zと+Zの違い:>Zは位置(最も高い面)、+Zは向き(上を向く面すべて)で選びます。箱ではどちらも上面1枚ですが、段差があると+Zは複数の面を返します。+-は面専用で、辺に使うとエラーになります。「垂直」のセレクタはありません。Z軸に垂直な辺は=XYです。
複合セレクタ
複数のセレクタをスペース区切りで並べるとAND(絞り込み)になります:
| edges >Z >X # Z最大位置 かつ X最大位置のエッジ
リスト構文で囲むとOR(和集合)になります:
| edges [>Z, <Z] # Z最大位置 または Z最小位置のエッジ
名前付け(as)
as で面やエッジに名前を付けて後から参照できます:
| faces <X as $left
| edges =Z as $top_edges
面を選択するとワークプレーンが暗黙的に作られるため、2Dプリミティブを直接パイプできます:
box 50 50 10
| faces top
| circle 5 | cut
| edges <Z | fillet 1
Face/Wireコンテキストでは、verts は現在の形状の頂点をVertex selectionとして返します。
Vertex selectionは2D/3Dプリミティブの両方に対応しており、各頂点にプリミティブが配置されます:
box 80 60 10
| faces top
| rect 70 50 | verts | circle 1 | cut
3Dプリミティブも同様です。各頂点が配置ポイントになります:
rect 100 100 | verts | box 1 1 1 # 4つの頂点にboxを配置
rect 100 100 | verts | sphere 2 # 4つの頂点にsphereを配置
Vertex selectionは translate で全頂点の位置をオフセットでき、選択コンテキストを維持します。Points selection (points) も同様です:
rect 80 60 | verts | translate 10 10 10 | cone 2 0 6
box 80 60 10 | faces >Z | points (polar 4 15) | translate 5 5 0 | hole 3
ワークプレーン / ポイント
面選択は暗黙的にワークプレーンを作成します。明示的な workplane は特定の向きが必要な場合にのみ使います:
| workplane XZ # 軸を明示したワークプレーン
| points (polar 6 20) # 円形にポイントを配置
| points (grid nx ny 20) # 格子状にポイントを配置(第3引数=ピッチ)
ソースコマンドとして workplane を使うと、2Dプリミティブ・sketch・wireの初期平面を指定できます:
workplane XZ | circle 10 | extrude 10 # XZ平面上に円
workplane XZ | sketch [...] | extrude 5 # XZ平面上にsketch
workplane XZ | wire [...] | sweep (circle 2) # XZ平面上にwire(spine)
平面名は XY XZ YZ の3つと、その符号反転 -XY -XZ -YZ。AB は「ローカル x がワールド A、ローカル y がワールド B」、-AB は同じ平面・同じローカル軸で法線だけ反転したものです。描く位置は変わらず、extrude/cut/hole の向きだけ逆になるので、押し出しを軸の負側にしたいときに使います。- は名前に密着させます(workplane - XY は減算)。逆順の綴り(ZX 等)はエラーになり、符号付きの名前を案内します。
| 名前 | ローカル x | ローカル y | 法線(extrude の向き) |
|---|---|---|---|
XY(既定) |
+X | +Y | +Z |
-XY |
+X | +Y | −Z |
XZ |
+X | +Z | +Y |
-XZ |
+X | +Z | −Y |
YZ |
+Y | +Z | +X |
-YZ |
+Y | +Z | −X |
workplane XZ | circle 10 | extrude 10 # +Y へ押し出し
workplane -XZ | circle 10 | extrude 10 # −Y へ押し出し(同じ位置に描き、向きだけ逆)
任意の法線を持つ平面を名前で作る構文はありません。傾いた面に描くにはソリッドの面を選択します(faces が面の法線をワークプレーンに渡します)。
# Face選択から直接 hole(面の中心に穴)
cylinder 30 5 | faces top | hole 3
# Point選択から hole(各ポイントに穴)
cylinder 30 5
| faces top
| points (polar 4 10)
| hole 3
polar / grid 省略形
FaceSelectionまたはPointSelectionコンテキストでは、points を省略して polar / grid を直接パイプできます。
# 省略形(面選択の後で使える)
cylinder 30 5 | faces top | polar 4 10 | hole 3
box 80 60 10 | faces top | grid 3 2 15 | circle 2 | cut
上記は以下と同じ意味です:
cylinder 30 5 | faces top | points (polar 4 10) | hole 3
box 80 60 10 | faces top | points (grid 3 2 15) | circle 2 | cut
3Dコンテキストでは polar / grid は従来通り配列複製として動作します。コンテキストによって意味が変わる点に注意してください。
変形
| translate x y z
| rotate rx ry rz # ソリッド: 3引数(ワールド軸)。省略不可
| rotate a # 2D形状(Face/Wire): 1引数、面の法線まわり
| scale sx sy sz # 非一様スケール(各軸個別)
| scale s # 一様スケール(全軸同じ倍率)
| mirror "X"/"Y"/"Z" # 鏡像反転。keep:true で原形と結合
| floor # 底面を z=0 に揃える
| move dx dy # ワークプレーン上の2Dオフセット
| moveto x y # ワークプレーン上の2D絶対位置
mirror は指定した軸に垂直な平面で鏡像反転します。"X" はYZ平面、"Y" はXZ平面、"Z" はXY平面です。原形は残りません。keep:true を付けると原形と鏡像を結合した形になり、origin: でミラー平面が通る点を指定できます(rotate と同じ規則)。ワークプレーン上の2D形状には "X" / "Y" のみで、面内で反転します。
box 30 20 10 | mirror "X" # YZ平面でミラー(反転のみ)
half | mirror "Z" keep:true # 半分から対称な全体
box 30 20 10 | mirror "X" origin:(15, 0, 0) # x=15 の平面で反転
floor – 底面をz=0に揃える
任意の3D形状のバウンディングボックス下端(zmin)を z=0 に揃えます。引数なし。
| floor
内部的には translate 0 0 -bbox.zmin と同等の処理を行います。centeredなプリミティブを底面合わせにしたいとき、center:(true,true,false) の代わりにパイプ1つで済むのが利点です。
# box (centered) の底面を z=0 に
box 10 10 10 | floor # z=-5..+5 → z=0..10
# sphere でも同様
sphere 15 | floor # z=-15..+15 → z=0..30
# 合成形状にも使える
union [box 20 20 10, cylinder 5 20] | floor
注意:
floorはパイプ操作(形状を移動する)です。数学関数のfloor(x)(切り捨て)とは別物です。
move はワークプレーン上で描画位置を相対移動、moveto は絶対位置に移動します。origin: で座標基準を切り替えられます(後述「座標指定の基準」参照)。
box 80 60 10
| faces top
| move 10 10 | circle 5 | cut # 面の中心から(10,10)ずらした位置に穴
| moveto 30 20 | rect 5 5 | cut # ワークプレーン原点から(30,20)にポケット
# ワールドXY座標を面に投影
| moveto 10 20 origin:"world"
# 任意のワールド点を新原点にして相対移動
| moveto 5 5 origin:(10,20,0)
# ワールドXYのデルタで移動
| move 10 0 origin:"world"
rotate の引数の個数
引数の個数は回す対象で決まり、省略はできません。ソリッドは rotate rx ry rz の3個ちょうど
(1軸だけ回すときも rotate 0 90 0)、ワークプレーン上の2D形状は rotate a の1個ちょうど
(面内回転。面から浮かせることはできません)。rotate 0 90 はエラーになります。
何も描いていないワークプレーンは回せません。
rect 10 5 | rotate 45 # 2D: 面内で45°
faces >Z | rect 10 5 | rotate 30 | cut 3 # 面上のスケッチを回してからカット
box 10 10 10 | rotate 0 0 45 # 3D: Z軸まわり45°
2D形状は描いたワークプレーンから出られないので、rotate 90 0 0 で立てたり
translate で浮かせたりはできません(poly check がエラーにします)。
縦の面(XZ / YZ)にパスや輪郭を置くときは、最初からその面で描くか、3D座標で書きます。
workplane XZ | wire [arc (0,-25) (25,0) center:(0,0)] | sweep (circle 5) # XZ面の円弧パス
arc (0,0,-25) (25,0,0) center:(0,0,0) | sweep (circle 5) # 同じパスを3D座標で
move / moveto も描いた形は動かしません。次に描く位置(カーソル)を動かす操作です。
形の位置は描くときに rect 10 10 at:(5, 5) のように指定します。
origin: キーワード引数
translate、rotate、scale は origin: キーワード引数で基準点を指定できます。
2D形状の rotate では既定がワークプレーン原点、"local" が2D形状の中心、
2成分の点はワークプレーン座標です。
| 値 | 意味 | デフォルト |
|---|---|---|
"world" |
ワールド原点 (0,0,0) を基準 | ✓ |
"local" |
オブジェクトのBoundingBox中心を基準 | |
(x, y, z) |
任意の点を基準 |
# ワールド原点中心に回転(デフォルト)
box 10 10 10 | translate 20 0 0 | rotate 0 0 45
# オブジェクト中心で回転
box 10 10 10 | translate 20 0 0 | rotate 0 0 45 origin:"local"
# 任意の点を中心に回転
box 10 10 10 | rotate 0 0 45 origin:(10, 20, 0)
# 一様スケール(原点基準で2倍)
box 10 10 10 | scale 2
# 非一様スケール
box 10 10 10 | scale 2 1 0.5
# オブジェクト中心を基準にスケール
box 10 10 10 | translate 20 0 0 | scale 3 origin:"local"
move、moveto、hole、プリミティブのat: でも origin: が使えます。詳しくは次の節を参照してください。
座標指定の基準(at: と origin:)
at: で位置を指定するとき、座標の解釈基準は成分数で暗黙的に決まります。origin: を使えば明示的に切り替えられます。
既定の基準(origin: 省略時):
| 成分数 | 基準 | 例 |
|---|---|---|
2成分 at: x y |
ワークプレーン座標(WP原点基準) | circle 5 at: 10 20 |
3成分 at: x y z |
ワールド座標(面に法線投影) | circle 5 at: 10 20 0 |
明示指定:
origin: 値 |
意味 |
|---|---|
"world" |
ワールド原点 (0,0,0) を基準。2成分でもワールド座標として解釈 |
"local" |
ワークプレーン原点を基準(2成分のデフォルトと同等) |
(ox, oy, oz) |
任意のワールド座標点を新たな原点とし、at: をその点からの相対WP座標として解釈 |
ワールド座標(3成分、または origin:"world" 指定の2成分)は、現在のワークプレーンの面に法線方向で投影されます。
origin: は以下の操作で使用できます:
at:を持つプリミティブ:circle,rect,ellipse,polygon,box,cylinder,sphere,cone,torus,wedge- 穴あけ:
hole(at:と組み合わせ) - カーソル移動:
moveto,move - 変形:
translate,rotate,scale
# 2成分 at: はWP原点基準(既定)
faces >Z | circle 5 at: 10 20 # WP座標 (10,20) に配置
# 3成分 at: はワールド座標(既定)
faces >Z | circle 5 at: 10 20 0 # ワールド(10,20,0) を投影
# origin:"world" で2成分もワールド基準に
faces >Z | circle 5 at: 10 20 origin:"world" # ワールドXY (10,20) を投影
# origin:(ox,oy,oz) で任意のワールド点を基準に
faces >Z | circle 5 at: 5 5 origin:(10,20,0) # (10,20,0) から相対WP(5,5)
# hole でも同様
faces >Z | hole 5 at: 0 0 origin:"world" # ワールド原点に穴
変数
変数は裸の名前です。= で値を与え、値を書ける場所ならどこでも使えます。def の仮引数、内包のループ変数も裸の名前です。
w = 80
h = 60
box w h 10
def plate(size, t) = box size size t
pins = [cylinder 2 10 at:(x, 0) for x in [-20, 20]]
予約語(box、shell、offset、for など)は変数名に使えません。
名前の前の $($w)は、以前のファイルとの互換性のために受け付けます。w と同じ変数を指します。新しいファイルでは使わないでください。予約語を変数名にする唯一の手段でもあります($shell = 2)。同じ名前を両方の書き方で代入すると(bore = 5 の後に $bore = cylinder 3 10)値が上書きされ、poly check が var.dollar-alias を警告します。
@paramアノテーション
変数に @param を付けると、GUIカスタマイザーでスライダーやドロップダウンとして操作できるパラメーターになります。変数宣言の直前の行に書きます。
@param 10..200 step:5 desc:"Box width"
width = 80
box width 60 10
これだけで、GUIには10から200まで5刻みのスライダーが表示されます。
基本構文
@param オプション...
変数名 = デフォルト値
範囲ショートハンド
よく使うmin/max/stepパターンを短く書けます:
| 記法 | 意味 |
|---|---|
@param 1..100 |
min:1 max:100 |
@param 1..100..0.5 |
min:1 max:100 step:0.5 |
@param -10..10..1 |
min:-10 max:10 step:1 |
ショートハンドの後にオプションを追加することもできます:
@param 1..100 desc:"Height"
オプション一覧
| キー | 型 | 説明 |
|---|---|---|
min |
数値 | 最小値(スライダー下限) |
max |
数値 | 最大値(スライダー上限) |
step |
数値 | ステップ幅(スライダーの刻み) |
label |
文字列 | 表示ラベル(省略時は変数名を使用) |
desc |
文字列 | 説明テキスト(ツールチップ) |
choices |
リスト | 選択肢リスト(ドロップダウン) |
group |
文字列 | GUIのグループ名(デフォルト: "General") |
type |
文字列 | 型ヒント: "int", "float", "string", "bool" |
hidden |
真偽値 | true でGUIに非表示 |
type を省略すると、デフォルト値から自動推論されます(42 ならint、2.5 ならfloat、"PLA" ならstring、true ならbool)。
選択肢(ドロップダウン)
choices を使うと、ドロップダウンメニューとして表示されます:
@param choices:["M3", "M4", "M5", "M6"] desc:"Bolt size"
bolt = "M4"
実用的な例
@param 40..200 step:5 group:"Dimensions" desc:"Case width"
case_w = 100
@param 30..150 step:5 group:"Dimensions" desc:"Case depth"
case_d = 60
@param 1..5 step:0.5 group:"Wall" desc:"Wall thickness"
wall = 2
@param type:"bool" group:"Features" desc:"Add ventilation holes"
vents = true
box case_w case_d 40
| color "steel"
| faces >Z | shell wall
CLIからの上書き
poly build コマンドの -D key=value オプションで、ビルド時にパラメータを上書きできます。--params-file でJSONファイルからまとめて指定することもできます。
poly build model.poly -D width=100 -D height=50
poly build model.poly --params-file presets/large.json
-D の値は型推論されます(100 → int, 1.5 → float, true → bool, PLA → string)。同じキーが複数のソースで指定された場合の優先順位は次のとおりです。
- CLI
-D --params-file(平坦なkey-value JSON)@paramのデフォルト値
ソースに定義されていないパラメータ名を -D で渡した場合は警告が表示されますが、実行は続行します。
値はアノテーションと照合されます。choices にない値はエラー(param.choice)です。min..max の範囲外の数値は警告(param.range)です。範囲はGUIのスライダーの目安で、わざと外すこともできますが、poly verify(既定で strict)と --strict では止まります。
詳しくは「はじめに」を参照してください。
@profileアノテーション
複数のトップレベル変数を一括で切り替えるプリセットを定義する。GUIカスタマイザーに「プリセット」のドロップダウンができる。@param とは独立していて、併用できる。
@profile {
"S": { width: 30, height: 20, depth: 15 },
"M": { width: 60, height: 40, depth: 30 },
"L": { width: 120, height: 80, depth: 60 }
}
@param 10..200 step:5 desc:"Box width"
width = 60
height = 40
depth = 30
box width height depth
| 項目 | 規則 |
|---|---|
| 置き場所と個数 | トップレベルに1ファイル1つまで(2つ目はパースエラー) |
| プリセット名 | ダブルクォートの文字列。重複はパースエラー |
| 値 | 数値・文字列・真偽値(null 不可)。空ボディ @profile {} はエラー、空エントリ "S": {} は可(宣言値のまま) |
| 存在しない変数 | 警告して無視 |
| GUIの初期選択 | ファイルの現在値と完全一致するエントリ。なければ “Custom”。個別に変更して一致しなくなっても “Custom” |
関数
def で単一式の関数を定義します:
def standoff(r, h, hole_r) = cylinder r h | diff cylinder hole_r h
box 80 60 3
| union standoff 4 10 1.5 at:10 10
括弧で呼ぶときは、引数に形状コマンドやパイプラインをそのまま書けます。引数どうしは , で区切ります:
def lift(s, h) = s | translate 0 0 h
lift(box 10 10 10 | fillet 1, 5)
コマンドの引数の中で関数を呼ぶときは、名前の直後に空白を入れずに ( を書きます。
空白を入れると、関数名と括弧の式が別々の引数になります(poly check が arg.function-value で止めます):
def r(k) = k * 2
cylinder r(3) 10 # 半径 6、高さ 10
cylinder r (3) 10 # ✗ arg.function-value
インポート
別の .poly ファイルから関数定義を読み込みます:
import "gear"
spur_gear 12 2 | extrude 8
インポートは読み込み元ファイルのディレクトリからの相対パスで解決されます。取り込まれるのは、そのファイルの def と代入だけです(形を作る文と、そのファイル自身の import は無視されます)。
poly live で Live エディタに開くときと、objhub に上げるときは、ファイルが1つしか持てないので、この取り込み分を import の行に展開します。
式
算術演算
+ - * / // % **
注意: Greedy引数内での
+/-の解釈は空白パターンで決まります。-5(密着)は負の数、10 - 5(前後に空白)は二項減算(= 5)、10 -5(前に空白・後に密着)は2つの引数(10と-5)です。紛らわしいときはカッコで囲むのが確実です。
比較と論理演算
== != < > <= >= ~
and or
a ~ b は近似比較です。数値どうしで、差が大きい方の 1% 以内なら true になります。
許容差は assert の tol: で変えられます(下の「計測と検証」)。
条件式
if condition then expr else expr
if/then/else は式なので、インラインで使えます:
use_round = true
shape = if use_round then circle 10 else rect 20 15
shape | extrude 5
then 節・else 節には形状コマンドを括弧なしで書けます。ただしパイプは節の中に書けません。| はいちばん
優先順位が低いので、式の後ろの | は if 全体の結果に掛かります。節の中でパイプを使うには
括弧で囲みます:
if use_round then circle 10 else rect 20 15 | extrude 5 # どちらの形も押し出す
if flag then (circle 10 | extrude 5) else (rect 20 15 | extrude 3)
box 40 30 (if deep then 20 else 10) # 引数の位置に書くときは括弧が必要
リスト内包表記
[expr for var in range(n)]
[expr for var in list]
in の後ろは range(...) でも任意のリストでもかまいません。要素はそのまま変数に入るので、点のリストを回せば変数はタプルです。
実用例:
# 15mm間隔で6個のボックスを配列
union [box 10 10 10 at:(i * 15, 0) for i in range(6)]
# 同心円
[r * 5 for r in range(1, 6)]
# 点のリストの各点に円柱(p はタプル、p[0] が x)
pts = [(0, 0), (20, 0), (20, 10)]
union [cylinder 2 4 at:(p[0], p[1]) for p in pts]
ネストした内包表記も使えます:
# 2Dグリッド生成
[[i + j * 10 for i in range(3)] for j in range(2)]
# → [[0, 1, 2], [10, 11, 12]]
数学関数
角度はすべて度。これらの名前で def は作れない(def.shadows-builtin)。引数の個数が違うと poly check が call.arity で止める。
| 関数 | 引数 | 意味 |
|---|---|---|
sin(a) cos(a) tan(a) |
1 | 三角関数(引数は度) |
asin(x) acos(x) atan(x) |
1 | 逆三角関数(結果は度) |
atan2(y, x) |
2 | y/x の逆正接(結果は度、象限を区別) |
sqrt(x) abs(x) |
1 | 平方根、絶対値 |
floor(x) ceil(x) round(x) |
1 | 切り捨て、切り上げ、四捨五入 |
min(a, b, ...) max(a, b, ...) |
1個以上 | 最小、最大 |
radians(d) / rad(d)、degrees(r) / deg(r) |
1 | 度とラジアンの変換 |
len(list) |
1 | リストの長さ |
range(n) / range(a, b) / range(a, b, step) |
1〜3 | 整数のリスト。range(5) は [0,1,2,3,4]、b は含まない、step は負も可(0 はエラー) |
定数: pi
タプルとリスト
(10, 20, 30) # タプル
[(0,0), (10,5), (20,0)] # リスト
要素は xs[i] で取り出せます(0 始まり)。リストどうしは + でつなげます:
a = [(0, 0), (10, 0)]
b = [(10, 10), (0, 10)]
polyline (a + b) | extrude 2 # 4点の閉じた輪郭
pts = a + [(5, 15)] # 1点足すときも [ ] で包む
+ がつなぐのはリストだけです。タプルどうし((1, 2) + (3, 4))や、リストとタプル(pts + (1, 2))はエラーになります。点の和や、点を数値2つとして足してしまう取り違えを防ぐためです。形状とリストの + は従来どおり和集合です(base + [boss, rib])。
計測と検証
形状の変数にドットでプロパティを付けると、カーネルが測った値が読めます。
assert はその値で意図を検査し、print は値を報告します。どちらも幾何には
影響しません。
プロパティ
g = box 80 60 25 | faces >Z | shell 2
g.volume # 体積
g.area # 表面積
g.solids # ソリッド数(1 でなければ部品が融合していない)
g.faces g.edges g.verts # 面・エッジ・頂点の数
g.valid # OCCT が B-Rep を正しいと判定したか(true / false)
g.bbox # バウンディングボックス。さらに .x .y .z(寸法)、.min .max .center(座標のリスト)
2D 形状(Face / Wire)では area、faces(領域の数)、wires(曲線の数)、bbox が読めます。
選択に付けたプロパティは、元のソリッドではなく選んだものを測ります。
(g | faces <Z).area は底面の面積です。面の選択では area、faces、bbox、
エッジの選択では edges、bbox、頂点の選択では verts、bbox が読めます。
面の上に描いた輪郭(g | faces >Z | rect 10 10)は 2D 形状なので、輪郭を測ります。
選択に .volume のようなソリッドのプロパティを付けると attr.unknown で止まります。
ソリッドはその変数で測ってください。
プロパティ名は変数や括弧の直後に密着させます。括弧で囲んだパイプラインの結果にも付けられ、 コマンドの引数にもそのまま書けます:
(g | faces >Z).area
box g.bbox.x 10 10
無い名前は attr.unknown で止まり、使える名前の一覧が出ます。
assert
assert g.solids == 1
assert g.bbox.x <= 80 and g.bbox.y <= 60
assert g.volume ~ 15552 # 近似比較。大きい方の 1% 以内
assert g.volume ~ 15552 tol:5 # 絶対許容差(同じ単位)
assert g.volume ~ 15552 tol:0.1% # 相対許容差
assert clear(lid, body) # 2 つのソリッドが重ならない(接するだけなら true)
条件は真偽値になる式です。破れた assert は assert.failed というエラーになりますが、
評価はそこで止まらず最後まで進みます。1 回の実行で全部の結果が分かり、トレースにも
assert ... の行が pass / FAIL で並びます。poly verify と poly build は終了コード 3 で
失敗し、build はファイルを書きません。エラーメッセージは両辺の実測値を引用します:
m.poly:7:1 error assert.failed: assert g.solids == 2 failed (left: 1, right: 2)
tol: は assert 文の末尾に書き、その条件の中の ~ にだけ効きます。
print "vol" g.volume g.bbox # vol 15552 80x60x25 at (-40,-30,-12.5)
print g # solid 1 faces 11 volume 15552
値を空白で区切って並べます。出力は info の診断(コード print)として、poly verify の報告、
--json の diagnostics、Live のステータス行に出ます。stdout には出ません。
ひとつの値だけを知りたいときは、ファイルを変えずに poly measure m.poly 'g.bbox.z' でも読めます。
ブーリアン演算(ソースコマンド)
union、diff、inter はパイプなしのソースコマンドとして複数形状を結合できます:
union [box 10 10 10, sphere 7] # 形状を結合
diff [box 10 10 10, sphere 7] # 2番目を1番目から引く
inter [box 10 10 10, sphere 7] # 交差部分のみ残す
パイプ操作としても使えます:
box 10 10 10 | union (sphere 7)
box 10 10 10 | diff (cylinder 3 20)
注意: [] は常にリストリテラルです。形状を結合するには union [...] と明示的に書きます。式の中では形状演算子 a + b / a - b / a * b も使えます(「形状演算子」参照)。
配置
at: は形状を指定位置に配置する名前付き引数です。at の直後にコロン : を付けて書きます。
カッコのルール:
- 単純な座標(リテラル・変数): カッコ省略可(推奨)。
at:20 0 0 - 式を含む場合: カッコ必須。
at:(x+1, y+1) - 座標リスト: ブラケット必須。
at:[(0,0), (10,0)] - カッコ付き
at:(x, y)も常に有効。 - 配列複製には
| gridや| polarパイプ操作を使います。
sphere 5 at:20 0 0 # 単純な位置(カッコ省略推奨)
sphere 5 at:x y # 変数もOK
sphere 5 at:(x+1, y+1) # 式を含む場合はカッコ必須
sphere 5 at:[(0,0), (10,0), (20,0)] # 複数位置(ブラケット必須)
sphere 5 | polar 6 20 # 円形配列(パイプ操作)
sphere 5 | grid 3 3 20 # 格子配列(パイプ操作)
同様に、angle: 名前付き引数で形状を回転配置できます:
rect 10 5 angle:45 # 45度回転した矩形
コメント
# これはコメントです