2018年04月
2018年04月26日
ビットマップペイントツールのチュートリアルをやってみた その140 3dsmax 2018
引き続きMAXScriptマニュアルに載っている「チュートリアル-ビットマップペイントツールを9つの簡単なステップで作成する」 の続きを考えて見たい。
UV不連続境界エッジを見つける事は出来るようになった。次はこれをどう扱うかだけど、不連続境界エッジではみ出して塗らなければならないのは下の画像のような時だ。
UVマップ上ではこんな感じで、実際にはペイントエリア内がグラデーションの付いた円などで塗られたりするわけだ。そしてはみ出してペイントさせなきゃならないのはそのエリアが不連続境界を横断している部分だけだ。
プログラムはブラシ立方体に交差する面を1枚ずつ取り出して、その面をブラシ立方体でトリミングし、生成された面の内部を塗って行くようになっているので、面を取り出した時に面の3つのエッジについて不連続境界かどうかを調べてエッジにフラグを立てて、トリム後のエッジにもそれが残っていくようにして行けば、生成されたペイントエリアを塗り潰す時にどのエッジをはみ出して塗ればいいのかわかるし、はみ出すのがどの向きなのか、また境界部分の色もわかるので、なんとかなりそうな感じだ。
続きはまた次回。
GW中は定期更新はお休みします。次回定期更新は5月7日になります。
2018年04月25日
プロシージャルモデリングについて調べてみた その40 modo11.2v2
引き続き「Fusion Damage Trim」を調べてみたい。
前回は「fDamage Push」オペレータを調べた。今回は「fDamage」アイテムを生成するオペレータの最後「fDamage Poly Bevel」を調べてみたい。
このオペレータは「ポリゴンベベル」オペレータで、デフォルトでは無効になっている。なぜか「シフト」パラメータには1.2mが設定されている。
そしてベベルの対象になるポリゴンは、「select By Selection Set」オペレータによって限定されている。このオペレータで設定されるポリゴンは「fDamage」と言う名前の選択セットだ。
しかし探してみてもこの名前の選択セットを使っている部分が見つからない。つまり「fDamage Poly Bevel」を有効にしても特に何も起こらない。
このオペレータはどういう用途を想定しているのかよくわからないけど、使うとしたら「fDamage」の元になっている「fDamage Cluster Sources」フォルダに入っているメッシュオブジェクトのポリゴンに「fDamage」という名前でポリゴン選択セットを作ればベベルオペレータの効果を適用する事が出来る。
例えば「fDamage Cluster Sources」フォルダ内にある「fD Pyramid」のポリゴンを下のように選択して、「fDamage」という名前で選択セットを作成する。
この状態で「fDamage Poly Bevel」を有効にすると下のようにこのメッシュに対応するメッシュにベベルがかかる事がわかる。
「ポリゴンベベル」オペレータは「シフト」や「インセット」パラメータにランダム要素を加える「+/−」パラメータなどもあるし、上のようにグループでベベルせずにポリゴンごとにベベルする事でさらに複雑な凹凸をつける事も出来るので、より複雑なパターンを作りたい時に使ってくれと言う仕様なのかな?
続きはまた次回。
2018年04月24日
ビットマップペイントツールのチュートリアルをやってみた その139 3dsmax 2018
引き続きMAXScriptマニュアルに載っている「チュートリアル-ビットマップペイントツールを9つの簡単なステップで作成する」 の続きを考えて見たい。
今回は前回作ったプログラムについて。
fn is_unce v1 v2 obj tch= ( faces1 = meshop.getMapFacesUsingMapVert obj tch #{v1} faces2 = meshop.getMapFacesUsingMapVert obj tch #{v2} if (faces1 * faces2).numberSet == 1 then return true return false ) obj = $Teapot001 tchannel = 1 fn v2e v1 v2 obj = ( obj.modifiers[#unwrap_uvw].selectVerticesByNode #{v1,v2} obj obj.modifiers[#unwrap_uvw].vertToEdgeSelect() return obj.modifiers[#unwrap_uvw].getSelectedEdges() ) ucedges = #{} for f = 1 to obj.faces.count do ( theVerts = (meshop.getMapVertsUsingMapFace obj tchannel #(f)) as array if is_unce theVerts[1] theVerts[2] obj tchannel then ucedges += (v2e theVerts[1] theVerts[2] obj) if is_unce theVerts[2] theVerts[3] obj tchannel then ucedges += (v2e theVerts[2] theVerts[3] obj) if is_unce theVerts[3] theVerts[1] obj tchannel then ucedges += (v2e theVerts[3] theVerts[1] obj) ) subobjectLevel = 2 obj.modifiers[#unwrap_uvw].selectEdgesByNode ucedges obj
まず不連続UV境界をチェックしているのが「is_unce()」ファンクションだ。引数「v1」「v2」に不連続境界かどうかを調べたいエッジ両端のUVマップの頂点インデックスが渡されて、「meshop.getMapFacesUsingMapVert」でそれぞれの頂点を含むUV面のビット配列が「faces1」「faces2」に得られる。ビット配列の乗算は2つの配列の共通する要素を抽出する計算になり、「numberSet」はその配列の中の要素数を返す。これが1なら2つの頂点を含む面が1つしかないので不連続境界という事になり、ファンクションの戻り値としてtrueを返す。それ以外はfalseを返す。
「v2e()」ファンクションは2つのUVマップの頂点インデックス「v1」「v2」からその頂点を両端に持つエッジのインデックス番号をビット配列で求めるものだ。
サンプルで使った「Teapot001」には「UVWアンラップ」モディファイヤが追加されえちて、その「selectVerticesByNode()」メソッドで2点の頂点を選択状態にして、「vertToEdgeSelect()」でその2点をエッジに変換する事で2点を両端に持つエッジを選択状態にする。そして最後に「getSelectedEdges()」で選択されているエッジをビット配列で取得して返す。オブジェクトに設定されている「UVWアンラップ」モディファイヤのメソッドは「オブジェクト.modifiers[#unwrap_uvw].メソッド」でアクセス出来る。
最後はメイン部分で、不連続境界エッジのインデックス番号を格納するビット配列「ucedges」を用意しておいて、オブジェクトに含まれる面のインデックス番号を1番から順に最後まで変数「f」に入れて、そこから「getMapVertsUsingMapFace()」でその面に含まれる3つの頂点番号を「theVerts」に配列に変換して取得する。
その3つの頂点から2つを組みあわせを変えながら「is_unce()」に渡して不連続境界かどうか調べて、そうだったらその2点から「v2e()」でエッジ配列を取得して、「ucedges」配列に追加する。
これを全ての面に対して行えば全ての不連続境界エッジのインデックス番号が「ucedges」に入る。
最後にサブオブジェクトレベルをエッジに切り替えて、「selectEdgesByNode()」で「ucedges」に入っているエッジ全てを選択状態にする。
続きはまた次回。
2018年04月23日
プロシージャルモデリングについて調べてみた その39 modo11.2v2
引き続き「Fusion Damage Trim」を調べてみたい。
前回は「fDamage Smooth Shift」オペレータを調べた。今回はその上の「fDamage Push」を調べてみたい。
「fDamage Push」は「プッシュインフルエンス」オペレータで、デフォルト状態では無効になっている。「距離」パラメータは「fDamage Cluster」ロケータの「Noise Push」ユーザーチャンネルに接続されていて、「fDamage Cluster」ロケータをビューポートでクリックする事で設定パネルが出て調整できる。今まで調べてきたものもそうなんだけど、せっかくこういう仕組みが設定されているなら、いちいち「メッシュオペレータ」リストを開けてオペレータを有効にするより、「有効」チャンネルを「fDamage Cluster」のユーザーチャンネルとして他のパラメータと一緒にポップアップパネルに出すようにすればいいんじゃないのかな。
この「プッシュインフルエンス」オペレータは「距離」パラメータに従って頂点を法線の平均方向に押し出すものだ。
そのまま適用すればこのように均等に押し出される。
しかし「fDamage Push」の「フォールオフ」には「fDamage Texture Falloff」という「テクスチャフォールオフ」オペレータが設定されていて、テクスチャのパターンの濃淡によってプッシュされる「距離」の倍率がマッピングされるようになっている。また、トランスフォームの「スケール」パラメータが5%になっていて、ノイズパターンを細かくしている。この値を調整する事でノイズのパターンのスケールが変更できる。
そしてそのテクスチャは「ノイズ-Hybrid」が設定されている。ノイズのパターンは-1000%〜1000%で、不透明度52%になっているので、±520%のノイズに「距離」パラメータがかかった距離だけ頂点が移動する事になる。値がプラスもマイナスも同じ量だけ変動するのでプッシュがかかったからと言ってオリジナルの形状より概観が大きくなるような事は無い。
このノイズのパターンはこんな感じだ。
「fDamage Push」を有効にして「Noise Push」パラメータを増やすと以下のようにランダムな凹凸がついた形状に変化する。
続きはまた次回。
2018年04月19日
ビットマップペイントツールのチュートリアルをやってみた その138 3dsmax 2018
引き続きMAXScriptマニュアルに載っている「チュートリアル-ビットマップペイントツールを9つの簡単なステップで作成する」 の続きを考えて見たい。
前回の手順で不連続エッジを全て選択するプログラムを作ってみた。下がそのプログラムだ。
fn is_unce v1 v2 obj tch= ( faces1 = meshop.getMapFacesUsingMapVert obj tch #{v1} faces2 = meshop.getMapFacesUsingMapVert obj tch #{v2} if (faces1 * faces2).numberSet == 1 then return true return false ) obj = $Teapot001 tchannel = 1 fn v2e v1 v2 obj = ( obj.modifiers[#unwrap_uvw].selectVerticesByNode #{v1,v2} obj obj.modifiers[#unwrap_uvw].vertToEdgeSelect() return obj.modifiers[#unwrap_uvw].getSelectedEdges() ) ucedges = #{} for f = 1 to obj.faces.count do ( theVerts = (meshop.getMapVertsUsingMapFace obj tchannel #(f)) as array if is_unce theVerts[1] theVerts[2] obj tchannel then ucedges += (v2e theVerts[1] theVerts[2] obj) if is_unce theVerts[2] theVerts[3] obj tchannel then ucedges += (v2e theVerts[2] theVerts[3] obj) if is_unce theVerts[3] theVerts[1] obj tchannel then ucedges += (v2e theVerts[3] theVerts[1] obj) ) subobjectLevel = 2 obj.modifiers[#unwrap_uvw].selectEdgesByNode ucedges obj
シーンに「Teapot001」を1つ作成して、「UVWアンラップ」モディファイヤを追加する。
わかりやすいように「UVパッキング」で並べなおした。
そしてプログラムを実行してみた。結果が以下で、UVマップの切断部分のエッジすべてが選択されているのがわかる。
続きはまた次回。