Fusion360曲面生成スクリプト の履歴(No.3)
更新歯車について勉強するシリーズ†
- 工作/歯車について勉強する 歯車の形状についての基礎
- 工作/歯車について勉強する2 仮想的なラックを使って実用的な歯車形状を切り出す話
- 工作/歯車について勉強する3 歯車に関するいろいろな計算機
- 工作/歯車について勉強する4 転位歯車の中心間距離と逆インボリュート関数
- 工作/Fusion360歯車スクリプト 勉強した結果を使って作ってみました
- 工作/Fusion360歯車切削スクリプト Fusion 360 内で歯車の歯切りを行うスクリプトです
- 工作/Fusion360曲面生成スクリプト 歯切り結果の表面をきれいにするスクリプトです
複数の曲線を繋いで曲面を生成したい†
Fusion 360 内でボディを徐々に動かしながら要素除去法によって成形したソリッドの 表面には連続する曲面が多数存在して非常に複雑な形になってしまう。
そこで、連続する曲線を結ぶ滑らかな曲面を作ることで形状を単純化したい。
これは出来上がる物の仕上がりの問題だけじゃなく、Fusion 360 の動作が重くなったり固まったりするのを防ぐ意味でもかなり重要だ。
目次†
始めに手動でやる方法を説明して、最後に手順の一部を自動化するスクリプトを紹介します。
手作業でやる方法†
サーフェスタブの「ロフト」と「厚み」を使うといい†
- サーフェスタブにあるロフトを使うと一連の曲線を繋いで曲面を生成可能
- 曲面に厚みを持たせてソリッドボディを作成可能
- プレス・プルで面をせり出して
- 元の形状から引き算する
というのが一連の流れになります。
ロフトを使い曲面を作成†
これは要素除去法で切り出したクラウンギアの半ピッチ分。 上でも見た複雑な形状をしている。
そこでサーフェスタブにあるロフトを選択して、1つの曲面を定義する一連のカーブを選択します。
OK を押すとサーフェスが生成されます。
「厚み」を使って押し出す & 「プレス・プル」で厚みを増す†
通常の「押し出し」は平面図形にしか効かないので、このような曲面を押し出すには「厚み」を使います。
押し出したらそのまま元の形状から引き算したいところなのですが、大抵の場合、元の形状とのオーバーラップが微妙すぎるというエラーが出てしまいます。
そこで押し出した形状をひっくり返して元の形状と接する面を選択。「プレス・プル」を使って 0.01 mm ~ 0.02 mm 程度押し出します。
元の形状から引き算する†
これで十分な重なりができるため元の形状から引き算できます。
が、その前に、よく見ると端の部分で長さが足りておらず切り残しが発生してしまう状況にありました。
そこで端面を選択してプレス・プルで切り取りたい部分が十分隠れるまで伸ばしてやります。
そうすれば切り取りを行えて、切り取った結果はきれいな曲面になってくれます・・・
実は、端の部分をプレス・プルで延ばした際、大きな数値を入れるとエラーになって十分に延ばすことができなかったため、結局切り残しが発生してしまっていました。
この部分はプレス・プルで押し込んで目立たなくしました。
こういう細かい修正がいろいろ必要になるあたり、面倒さが残ります・・・
次はこの部分†
同様の手順で滑らかにします。
そしてここ†
上の端が足りていないので延長してから切り取ります。
最後にここ†
この部分は苦労しました。
1枚の曲面が広範囲に広がっていてなおかつ結構な曲率を持っているせいで、 うかつにたくさん曲線を選んでしまうとロフトが失敗してしまいます。
さらにはロフトがうまく行っても「厚み」を付けるところで失敗したり、
「厚み」までついても「プレス・プル」で失敗したり、
散々でした。
結局大きな1枚の曲面として扱うのをあきらめて、2枚に分割してそれぞれ作業。 しかもいくつか「選んじゃダメな曲線」があったのでそれを飛ばしてやることで何とか切り取ることができました。
鏡面対称&円周上に配列&結合で完成†
気になる部分†
どうしても継ぎ目に段差が残ります。
ただまあこの段差の大きさは 0.02 mm とかそのくらいなので、 3D プリンタで出力して遊ぶ分にはそれほど問題にならないのではないかと期待しています。。。
実際にはどうなのか???
スクリプト†
曲線を選択すると繋いで厚みを付けるところまでを行うスクリプトです。
厚みを付けるところでエラーが出るかどうかがすぐに分かるだけでもかなり助かると思います。
本当はプレス・プルまでスクリプトでやってしまいたいところなのだけれど、 残念ながらプレス・プルはスクリプトから呼び出すことはできないのだそうで。。。
せめて「生成した面」を選択した状態でスクリプトを終了できるなら、 プレス・プルのコマンド起動まではスクリプトで可能なので便利に使えそうなのだけれど、 「生成した面」を選択した状態で終える方法もよく分からず、残念ながらそのままになっています。
厚みを持たせると「生成した面」が相手の部材側を向くことになって、 プレス・プルするときに選択しづらいので、選択だけでもできると便利なのに。
ライセンス†
MIT とします。
主に自分の勉強のために作っているものですのでいろいろおかしなところがあると思いますが、 利用者の責任の下、ご自由にお使いください。
ダウンロード&更新履歴†
プレビューの正しい方法とかエラーハンドリングとかよくわかってないです。。。
ウォームホイールを切ってみた†
表面をきれいにするの、ものすごく大変。
しかも、どうしてもきれいにしきれないところが残ってしまう・・・
4条のウォームと組み合わせて使うウォームホイールを作りたい。
歯切りを行う際にホブとして用いるウォームは通常とは逆に歯元の丈を 1.0、歯末の丈を 1.25 にした。
後は
- 回転複製して共通部分を取り出すことで正しい歯形を得て
- その部分を切り出して、さらに半分だけにして
- 個々の曲面に対して近似曲面を作成しては除去を繰り返す
- 歯切りを行う際にホブとして用いるウォームはバックラッシュゼロで作成したので
- 表面をバックラッシュ分だけ削りながらきれいな面を出していく
- だいたい満足したら回転複製&共通部分を取り出すことできれいな面だけで構成されるパーツを得て、
- 回転複製を繰り返して全パーツを揃えたら結合する
「個々の曲面に対して近似曲面を作成しては除去を繰り返す」の作業が無茶苦茶しんどい・・・
LANG: p5js_live // =============== ここが設定 const gif_url = 'https://dora.bk.tsukuba.ac.jp/~takeuchi/?plugin=attach&refer=%E5%B7%A5%E4%BD%9C%2FFusion360%E6%9B%B2%E9%9D%A2%E7%94%9F%E6%88%90%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88&openfile=worm_wheelA10.gif'; const multi = 1; // スライダーは multi 回ループで最大値になる const fps = 1; // 描画頻度 (frame per second) const maxWidth = 600; // 横幅最大値 // ================ ここから下は汎用コード let gif = null; let frameSlider = null; let w, h; p.preload = () => gif = p.loadImage(gif_url); const draw = () => { let index = frameSlider.value(); gif.setFrame(index % gif.numFrames()); // フレームを選択して p.image(gif, 0, 0, w, h); // 描画 } p.setup = () => { p.frameRate(fps); w = Math.min(maxWidth, gif.width); h = gif.height * w / gif.width; p.createCanvas(w, h + 20); frameSlider = p.createSlider(0, gif.numFrames() * multi - 1); frameSlider.value(0); frameSlider.position(0, h); frameSlider.size(w); frameSlider.input(draw); draw(); } p.draw = () => { if(p.mouseIsPressed) return; frameSlider.value((frameSlider.value() + 1) % (gif.numFrames() * multi)); draw(); }
ウォームと合わせて回してみます。
LANG: p5js_live // =============== ここが設定 const gif_url = 'https://dora.bk.tsukuba.ac.jp/~takeuchi/?plugin=attach&refer=%E5%B7%A5%E4%BD%9C%2FFusion360%E6%9B%B2%E9%9D%A2%E7%94%9F%E6%88%90%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88&openfile=worm_wheelA11.gif'; const multi = 10; // スライダーは multi 回ループで最大値になる const fps = 10; // 描画頻度 (frame per second) const maxWidth = 600; // 横幅最大値 // ================ ここから下は汎用コード let gif = null; let frameSlider = null; let w, h; p.preload = () => gif = p.loadImage(gif_url); const draw = () => { let index = frameSlider.value(); gif.setFrame(index % gif.numFrames()); // フレームを選択して p.image(gif, 0, 0, w, h); // 描画 } p.setup = () => { p.frameRate(fps); w = Math.min(maxWidth, gif.width); h = gif.height * w / gif.width; p.createCanvas(w, h + 20); frameSlider = p.createSlider(0, gif.numFrames() * multi - 1); frameSlider.value(0); frameSlider.position(0, h); frameSlider.size(w); frameSlider.input(draw); draw(); } p.draw = () => { if(p.mouseIsPressed) return; frameSlider.value((frameSlider.value() + 1) % (gif.numFrames() * multi)); draw(); }