2019年7月3日水曜日

輪郭

 中間ファイルをゴニョゴニョするのも飽きてきたので、一旦違うことをやってみる。
 そもそも、なぜSVGやらHP-GLやらガーバーやらを扱っているかというと、結局は銅箔パターンのラスタ画像がほしいだけの話で、それなのにKiCADのヤツがベクタしか吐けないなんて贅沢を言うから苦労しているわけで。
 他のCAD(MBEとか)であれば、直接ラスタ画像を吐けるので、まずは目的の操作(最終的にNCプログラムを出したい)を実現できるかを試すために、とりあえずMBEからラスタを吐いて処理してみた。

***

 MBEは、解像度が最大で2400DPIまでしか指定できない。2600DPIまで指定できれば、1mmあたり100pxと扱いやすい解像度になるのだが、今回は1270DPIで、50ピクセルで1mmとしてみた。
 想定する工具はΦ0.3mmなので、銅箔パターンから外側に7.5ピクセル分オフセットした幅1の線が得られるまでを、今回の目標とした。







 上から、元画像、1回目の膨張、2回目の膨張、1回目と2回目の膨張のXOR、元画像とXORを重ねた図、という並び。
 1回目の膨張では、ツールパスの半径分の7ピクセルを膨張させている。2回目の膨張は1を指定しており、次のXORで2回の膨張の差分を得ている。
 1回目の膨張は工具半径の補正を目的としており、2回目の膨張は幅1pxの線を得ることを目的としている。

***

 ということで、オフセットした輪郭線を得るのは、簡単に処理ができる。
 後処理は簡単で、中間形式のパーサーが大変そうだな、という予想は、あながち外れていない感じだ。もっとも、この後(輪郭線→NCプログラム)が面倒なわけだが。

 ざっと見てみると、ギャップが狭い部分(右側中段のランドのあたりとか)で、複数の輪郭線が接している領域がある。この部分は、線の幅が1という前提が適用できないので、なかなか難しそうな気がする。

 NCプログラムは、輪郭線のピクセルをすべてG1で吐いてしまえば楽なのだが、このサンプル画像程度でも7千ピクセル以上の点があるので、実際の基板では膨大な点数になることが予想される。それに、NCコントローラーは1行読み込んで解析して処理するのにもある程度の時間がかかるので、あまりにも行数が多いとかなり遅くなってしまうと予想される。
 ということで、ある程度端折って吐き出す必要がある。
 例えば、前回のG1位置から0.5mm離れた場合は新しいG1を出す、みたいな処理でもいいし、曲線部分はそのようにする必要があるが、直線部分はもう少し省略したい。
 ベクトル演算(整数近似でいい)を使えば、直線判定は可能だろうから、それで直線から逸脱した場合に、その前の点に対してG1を司令する、というふうになるんだろうか。まぁ、まずは0.25mmとかのしきい値でコンスタントにG1を出して、ある程度ちゃんと動くようになったら直線は1本のG1で、という感じかなぁ。

***

 ケースは明日届くんだけど、試しに寸法を机に重ねてみたら、予想以上にデカイ。相当片付けないと部屋に置けないぞ。。。制御基板や集塵機だけじゃなく、鉛蓄電池とかも問題なく入りそうな気がする。ちゃんと作り込めば丸1日くらい完全にスタンドアロンで動きそうだな。

***

 画像データからNCプログラムに変換するソフトなんて、探せばいろいろあるだろうに、なんでこんな苦労してるんだか。。

***
追記

 輪郭線をトレースしてPoint[][]に変換し、Graphics.DrawLinesを複数回呼び出してみた。


 やはり輪郭線が密集する部分が鬼門のようだ。
 輪郭線のパスは、可能な限りベクトルが変化しないような操作が欲しい。この画像のような、狭い範囲で複数のパスが密集するのは、あまり良くない。

 解決策としては、例えば元画像をラベリングし、唯一の連続した領域に対して膨張や輪郭抽出を行い、輪郭をトレースすれば、一つの領域を一筆書きで一周できる。
 ただ、ラベリングアルゴリズムは相当に面倒で、自前で実装するには難易度が高い。テキトーなソースコードをコピペしてくるのもなんだかなぁ。

 とりあえず、Point[][]で隣接した輪郭線のデータを取り出せるようになったので、このデータの後処理で大量のG1だったり、最小限のG1だったり、というデータに変換できるようになる。
 単純に電気回路として最低限の切削を行うなら、輪郭線からG1を作ればいいのだけど、それでは浮島ができてしまうので、それを除去する方法を考える必要がある。
 どういうアルゴリズムで処理するのがいいのかねぇ。適当なオーバーラップを考慮した膨張・輪郭抽出を繰り返していくのがいいかな? とりあえずその方向でやってみよう。

***
追記

 膨張を繰り返してトレースしてみた。


 イーカンジ

 最大1.41pixの間隔で点が打ってあるから、データは相当な量になる。これを適当にフィルタリングして、各線の間に高さ操作とかも加えれば、NCプログラムとして吐き出せるようになる。はず。
 線間の移動を、一番近い点に飛ぶ、みたいな挙動にすれば多少は高速化できるけど、総当たりで調べると相当な計算量になるはず。そもそも線と線の間はG0で移動するわけだから、移動時間はさほどの量にはならないはず。

 あとは、貫通穴とか輪郭の取扱をどうするかだなぁ。
 工具が0.3mmだから、パッドの内径を0.5mmくらいにすれば、パッドの中央にマーキングできるので、ボール盤とかで穴開けるときは便利そう。
 輪郭に関してはどうすっかなぁ。輪郭線部分の銅箔を剥ぐようなデータを作って、ミニルータで切るとか?
 CAM側の都合で言うと、輪郭線や貫通穴は深く加工すればいいわけで、「ここは銅箔剥ぐだけですよ」「ここは深く切りますよ」という情報さえあれば、そういうNCプログラムを作ることはできる。ただ、MBEでラスタを出すと、線や面の種類に関する情報はなくなるので、CAM側で自動的に判定することはできない。一番外側を輪郭線として扱うとか、一番外側の輪郭からある程度オフセットした部分を輪郭として使う(ベタ面を使う前提)とか、いろいろやり方はあるし、貫通穴に関してはドリルファイルとかがあるはずなので、そっちを使うという手もある。

***
追記

 ラベリングを通してみた。



 ラベリングアルゴリズムはもっと手間取るかなと思ってたけど、思ったよりは簡単に実装できた。さすがに何回もフルスクラッチしてるだけあって手慣れてきた(おい

 2枚目の画像は、黒い部分が残す領域。左上の1枚は反転されてるけど。
 思ったけど、ラベリングしてしまうと、工具直径より狭い部分でも気にせず切削してしまうので、必要なパターンを破壊しそうな気がする。まぁ、それを避けようとすると狭い部分は短絡してしまうので、どっちもどっちな気がする。
 狭いパターンを破壊しないようにするなら、ラベリングしないで得た輪郭とANDを取れば良いはず。最悪でも短絡は避けたい場合は、ラベリングした輪郭だけで切削すればいい。

0 件のコメント:

コメントを投稿