2005年04月14日

paintWeight

スキンモディファイヤのウェイトをブラシで塗るように編集できるスクリプト、LWのVertexPaintみたいなヤツ
標準機能のペイントウェイトの使い方がよくわからない(使いづらい)ので作ってみた
自分で言うのもなんだけど、とても使いやすい
けど他の作業に移る時に、右クリックやパネルを閉じたりしていないとエラーが出る時があるし
最悪の場合、maxが落ちたり、マウスとキーボードが利かなくなるときがあるという諸刃の剣


 Ofer Zelichover のPaintSelectを参考にした

 

--
--  スキンモディファイヤのウェイトをブラシで塗るように編集できるスクリプト
--  3ds max 5.1
--
macroScript paintWeight category:"HowTo"
(
  local curObj
  local curSkin
  local boneNames = #()
  local brushSize
  local paintBrush
  local weightValue
  local opMode
  local curBone
  local newList = #()
  local vertsList = #()
  local isActive = true

 
  rollout mainPanel "PaintWeight" width:249 height:142
  (
    radiobuttons rdo_operation "Operation" pos:[158,56] width:70 height:78 labels:#("Add", "Sub", "Replace", "Erase") columns:1
    spinner spn_value "Value" pos:[46,57] width:90 height:16 range:[0,1,1] scale:0.01
    dropdownList ddl_bone "Bone" pos:[6,9] width:238 height:41 items:#()
    spinner spn_brushsize "BrushSize" pos:[21,81] width:114 height:16 range:[1,100,5] type:#integer scale:1
    on mainPanel close  do
    (
      isActive = false
      try(destroyDialog mainPanel)catch()
      redrawViews()
    )
    on mainPanel open do
    (
      ddl_bone.items = boneNames
      curBone = skinOps.getSelectedBone curSkin
      ddl_bone.selection = curBone
      opMode = 1
    )
    on rdo_operation changed stat do
    (
      opMode = stat
    )
    on spn_value changed val do
    (
      weightValue = val
    )
    on ddl_bone selected sel do
    (
      curBone = ddl_bone.selection
      skinOps.selectBone curSkin curBone
    )
    on spn_brushsize changed val do
    (
      brushSize = val
    )
  )--rollout
 
  fn isListed vert = (
    local vlist = vertsList + newList
    local result = false
    for v in vlist do
    (
      if v == vert then
      (
        result = true
        exit
      )
    )
    result
  )
 
  fn getVertsInRadius obj pos face r faceList = (
    append faceList face
    local tempVerts = meshOp.getVertsUsingFace obj face
    for v in tempVerts where (distance (meshOp.getVert obj v) pos <= r) do
    (
      if false == (isListed v) then
      (
        append newList v
        local tempFaces = meshOp.getFacesUsingVert obj v
        for f in tempFaces do
        (
          local exists = false
          for ff in faceList do
          (
            if f == ff then
            (
              exists = true
              exit
            )
          )
          if exists == false then
          (
            append faceList f
            getVertsInRadius obj pos f r faceList
          )
        )-- for f
      )
    )-- for v
  )
 
  fn setWeightValue = (
    local val
    case opMode of
    (
      1:(
        for v in newList do
        (
          val = try(skinOps.GetVertexWeight curSkin v curBone)catch(0.0)
          val += weightValue
          skinOps.setVertexWeights curSkin v curBone val
        )
      )
      2:(
        for v in newList do
        (
          val = try(skinOps.GetVertexWeight curSkin v curBone)catch(0.0)
          val -= weightValue
          skinOps.setVertexWeights curSkin v curBone val
        )
      )
      3:(
        for v in newList do
        (
          skinOps.setVertexWeights curSkin v curBone weightValue
        )
      )
      4:(
        for v in newList do
        (
          skinOps.setVertexWeights curSkin v curBone 0
        )
      )
    )
  )
 
  fn paintWeightProc msg ir obj faceNum shift ctrl alt = (
    --disableScreenRedraw()
   
    local brush = paintBrush
    local brushScale = [1,1,1]*((getScreenScaleFactor brush.pos)*0.01)
    try(brush.pos = ir.pos)catch()
    try(brush.dir = ir.dir)catch()
    local r = brushSize * brushScale.x
    try(brush.radius = r)catch()
   
    if ir == undefined then
    (
    )
    else if #mousePoint == msg then
    (
      vertsList = #()
      newList = #()
      getVertsInRadius curObj ir.pos faceNum r #()
      vertsList += newList
      setWeightValue()
    )
    else if #mouseMove == msg then
    (
      newList = #()
      getVertsInRadius curObj ir.pos faceNum r #()
      vertsList += newList
      setWeightValue()
    )
   
    --enableScreenRedraw()
    if (msg != #mouseAbort) and (isActive == true) then #continue
  )
 
  on isEnabled do
  (
    selection.count == 1 and undefined != (try(selection[1].skin)catch(undefined))
  )
 
  on isVisible do
  (
    selection.count == 1 and undefined != (try(selection[1].skin)catch(undefined))
  )
 
  on execute do
  (
    weightValue = 1
    brushSize = 5
    paintBrush = circle name:"paintBrush" radius:brushSize wireColor:(color 230 230 0) displayRenderMesh:false
   
    curObj = selection[1]
    curSkin = curObj.skin
    max modify mode
    modPanel.setCurrentObject curSkin
    subObjectLevel = 1
   
    local numBones = skinOps.getNumberBones curSkin
    boneNames = #()
    mainPanel.ddl_bone.items = #()
    for i=1 to numBones do
    (
      append boneNames (skinOps.getBoneName curSkin i 1)
    )
   
    try(destroyDialog mainPanel)catch()
    createDialog mainPanel
   
    isActive = true
    mouseTrack on:curObj prompt:"" trackCallback:paintWeightProc
    delete paintBrush
    try(destroyDialog mainPanel)catch()
  )
)--macroscript

【関連する記事】
posted by toka at 18:08| Comment(0) | TrackBack(0) | MAXScript | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:


この記事へのトラックバック
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。