
2025/12/21 2:45
OpenSCADはとても便利ですね。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Summary
著者は、Fusion 360 で作成したバッテリーオーガナイザーを無料のコードベース CAD ツールである OpenSCAD に変換し、プログラミングを学びながらコストを抑えることを目指しています。
彼は行数 (
numRows)、列数 (numColumns) およびバッテリー種別 (batteryType) の変数を設定し、 AA = 15、 AAA = 11、 heightCompartment = 19、 thicknessWall = 1 といった定数を定義します。これらを用いてボックスの幅・長さ・深さを計算し、ネストされたループで穴の格子を生成します。各ループ内では
let() を使って開始位置 (startColumn、startRow) を求めた後、バッテリー穴を表す立方体を移動させます。 difference() 操作により全ての穴が固体ブロックから除去されます。生成されたスクリプトは STL としてエクスポートでき、直接プリントできます。
以前、著者は Fusion 360 でパラメトリック AA/AAA オーガナイザーを作成し Printables に共有しました。本 OpenSCAD バージョンでは
let() 構文が必要かどうかについて少し不確実性がありますが、穴の位置決めには機能することを確認しています。このコーディング手法はベアリングドラフトやスペーサーなど他のシンプルな部品にも拡張できると予想され、スクリプトベース CAD の活用範囲が広がります。
メーカーにとって、この方法は高価なソフトウェアを必要とせず機能的なオーガナイザーや基本部品を作成する障壁を下げるため、ホビイストおよび小規模製造コミュニティで OpenSCAD の採用拡大につながる可能性があります。
本文
OpenSCADで簡単なバッテリーホルダーを設計する
今年初めに、Autodesk Fusion で AA と AAA バッテリー用の非常にシンプルなボックス/オーガナイザーを設計しました。数個の変数を変更するだけでバッテリー種別・サイズや行列数などを調整できるようパラメータ化しており、今日早朝に Printables にアップロードしたところ、この機能がとても便利だと実感しました。そのため、OpenSCAD の基礎を学ぶにはこの設計を再実装するのが良い方法だと思いました。
OpenSCAD はコードを書いてオブジェクトを生成するという全く別のタイプの CAD ツールです。私のバッテリーホルダーは「ボックス+切り込みパターン」というとても単純な構造で、入力パラメータも使うため、新しい言語/ツールへの入門として最適だと判断しました。将来的には、こういったシンプルな設計では Fusion を立ち上げるよりも OpenSCAD の方が効率的になるかもしれません。
チュートリアルを少し進めて、1 時間ほど試行錯誤した結果、以下のようになりました。
battery_holder_generator.scad というファイルです。スライサーでは Fusion モデルが上部に、OpenSCAD の出力が下部に表示されます。
数個の変数―
numRows(行数)、numColumns(列数)、そして batteryType(バッテリー種別)―を変更するだけで、カスタマイズされたバッテリーホルダーをレンダリングできます。生成した STL をスライサーに投入してプリントすれば、重い/高価な CAD ソフトウェアは不要ですし、出力もほぼ同等です。
コメントや情報量の多い出力が無いので、コード本体だけを紹介します:
AA = 15; AAA = 11; heightCompartment = 19; thicknessWall = 1; numRows = 4; numColumns = 10; batteryType = AA; widthBox = (numRows * batteryType) + ((numRows + 1) * thicknessWall); lengthBox = (numColumns * batteryType) + ((numColumns + 1) * thicknessWall); depthBox = heightCompartment + thicknessWall; difference() { cube([lengthBox, widthBox, depthBox]); for (c = [1 : numColumns]) for (r = [1 : numRows]) let ( startColumn = ((c * thicknessWall) + ((c - 1) * batteryType)), startRow = ((r * thicknessWall) + ((r - 1) * batteryType)) ) { translate([startColumn, startRow, thicknessWall]) cube([batteryType, batteryType, heightCompartment + 1]); } }
要するに、まずボックスを描画し、
difference() を使ってバッテリー用の穴を切り取っています。最初の cube() がメインボックスで、二番目の cube()(その個数と位置はネストされたループ内の translate() で決まります)が差し引かれます。
これだけです—かなりシンプルですが、実用的ですね!
私が混乱した点の一つに、なぜループ内で
let() を使って startColumn と startRow を定義する必要があるのかがあります。よく理解できていません…
このテクニックは、より複雑なデザインではあまり役立たないかもしれませんが、ベアリングドリフトやスペーサーなど、実際に非常に便利な単純形状を作る際にはとても有用だと思います。