2019年05月28日

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

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

前回「boeders」に各三角面の3つのエッジがUVマップの輪郭線かどうかのデータを格納するようにした。

今回はそのデータを使ってようやくはみ出し部分の処理をしていくわけだけど、プライベートメンバの初期化位置をちょっと変更した。そして新たに「bareas」メンバを追加した。これに輪郭を広げた部分をブラシ立方体でトリムした多角形のUVマップを格納する。従来の「maps」と分けたのははみ出し塗りを本体の塗りから分離して、あとから塗ることではみ出し部分が本体のペイントを上塗りするのを防ぐことが出来るからだ。

struct objectPaint (
  public
    maxFaceRadius = 40.0,
    brushsize=10,
    BrushShape = 2,
    BrushColor = black,
    theObj,
    brushtransform,
    bitmapX = 512,
    bitmapY = 512,
    temp_bitmap_filename = (getDir #preview +"/microPaint_temp2.tga"),
    theBitmap,
    checkBitmap,
    overpaint = 0.01,

  private
    sanim,
    tmpm,
    maps,
    muw,
    cmuw = false,
    offpoint,
    borders,
    bareas,

「clipface()」は元に戻した。

fn clipface &vlist w2b = ( 
  for i = 0 to 5 do (
    vtmp = #()
    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]
      ) else if st[1] == 2 then (
        append vtmp vlist[j] 
        append vtmp (innerpoint vlist[j] vlist[j+1] st[2])
      ) else if st[1] == 1 then (
        append vtmp (innerpoint vlist[j] vlist[j+1] st[2])
      )
    )
    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]
    ) else if st[1] == 2 then (
      append vtmp vlist[vlist.count]
      append vtmp (innerpoint vlist[vlist.count] vlist[1] st[2])
    ) else if st[1] == 1 then (
      append vtmp (innerpoint vlist[vlist.count] vlist[1] st[2])
    )
    vlist = vtmp
  )
),

「get_offpoints()」にプライベートメンバの初期化を移した。

fn get_offpoints = (
  offpoint = #()
  borders = #()
  useEdges = #()
  islands = #()

  muw = theObj.modifiers[#unwrap_uvw]

「crossFaceMaps()」を書き換えて輪郭エッジとそれを膨らませたエッジの間の四角い領域を「barea」として生成して、それを「clipface()」を使ってブラシ立方体にトリムさせてはみ出し部分の塗り領域を生成して「bareas」に追加するようにした。その際、ビットマップ座標からワールド座標に変換するマトリクスを一緒につけることであるピクセルのブラシ中心からの距離などが算出できるようにした。

fn crossFaceMaps theMesh theChannel mt2b =
(
  invBrushTransform = inverse( brushtransform)
  crossfaces = selectcrossface()
  maps = #()
  bareas = #()

  for faceIndex in crossfaces do (
    vlist = #()

    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])

    mg2b = mg2t * mt2b
    mw2b = (inverse mg2w) * mg2b
    mb2w = inverse mw2b
    mt2w = (inverse mg2t) * mg2w
    
    for i = 1 to 3 do (
      if borders[faceIndex][i] then (
        j = i + 1
        if j == 4 then j = 1
        barea = #()
        append barea vlist[i]
        append barea vlist[j]
        offpoint[texFace[j]][3] = 1.0
        append barea (offpoint[texFace[j]] * mt2w)
        offpoint[texFace[i]][3] = 1.0
        append barea (offpoint[texFace[i]] * mt2w)

        clipface &barea invBrushTransform 

        if barea.count != 0 then (
          bmaplist =  #()
          for v in barea do (
            append bmaplist (v * mw2b)
          )
          append bareas #(bmaplist,mb2w)
        )
      )
    )
    
    clipface &vlist invBrushTransform 

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

      for v in vlist do (
        mp = v * mw2b
        append maplist mp
      )

      append maps #(maplist , mb2w)
    )
  )
),

続きはまた次回。

maxまとめページ



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

この記事にコメントする

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

Archives