PyVistaで面が閉じた立体を作ってSTL保存する1つの例

  • このエントリーをはてなブックマークに追加

これまで当ブログではPyVistaを使ってSTLを作ってきましたが、まだ欠落面が存在する3Dモデルでした。ここでは最後の仕上げとして欠落面を閉じた完全な立体を作成、そしてSTLファイルを保存するPythonコードを紹介します。

こんにちは。wat(@watlablog)です。ここではPython/PyVistaで欠落面を閉じたSTLを作成する方法を紹介します

この記事の目標

PythonでSTLの欠落面を閉じる方法を身につける

当WATLABブログでは過去に「PyVistaをインストールしてPythonでSTLを扱う備忘録」や「Python/PyVistaでSTLモデルを座標変換してみた」という記事でPyVistaを使ってSTLファイルの基本的な扱いを学びました。

PyVistaについては上記記事を参照下さい。

ライブラリを使うとびっくりするくらい簡単にSTLファイルの処理ができるのはすごい!

そして「PyVistaで任意サーフェスメッシュを作成してSTL保存する」で断面プロファイルの押し出しによってサーフェスメッシュを作成、STLファイル保存してみました。

この記事ではサーフェス(面)情報のみのSTLファイルを作成しました。この内容は例えばCAEソフト等で結果を出力する観測面を作成する事には役立ちますが、ソリッドモデル(中身の詰まったモデル)への変換を行ったり、3Dプリンタ用のモデルとして使う事はできません。

欠落面というのは下図のような開いた面の事で、欠落面を形成している辺をフリーエッジと呼びます。今回は前回のモデルを使ってこの欠落面を埋め、フリーエッジを無くす事を目標とします。

フリーエッジ/欠落面のサンプル図

コードの方針

本記事のコードを後半に載せますが、コードを理解するためにもコード上で行っている事を事前に図付きで説明しておきます。

輪郭を押し出してサーフェスを作る

まずはサーフェスを作るための輪郭を作りますが、「def NACA4()」という関数を使います。

ここは「PyVistaで任意サーフェスメッシュを作成してSTL保存する」という記事で詳細を説明していますので、まだ読んでいない方は是非ご覧ください。

この記事では下図の結果を得ます。先ほど紹介した欠落面がある状態です。

押し出したサーフェスメッシュ

欠落面を埋める事ができるサーフェスを作る

次に、欠落面を埋める事ができるサーフェスを作成します。
目標としては下図の状態を作るワケですが…現状の筆者のスキルだと少しやっかいな方法で工夫するしかありませんでした。

サイドのサーフェスメッシュ

側面の点列データを抽出して座標変換する

工夫の内容を説明します。
この時点で輪郭のサーフェスメッシュが存在します。そして、このメッシュはデローニー三角形分割によりメッシュを作成しています。

PyVistaのデローニー三角形分割は、どうやらxy方向の点列群に対して処理が行われるようでした。

上記理由から輪郭を押し出す方向をy軸に設定していたわけですが、側面に対しては点群を作っただけでは正常に三角形分割されません。

そのため、下図のように面を作りたい点群(ここではy軸の最大値と最小値とセットになっているxyz座標で定義される点群)を抽出した後にy軸とz軸を入れ替える座標変換を実施します。

座標変換の例

デローニー三角形分割をした後に再び座標変換する

座標変換後であれば、PyVistaのデローニー三角形分割で問題なくサーフェスメッシュを切る事ができます。
2面がくっつかないように1面ずつ切っています。

そしてメッシュを作成した後は、再度y軸とz軸を入れ替えて元の座標系に戻します(下図)。

メッシュ後に座標変換をした例

今回はこのような面倒な処理で側面のメッシュを作成しましたが、もしかしてもっと簡単な方法があるのかも知れませんね。PyVistaで何か良い事例があれば是非知りたい所!

デローニー三角形分割は以下のドキュメントを参考にしました。

PyVista:三角形サーフェスを作成

重複節点をマージする

座標変換して元の位置に戻した側面メッシュは、元のメッシュと重ねる事で見かけ上は一体になっているように見えます。

しかし、下図のように異なる面同士が接続される部分は、頂点(ここでは節点と呼んでいます)が重なっています。これを重複節点と呼びます。

マージ節点

この重複節点はPyVistaであれば「.clean()」にtolerance公差)を設定してマージする事が可能です。

toleranceを大きくとってしまうと、隣接の節点もマージされてしまい形状が破綻します。そのため面の細かさによってtoleranceの値は調整する必要があります。

本コードでは元のサーフェスメッシュ節点数とマージ後のサーフェスメッシュ節点数がイコールになるかどうかを判定して警告文を出すようにしてみました。

.clean()は以下のドキュメントを参考にしました。

PyVista:pyvista.PolyDataFilters.clean

Python/PyVistaで面が閉じた立体を作ってSTL保存する

全コード

以下に全コードを示します。このコードを実行すると「surf_closed.stl」というSTLファイルが作成されます。

やっている事の概要は上に書きましたが、詳しくはコード内のコメントを参照下さい。

他ソフト検証:Blenderでimportしてみた

作成したSTLファイルが他のソフトでも使えるかどうかを確かめるために、3Dモデリングソフトで有名なBlenderでimportしてみました。

結果は正常に読み込まれていました。前回記事の欠落面のある開いたサーフェスメッシュも読み込み可能でしたので、おそらくこのモデルで3Dプリンタ出力とかできるのではないでしょうか?

Blenderで読み込みテスト

僕は(まだ)3Dプリンタを持っていませんが、数学的に自由な曲面を作成して3Dモデルを作る事ができれば、DIYの幅がグッと広がりそうですね!

おまけ1:モデルの拡大縮小

ここで紹介しているモデルは弦長を1として全て比率で寸法を割り振っています。

実際に3Dプリンタ等で実寸法を扱いたい場合は、元の作図式を実寸法に合わせるよう修正するか、出来上がったモデルの拡大縮小処理をする必要があります。

当ブログの過去記事である「Python/PyVistaでSTLモデルを座標変換してみた」ではSTLファイルの拡大縮小の他に、並進移動回転移動を紹介しています。是非組み合わせてみて下さい。

おまけ2:背景を白くしてプロット

おまけとして、白背景でSTLファイルを読み込むコードの例を示します。

下図が白背景プロットの例です。当ブログのアイキャッチ画像(タイトル部分の画像)もこれで作っています。

白背景でSTLファイルを読み込んだ例

まとめ

本記事ではサーフェスメッシュの開いた面、いわゆるフリーエッジによって形成された欠落面を閉じる方法を紹介しました。

PyVistaのデローニー三角形分割.delauney_2d()と重複節点をマージする.clean()を使うのは過去記事と同じですが、座標変換を繰り返すという事を行いました。

…本当はもっと簡単な方法があるのではないか、と思うようなやり方ですが、今のスキルではこれが精一杯のようです。

(欠落面を自動検出してくれてイイ感じに埋めてくれるメソッドとか無いかな???)

ようやく面を閉じた立体モデルを作る事ができるようになりました!これで色々応用に進めそうです!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!

SNSでもご購読できます。

コメントを残す

*