2019年05月16日

ビットマップペイントツールのチュートリアルをやってみた その223 3dsmax 2019

引き続きMAXScriptマニュアルに載っている「チュートリアル-ビットマップペイントツールを9つの簡単なステップで作成する」 の続きを考えて見たい。

さっそくクリップ処理する三角面の頂点に対応する「offpoint」に入っている頂点データをビットマップ座標系に変換してから「olist」配列に格納して、「clipface」に渡して、「vlist」のクリップと同様の処理を加えてみた。「offpoint」は輪郭線上の頂点以外は「undefined」が入っているので、その時は処理をスキップしている。

fn crossFaceMaps theMesh theChannel mt2b =
(
  invBrushTransform = inverse( brushtransform)
  crossfaces = selectcrossface()
  for faceIndex in crossfaces do (
    vlist = #()
    olist = #()
    sufFace = getFace theMesh  faceIndex
    append vlist (getVert theMesh sufFace.x)
    append vlist (getVert theMesh sufFace.y)
    append vlist (getVert theMesh sufFace.z)
    mg2w=(matrix3 [vlist[1].x,vlist[1].y,vlist[1].z] [vlist[2].x,vlist[2].y,vlist[2].z] [vlist[3].x,vlist[3].y,vlist[3].z] [0,0,0])
    texFace = meshop.getMapFace theMesh theChannel faceIndex
    tv1= meshop.getMapVert theMesh theChannel texFace.x
    tv2= meshop.getMapVert theMesh theChannel texFace.y
    tv3= meshop.getMapVert theMesh theChannel texFace.z
    mg2t=(matrix3 [tv1.x,tv1.y,1] [tv2.x,tv2.y,1] [tv3.x,tv3.y,1] [0,0,0])
    if offpoint[texFace.x] != undefined then (
      offpoint[texFace.x][3] = 1.0
      append olist (offpoint[texFace.x] * mt2b)
    )else (append olist undefined )
    if offpoint[texFace.y] != undefined then (
      offpoint[texFace.y][3] = 1.0
      append olist (offpoint[texFace.y] * mt2b)
    )else (append olist undefined )
    if offpoint[texFace.z] != undefined then (
      offpoint[texFace.z][3] = 1.0
      append olist (offpoint[texFace.z] * mt2b)
    )else (append olist undefined )

    mg2b = mg2t * mt2b
    mb2g = inverse mg2b
    mb2w = mb2g * mg2w
    
    clipface &vlist &olist invBrushTransform 

    if vlist.count == 0 then continue
    maplist =  #()

    for v in vlist do (
      mp = (meshop.getBaryCoords theMesh faceIndex v) * mg2b
      append maplist mp
    )
    append maps #(maplist , mb2w, olist)      )
),

そして「clipface()」に処理を追加した。

fn clipface &vlist &olist w2b = ( 
  for i = 0 to 5 do (
    vtmp = #()
    otmp = #()
    for j = 1 to (vlist.count - 1) do (
      st = chckClip vlist[j] vlist[j+1] w2b i
      if st[1] == 0 then (
        append vtmp vlist[j]
        append otmp olist[j]
      ) else if st[1] == 2 then (
        append vtmp vlist[j] 
        append vtmp (innerpoint vlist[j] vlist[j+1] st[2])
        append otmp olist[j] 
        if olist[j] != undefined and olist[j+1] != undefined then (
          append otmp (innerpoint olist[j] olist[j+1] st[2])
        ) else ( append otmp undefined )
      ) else if st[1] == 1 then (
        append vtmp (innerpoint vlist[j] vlist[j+1] st[2])
        if olist[j] != undefined and olist[j+1] != undefined then (
          append otmp (innerpoint olist[j] olist[j+1] st[2])
        ) else ( append otmp undefined )
      )
    )
    if vlist.count == 0 then exit
    st = chckClip vlist[vlist.count] vlist[1] w2b i
    if st[1] == 0 then (
        append vtmp vlist[vlist.count]
        append otmp olist[vlist.count]
    ) else if st[1] == 2 then (
      append vtmp vlist[vlist.count]
      append vtmp (innerpoint vlist[vlist.count] vlist[1] st[2])
      append otmp olist[vlist.count]
      if olist[1] != undefined and olist[vlist.count] != undefined then (
        append otmp (innerpoint olist[vlist.count] olist[1] st[2])
      ) else ( append otmp undefined )
    ) else if st[1] == 1 then (
      append vtmp (innerpoint vlist[vlist.count] vlist[1] st[2])
      if olist[1] != undefined and olist[vlist.count] != undefined then (
        append otmp (innerpoint olist[vlist.count] olist[1] st[2])
      ) else ( append otmp undefined )
    )
    vlist = vtmp
    olist = otmp
  )
),

結果を下の三角面からデータを抽出して確認してみた。黒い部分がブラシ立方体でクリッピングされて抽出される部分だ。

fig 1

これがその三角形がトリミングされたところと、オレンジ色の線はその輪郭線を膨らませたエッジがトリミング処理されたもの。矢印の部分がクリッピングされた部分だ。

fig 2

見てわかる通り、クリッピングされる位置がズレてしまって、クリッピングしている位置が一直線上に並んでいない。

これは下のようなコーナーでは膨らませた輪郭線がもとのエッジより長くなってしまうために元のエッジと同じ比率でクリッピングすると、コーナーで伸ばしたぶんだけ切り取る長さも長くなってしまうためだ。

fig 3

それから元のデータが三角形であるために、2本のエッジが輪郭線で、もう1本が輪郭線では無いかどうかを頂点データが有効か無効かだけでは判別できない欠点が出てしまっている。三角形の場合、2つの頂点が有効データで、もう1つが無効データなら、2つの有効頂点の間のエッジのみ有効なのがわかるが、2本のエッジを有効にするには3つの頂点を有効にしなくてはならず、それは3本のエッジが有効の場合と同じになっちゃうからね。

もう少し検討が必要なようだ。

続きはまた次回。

maxまとめページ



take_z_ultima at 11:30│Comments(0)3ds Max | CG

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 

Archives