Si Side Bar Ver2.3.7 ハードエッジを維持しながら法線のロックを解除する
github.com
SIからモデル移植するなど、FBX経由でメッシュを移植した場合、法線のハード・ソフトの情報が失われ、すべて法線ロックされた状態に置き換わってしまいます。
この後ハードエッジを編集するには一旦ロックを解除してすべてがハードエッジになった状態から再設定する必要があるのですが、その手間を軽減するためにハード、ソフト状態を維持したまま法線ロック解除する機能を付けました。
実行すると法線のロック解除とは違い、ハードエッジ情報を保ったままロックを解除します。
Si Side Bar Ver2.3.5 UVを保持しながらフェースを追加する機能
・UVを保持しながらフェースを追加する機能を実装。
境界UV部分では縦エッジを指定すると意図しないUV面になってしまうので、横エッジ指定で追加が推奨です。
・2.3.2でUVを保持しながらエッジを押し出す機能も追加してます。
SI Side Bar
Maya上でのオブジェクト編集をサポートする多機能ツールをリリースしています。
フリーなライセンスなのでご自由にお使いください。
最新版2.3.1
・マウスジェスチャー入力のボタン毎の切り替え機能を追加
PySideでマウスジェスチャー入力してみる
サンプル置いときますね。
SIサイドバーでマウスジェスチャー入力を自前実装したときのサンプルです。
こまかいことは置いといてコードがこちら
実行するとこんな感じでUIの数値をマウスジェスチャーで変更できるようになります。
UIをクリック+ドラッグすると数値が変化、円を描くように数値加算、減算することができます。
マウスの進行方向を一定角度以上に変化させると+-の符号が反転します。
Shift+ドラッグで10、Ctrl+ドラッグで100単位の入力となっています。
どういうことやってるの?
UIをクリックするとPySideのイベントフィルターでマウス位置を取得するようになります。
マウスの座標を一定間隔でサンプルポイントとして取得して、そのベクトルから入力値を決定しています。今回の例は単純に足すか引くかの判定に使用しています。
例えば以下のように緩やかな角度でマウスが進んでいる場合は+1し続けます。
この場合の角度の求め方はそれぞれのサンプルポイントの位置から直前のポイントの位置を引き算し、2本のベクトルのなす角度を算出します。
上記の例ではこのくらい。なす角θは狭くなります。
まっすぐ動いている場合は0°です。
マウスの進行方向を反転したりと、急激な角度変化が起きたときに+-の符号を反転する機能を付けるのにはどんな条件付けが必要でしょうか?
反転するような動きは以下のような感じですね。
この場合の二つのベクトルが成す角はこんな。
急角度で反転するに従い大きくなります。
完全にUターンした場合は180°ですね。
サンプルでは反転する閾値を120°に設定しています。
この仕組みで一定角度以上に動きが変化しなければ円を描くようにマウスで数値加算ができるように、Uターンで加算減算反転を実現しています。
ちなみに
2本のベクトルの角度は
・ベクトルを正規化
・ベクトルの内積をとる
・内積の値を逆コサイン
で求めることができます。
※サンプルの97行目以降参照
求まる値はラジアンですが、わかりやすいように度数法に変換して使用しています。
Mayaの標準モジュールのみで構築する必要があったため正規化や内積を細かく計算していますが、Numpyモジュールがあればもっと簡潔に書けますね。
デスクさん標準でNumpyいれてくらさいまし。
ダイクストラ法とA*アルゴリズムをMaya上でビジュアライズする+おまけ
この記事はMaya Python Advent Calender 19日目の記事です。
ダイクストラ?A*?
聞きなれない方もいらっしゃるかもしれませんが、いわゆる最短経路長問題を解決するアルゴリズムです。
迷路、経路探索というとわかりやすいかもしれません。
このアルゴリズムでは単なる経路探索ではなく距離や移動時間といった重みをつけて探索できます。カーナビなどもこのアルゴリズムが利用されているそうです。
ダイクストラ法
対象の全ノードに対する最短経路を計算し始点と終点を結ぶ最短経路を求めます。
全ノード探索するので処理コストはかかりますが、始点からの最短重みが計算されるのでMayaでいうところのメッシュ形状を考慮したソフト選択とか実装できたりします。
A*(エースター)
ダイクストラ法の発展形。予想される最短ノードから順番に探索し、経路が見つかった処理終了するので計算量が少なく済み圧倒的に早いです。今回の例ではユークリッド距離でヒューリスティック関数を実装しています。
詳しくはググってね☆
実装コードご紹介
例題としてMaya上で選択したメッシュの2頂点感を結ぶ最短経路をもとめるスクリプトを作成してみました。
サンプルとしてXSI男さん(ややHighMesh化)にご協力いただきます。
総頂点数4795となっています。
ダイクストラ法
細かいことは置いといてコードがこちら
任意の2点を選択して実行するとこんな感じで最短経路が求められます。
ログで計算回数と実行時間を確認します。
探索回数28664回、総実行時間2.93sec
といった結果になりました。
念のため両胸ポッチの最短経路も求めておきます。
ははあ、距離2.29ね。
※あくまで念のためです。
A*アルゴリズム
お次はA*で実装した例です。
処理の流れはほぼ同じですが、事前に終点からの直線距離を計算しておき、一番最短である可能性の高いノードから探索していきます。
実行結果は同じ、正しく最短経路が求まっています。
ログを確認してみましょう。
実行時間が0.43sec、計算回数は2456回
約7倍ほど早いですね。
計算量と時間比較
このメッシュ数なので7倍程度の差になっていますが、ダイクストラ法はO(n²)で計算量が増加するのでハイメッシュになればなるほど差が大きくなります。
試しに33458頂点に割りなおして実行すると・・・
総実行時間で17倍程度に差が開きます。
ノード探索の様子をビジュアライズ
ダイクストラとA*、同じようなアルゴリズムなのにどうして大きく差がつくのでしょうか?実際にノード探索がどのように進んでいくのかわかりやすいようにビジュアライズしてみましょう。
題材はXSI男さん(さらにハイメッシュ顔半分)のUV。
この2点間の探索を行います。
ダイクストラをビジュアライズ
始点から周囲に対して均一に探索範囲が広がっていきます。
全ノード探索後に最短ルートが確定しています。
A*をビジュアライズ
終点からのユークリッド距離を基準に探索ノードを決定しながら進んでいきます。
終点付近に近づくにつれ、迷わずノード探索するようになります。
用途に応じて使い分けたいですね。
念のため両胸ポッチの探索もビジュアライズしておきます。
ははあ、こう進んでるんですね。
※あくまで念の(ry
おまけ
以前TKCMさんの記事で紹介されていたメッシュ形状を考慮したソフト選択のFablic_Engenでの実装、どうしてもやってみたくなったので作ってみました。
ソフト選択反映にラグがあるあたりはちょっと劣化版ですが、、
コードはこちら。
実行するとスフィアとUIが取り出されます。
コンポーネントを選択してComputeすると頂点の重みが計算されてソフト選択状態になります。
ノードのエッジ間の距離で重みづけされるので分断されている箇所の距離も正確に考慮されます。
最後に
こちらのサンプルはアルゴリズム初心者がなんとなーく実装したゆるいコードとなっております。
実装面での間違いや速度面の改善案などあればご指摘いただけるとうれしいです。