概要
3Dプリンター便利ですよね。
日常用途でもちょっとした部品を作りたいとき,よく使います。
自分が持っているのはEntina Tina2S
というAmazonで2万ちょっとで変えたものなのですが,
ホビー用3Dプリンターが出たばかりの5-6年前と比べて,低価格でそこそこの精度が出るものが増えた気がします。
https://www.entina3d.com/en-jp/products/entina-tina2s-3d-printers
一方で,3D-CADをどう調達するかが悩みどころです。
自分は仕事で使う有償ソフトで慣れきってしまい,なかなか合うものが見つからない状況でした。
(個人利用無償のFusion360を覚えるのが一番良いのですが)
パラメトリックにモデルを作りたい
一方で,仕事と違ってホビー用途でモデルを作る場合,意外と本格的な3D-CADソフトは適さない状況もあるように感じます。
基本的には図面がない中で作るので,現物を印刷した後でハマらないことに気が付いたり,使っているうちに改善点に気が付いて作り直しになったり...
こういった時に,いちいちCADを開いて,寸法を調整して,STLにエクスポートして,印刷設定して…等々やると大変です。
SolidPython/OpenSCAD
そこで,単純な部品はPythonで生成ロジックを書けると便利です。
SolidPython
を使うと,直方体や円柱,球などの基本的なオブジェクトの作成,移動やスケーリングなどの操作,ブーリアン演算が簡単に行えます。
import subprocess
import numpy as np
import solid as sl
# 支柱
base1 = sl.cube((0.1, 0.1, 3), (0, 0, 0))
base2 = sl.translate([0, 0.8, 0])(base1)
base = base1 + base2
# 段差
steps = []
for z in np.arange(0, 3, 0.5):
step = sl.cube((0.1, 0.8, 0.1))
step_t = sl.translate(v=(0.05, 0, z + 0.25))(step)
steps.append(step_t)
# baseとstepを結合
rudder = base + sum(steps)
# 傾斜
rudder_t = sl.rotate(-20, [0, 1, 0])(rudder)
# 保存
sl.scad_render_to_file(rudder_t, "output.scad")
# openscadでstlに変換する
subprocess.run(["openscad", "-o", "output.stl", "output.scad"])
基本図形の作成
以下のように直方体を配置できます。第1引数は(x, y, z)方向の寸法,第2引数は原点です。
base1 = sl.cube((0.1, 0.1, 3), (0, 0, 0))
幾何変換
平行移動などの変換も簡単です。以下はbase1
というオブジェクトをベクトルv
だけ移動した新規オブジェクトbase_2
を作成しています。
base2 = sl.translate([0, 0.8, 0])(base1)
ブーリアン演算
オブジェクト同士の四則演算でブーリアン演算ができます。これは便利ですね!
# `base1`と`base2`の和
sum = base1 + base2
# 差
diff = base1 - base2
ループ処理
Pythonの基本文法なので言うまでもないですが,以下のようにforループに組み込むことで,繰り返し形状を作成できます。
# 段差
steps = []
for z in np.arange(0, 3, 0.5):
step = sl.cube((0.1, 0.8, 0.1))
step_t = sl.translate(v=(0.05, 0, z + 0.25))(step)
steps.append(step_t)
# baseとstepを結合
rudder = base + sum(steps)
出来上がったもの
梯子ができました。
パラメータを少し変えてみると,
パラメータ化しておくと,このような変更もささっとできるのがいいですね。
螺旋階段
ループ処理の微変更で以下のような形状も作ることができます。
import subprocess
import numpy as np
import solid as sl
# 支柱
base = sl.cylinder(0.1, 6)
# 段差
steps = []
for i, z in enumerate(np.arange(0, 6, 0.2)):
step = sl.cube((0.5, 1.6, 0.1))
step_t = sl.translate(v=(0.05, 0, z + 0.1))(step)
step_r = sl.rotate(30*i, [0, 0, 1])(step_t)
steps.append(step_r)
# baseとstepを結合
rudder = base + sum(steps)
# 保存
sl.scad_render_to_file(rudder, "output.scad")
# openscadでstlに変換する
subprocess.run(["openscad", "-o", "output.stl", "output.scad"])
まとめ
3D-CAD自動化はソフトごとの独自色が強く,基本形状であっても学習のハードルが高いのですが,
SolidPythonであれば,形状作成のロジックさえ固めてしまえば想像以上に短いコードで書けると思います。
そのうちViewerと連携したアプリとか,形状最適化とかもやってみたいと思います。