Files
2025-09-29 00:52:08 +02:00

622 lines
19 KiB
Plaintext
Executable File

-- Load tool's main utility-functions:
filein (::RsConfigGetWildwestDir() + "script/3dsmax/characters/rigging/skindatatransfer_Funcs.ms")
unregisterRedrawViewsCallback RStransferSkinDataDrawCallback
fn RStransferSkinDataDrawCallback = (gRsSkinDataTransfer.viewportDraw())
struct RStransferSkinDataDrawDataStruct (obj, elemStartVerts = #(), chooseVert)
try (destroyDialog RsSkinDataTransferRoll) catch ()
-- Version-phrase generated via: (filein (RsConfigGetWildWestDir() + "script/3dsmax/_config_files/wildwest_header.ms"); print (RsRandomPhrase count:100))
rollout RsSkinDataTransferRoll "Transfer Skin Data [v1.01:Thirsty Frog]" width:300
(
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:RsSkinDataTransferRoll.width
local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"SkinDataXFer_Prep" filename:(getThisScriptFilename())
local skinVertDataStore
local sourceObj, targetObj
local objsWere = #()
local objVertSelData = #(RStransferSkinDataDrawDataStruct(), RStransferSkinDataDrawDataStruct())
-- Used to communicate with vert-picker tool
local pickObjNum
local pickElemNum
fn sourceFilter obj = (obj != targetObj) and (isKindOf obj.baseObject Editable_Poly) --(obj.modifiers[#skin] != undefined)
fn targetFilter obj = (obj != sourceObj) and (isKindOf obj.baseObject Editable_Poly)
label getSourceLbl "Transfer from:" across:2
label getTargetLbl "Transfer to:"
pickbutton getSourceObjBtn "[pick object]" filter:sourceFilter autoDisplay:true width:130 across:2
pickbutton getTargetObjBtn "[pick object]" filter:targetFilter autoDisplay:true width:130
local objBtns = #(getSourceObjBtn, getTargetObjBtn)
local vertPickBtnWidth = 100
local defaultVertPickText = "[pick vertex]"
button vertPickBtnA01 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
-- label vertPickLbl1 "Element 01" across:3
label vertPickLbl1 "Head" across:3
button vertPickBtnB01 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
button vertPickBtnA02 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
label vertPickLbl2 "Upper Teeth" across:3 offset:[2,0]
button vertPickBtnB02 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
button vertPickBtnA03 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
label vertPickLbl3 "Lower Teeth" across:3 offset:[2,0]
button vertPickBtnB03 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
button vertPickBtnA04 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
label vertPickLbl4 "Tongue" across:3 offset:[2,0]
button vertPickBtnB04 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
button vertPickBtnA05 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
label vertPickLbl5 "Right Eyeball" across:3 offset:[2,0]
button vertPickBtnB05 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
button vertPickBtnA06 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
label vertPickLbl6 "Left Eyeball" across:3 offset:[2,0]
button vertPickBtnB06 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
button vertPickBtnA07 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
label vertPickLbl7 "Right Hand" across:3 offset:[2,0]
button vertPickBtnB07 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
button vertPickBtnA08 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
label vertPickLbl8 "Left Hand" across:3 offset:[2,0]
button vertPickBtnB08 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
button vertPickBtnA09 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
label vertPickLbl9 "Element 09" across:3 offset:[2,0]
button vertPickBtnB09 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
button vertPickBtnA10 "" across:3 width:vertPickBtnWidth offset:[9,-3] enabled:false
label vertPickLbl10 "Element 10" across:3 offset:[2,0]
button vertPickBtnB10 "" across:3 width:vertPickBtnWidth offset:[-6,-3] enabled:false
-- Lists generated on open, from rollout's controls:
local vertPickBtnsA = #()
local vertPickBtnsB = #()
local elemNames = #()
local vertPickBtns = #(vertPickBtnsA, vertPickBtnsB)
checkBox hideElementsChk "Hide picked elements" align:#center checked:false
button copyBtn "Copy from sel." across:3 offset:[2,6] enabled:false
button transferBtn "Transfer Data" offset:[4,6]
button pasteBtn "Paste to sel." enabled:false offset:[5,6]
button debugMoveBtn "[debug vert-pos copy]" height:18 tooltip:"Moves verts on Target to positions of matching verts on Source, used to spot matching-errors\n\n(is undoable)"
fn pickedObj obj objNum =
(
if obj != undefined do ( print ("Triggered pickedObj with "+obj.name))
-- Stop hiding faces on previous object:
local objWas = objsWere[objNum]
if hideElementsChk.checked and (isValidNode objWas) do
(
print objWas
objWas.unhideAll #Face
)
objsWere = #(sourceObj, targetObj)
if (obj == undefined) then
(
objBtns[objNum].object = undefined
objVertSelData[objNum] = RStransferSkinDataDrawDataStruct()
vertPickBtns[objNum].enabled = false
vertPickBtns[objNum].text = defaultVertPickText
)
else
(
objVertSelData[objNum] = RStransferSkinDataDrawDataStruct obj:obj
vertPickBtns[objNum].enabled = true
vertPickBtns[objNum].text = defaultVertPickText
-- If object has a single vert selected, make that the first element's start-vert:
local baseObj = if (isProperty obj #baseObject) then obj.baseObject else obj
local vertSel = (polyop.getVertsByFlag baseObj 1) as array
if (vertSel.count == 1) do
(
local vertSel = vertSel[1]
objVertSelData[objNum].elemStartVerts[1] = vertSel
vertPickBtns[objNum][1].text = vertSel as string
)
if hideElementsChk.checked do
(
gRsSkinDataTransfer.hideTheseElements obj objVertSelData[objNum].elemStartVerts
)
)
)
fn hideElementFaces hideThem =
(
local objNum = 0
for obj in #(sourceObj, targetObj) do
(
objNum += 1
if hideThem then
(
gRsSkinDataTransfer.hideTheseElements obj objVertSelData[objNum].elemStartVerts
)
else
(
if isValidNode obj do
(
obj.unhideAll #Face
)
)
)
)
on hideElementsChk changed hideThem do
(
--print ("hideElementsChk: "+(hideElementsChk.checked as string))
hideElementFaces hideThem
)
on getSourceObjBtn picked obj do
(
sourceObj = obj
pickedObj obj 1
)
on getTargetObjBtn picked obj do
(
targetObj = obj
pickedObj obj 2
)
on getSourceObjBtn rightclick do
(
sourceObj = undefined
pickedObj undefined 1
)
on getTargetObjBtn rightclick do
(
targetObj = undefined
pickedObj undefined 2
)
tool RStransferSkinMouseTool
(
local objNum = RsSkinDataTransferRoll.pickObjNum
local drawData = RsSkinDataTransferRoll.objVertSelData[objNum]
local obj = drawData.obj
local objBase
on start do
(
objBase = if isProperty obj #baseObject then obj.baseObject else obj
polyOp.collapseDeadStructs objBase
)
fn getObjVert =
(
if (isValidNode obj) then
(
local drawVertNum
local vertDist = 10
local mouseDist, vertPos
local vertNums = (polyop.getVertsByFlag objBase 0 mask:8) - (polyop.getHiddenVerts objBase)
for n = vertNums do
(
vertPos = polyop.getvert obj n node:obj
mouseDist = distance viewPoint (gw.wtranspoint vertPos)
if mouseDist < vertDist do
(
drawVertNum = n
vertDist = mouseDist
)
)
drawData.chooseVert = drawVertNum
completeRedraw()
)
else #stop
)
on freeMove do (getObjVert())
on mouseMove clickNum do (getObjVert())
on mousePoint clickNum do
(
if (clickNum > 1) and (drawData.chooseVert != undefined) do
(
#stop
)
)
on mouseAbort clickNum do
(
drawData.chooseVert = undefined
completeRedraw()
)
)
fn getVertBtn ctrl =
(
-- Work out which object/element this control works for, and set variables for picker-tool to find:
pickObjNum = undefined
for listNum = #{1..2} while (pickObjNum == undefined) do
(
pickElemNum = findItem vertPickBtns[listNum] ctrl
if (pickElemNum != 0) do
(
pickObjNum = listNum
)
)
)
fn clearVertBtn ctrl =
(
print ("Clearing vert for "+(ctrl as string))
getVertBtn ctrl
objVertSelData[pickObjNum].elemStartVerts[pickElemNum] = undefined
objVertSelData[pickObjNum].chooseVert = undefined
ctrl.text = defaultVertPickText
if hideElementsChk.checked do
(
gRsSkinDataTransfer.hideTheseElements objBtns[pickObjNum] objVertSelData[pickObjNum].elemStartVerts
)
completeRedraw()
)
fn pickObjVert ctrl =
(
getVertBtn ctrl
startTool RStransferSkinMouseTool
local objData = objVertSelData[pickObjNum]
local selVert = objData.chooseVert
if (selVert == undefined) then
(
print "chooseVert undefined!"
)
else
(
local selElemVerts = gRsSkinDataTransfer.getConnectedVerts objData.obj selVert
local elemStartVerts = objData.elemStartVerts
for n = 1 to elemStartVerts.count where (n != selVert) and (elemStartVerts[n] != undefined) do
(
-- Clear any other start-verts that are in the same mesh-element as the new vert:
if selElemVerts[elemStartVerts[n]] do
(
elemStartVerts[n] = undefined
vertPickBtns[pickObjNum][n].text = defaultVertPickText
)
)
elemStartVerts[pickElemNum] = selVert
ctrl.text = selVert as string
completeRedraw()
)
hideElementsChkState = hideElementsChk.checked
--print ("hideElementsChkState : "+(hideElementsChkState as string))
RsSkinDataTransferRoll.hideElementsChk.state = false
hideThem = RsSkinDataTransferRoll.hideElementsChk.state
hideElementFaces hideThem
RsSkinDataTransferRoll.hideElementsChk.state = hideElementsChkState
hideThem = RsSkinDataTransferRoll.hideElementsChk.state
hideElementFaces hideThem
if hideElementsChk.checked do
(
gRsSkinDataTransfer.hideTheseElements objBtns[pickObjNum].object objVertSelData[pickObjNum].elemStartVerts
)
)
on vertPickBtnA01 pressed do (pickObjVert vertPickBtnA01)
on vertPickBtnA02 pressed do (pickObjVert vertPickBtnA02)
on vertPickBtnA03 pressed do (pickObjVert vertPickBtnA03)
on vertPickBtnA04 pressed do (pickObjVert vertPickBtnA04)
on vertPickBtnA05 pressed do (pickObjVert vertPickBtnA05)
on vertPickBtnA06 pressed do (pickObjVert vertPickBtnA06)
on vertPickBtnA07 pressed do (pickObjVert vertPickBtnA07)
on vertPickBtnA08 pressed do (pickObjVert vertPickBtnA08)
on vertPickBtnA09 pressed do (pickObjVert vertPickBtnA09)
on vertPickBtnA10 pressed do (pickObjVert vertPickBtnA10)
on vertPickBtnB01 pressed do (pickObjVert vertPickBtnB01)
on vertPickBtnB02 pressed do (pickObjVert vertPickBtnB02)
on vertPickBtnB03 pressed do (pickObjVert vertPickBtnB03)
on vertPickBtnB04 pressed do (pickObjVert vertPickBtnB04)
on vertPickBtnB05 pressed do (pickObjVert vertPickBtnB05)
on vertPickBtnB06 pressed do (pickObjVert vertPickBtnB06)
on vertPickBtnB07 pressed do (pickObjVert vertPickBtnB07)
on vertPickBtnB08 pressed do (pickObjVert vertPickBtnB08)
on vertPickBtnB09 pressed do (pickObjVert vertPickBtnB09)
on vertPickBtnB10 pressed do (pickObjVert vertPickBtnB10)
on vertPickBtnA01 rightclick do (clearVertBtn vertPickBtnA01)
on vertPickBtnA02 rightclick do (clearVertBtn vertPickBtnA02)
on vertPickBtnA03 rightclick do (clearVertBtn vertPickBtnA03)
on vertPickBtnA04 rightclick do (clearVertBtn vertPickBtnA04)
on vertPickBtnA05 rightclick do (clearVertBtn vertPickBtnA05)
on vertPickBtnA06 rightclick do (clearVertBtn vertPickBtnA06)
on vertPickBtnA07 rightclick do (clearVertBtn vertPickBtnA07)
on vertPickBtnA08 rightclick do (clearVertBtn vertPickBtnA08)
on vertPickBtnA09 rightclick do (clearVertBtn vertPickBtnA09)
on vertPickBtnA10 rightclick do (clearVertBtn vertPickBtnA10)
on vertPickBtnB01 rightclick do (clearVertBtn vertPickBtnB01)
on vertPickBtnB02 rightclick do (clearVertBtn vertPickBtnB02)
on vertPickBtnB03 rightclick do (clearVertBtn vertPickBtnB03)
on vertPickBtnB04 rightclick do (clearVertBtn vertPickBtnB04)
on vertPickBtnB05 rightclick do (clearVertBtn vertPickBtnB05)
on vertPickBtnB06 rightclick do (clearVertBtn vertPickBtnB06)
on vertPickBtnB07 rightclick do (clearVertBtn vertPickBtnB07)
on vertPickBtnB08 rightclick do (clearVertBtn vertPickBtnB08)
on vertPickBtnB09 rightclick do (clearVertBtn vertPickBtnB09)
on vertPickBtnB10 rightclick do (clearVertBtn vertPickBtnB10)
on copyBtn pressed do
(
local sourceObj = undefined
if (selection.count == 1) do (sourceObj = selection[1])
if (sourceFilter sourceObj) and (sourceObj.modifiers[#skin] != undefined) then
(
undo off
(
local startTime = TimeStamp()
skinVertDataStore = gRsSkinDataTransfer.getVertTransferData sourceObj
format "\nCopy took % seconds\n\n" ((timeStamp() - startTime) / 1000.0)
)
pasteBtn.enabled = true
)
else
(
messageBox "Invalid copy-node!"
)
)
fn pasteVerts targetObj =
(
local sourceStartVerts = objVertSelData[1].elemStartVerts
local targetStartVerts = objVertSelData[2].elemStartVerts
local useStartVerts = for n = 1 to sourceStartVerts.count
where (sourceStartVerts[n] != undefined) and (targetStartVerts[n] != undefined)
collect n
local failVerts = #{}
for n in useStartVerts do
(
if not (gRsSkinDataTransfer.pasteVertTransferData targetObj skinVertDataStore sourceStartVerts[n] targetStartVerts[n]) do
(
failVerts[n] = True
)
)
if (failVerts.numberSet == 0) then return True else
(
local msg = stringStream ""
format "Pattern-match% not found on %, failed to transfer data for these elements:\n\n" (if (failVerts.numberSet == 1) then "" else "es") targetObj.name to:msg
for n = failVerts do
(
format "% (% -> %)\n" elemNames[n] sourceStartVerts[n] targetStartVerts[n] to:msg
)
messageBox (msg as string) title:"Pattern-match failure"
return False
)
)
on pasteBtn pressed do
(
local targetObj = undefined
if (selection.count == 1) do (targetObj = selection[1])
if (skinVertDataStore != undefined) and (targetFilter targetObj) then
(
undo off
(
local startTime = TimeStamp()
pasteVerts targetObj
format "\nPaste took % seconds\n\n" ((timeStamp() - startTime) / 1000.0)
)
)
else
(
messageBox "Invalid paste-node!"
)
)
on transferBtn pressed do
(
if (sourceObj != targetObj) and (isValidNode sourceObj) and (isValidNode targetObj) do
(
undo "transfer skin data" on
(
local StartTime = TimeStamp()
skinVertDataStore = gRsSkinDataTransfer.getVertTransferData sourceObj
if (skinVertDataStore != undefined) do
(
pasteVerts targetObj
skinXFerComplete = true
if (::RsPreserveHandSkin == true) do
(
print ("Attempting hand shit")
inputHandSkinData targetObj
)
format "\nTransfer took % seconds\n\n" ((TimeStamp() - StartTime) / 1000.0)
--now if we're called from the prep tool we need to delete the template data
if mjrTarget != undefined do --for if calling via the prep tool
(
local tempNode = getNodeByName "templateMesh"
if (tempNode != undefined) do
(
local tempNodeParent = getNodeByName "templateHead"
delete tempNode
if (tempNodeParent != undefined) do
(
delete tempNodeParent
)
)
)
)
)
)
)
on debugMoveBtn pressed do
(
if (sourceObj != targetObj) and (isValidNode sourceObj) and (isValidNode targetObj) do
(
undo "transfer vertex positions" on
(
local StartTime = TimeStamp()
local objA = objVertSelData[1].obj
local objB = objVertSelData[2].obj
local sourceStartVerts = objVertSelData[1].elemStartVerts
local targetStartVerts = objVertSelData[2].elemStartVerts
local useStartVerts = for n = 1 to sourceStartVerts.count
where (sourceStartVerts[n] != undefined) and (targetStartVerts[n] != undefined)
collect n
for startVertNum in useStartVerts do
(
polyOp.collapseDeadStructs objA
polyOp.collapseDeadStructs objB
local objAstartVert = sourceStartVerts[startVertNum]
local objBstartVert = targetStartVerts[startVertNum]
local patternHash = gRsSkinDataTransfer.getUniquePatternHashLevel objA objAstartVert
local startEdgeNum = gRsSkinDataTransfer.findPatternTreeMatch objB objBstartVert patternHash
if (startEdgeNum == undefined) do
(
messageBox ("Topology-match not found!") title:"Edges around selected verts are too different"
return false
)
local matchVerts = gRsSkinDataTransfer.matchObjVerts objA objB objAstartVert objBstartVert targetStartEdge:startEdgeNum debugVertMove:true
local vertNumsA = matchVerts[1]
local vertNumsB = matchVerts[2]
format "Matched: %\n" vertNumsA.count
for n = 1 to matchVerts[1].count do
(
-- polyop.setVert objB vertNumsB[n] (polyop.getVert objA vertNumsA[n])
)
pasteBtn.enabled = true
)
redrawViews()
format "\nTransfer took % seconds\n\n" ((TimeStamp() - StartTime) / 1000.0)
)
)
)
on RsSkinDataTransferRoll open do
(
banner.setup()
-- Build control-lists:
for ctrl in RsSkinDataTransferRoll.controls do
(
case of
(
(matchPattern ctrl.name pattern:"vertPickBtnA*"):(append vertPickBtnsA ctrl)
(matchPattern ctrl.name pattern:"vertPickBtnB*"):(append vertPickBtnsB ctrl)
(matchPattern ctrl.name pattern:"vertPickLbl*"):(append elemNames ctrl.text)
)
)
vertPickBtnsA.text = defaultVertPickText
vertPickBtnsB.text = defaultVertPickText
-- RsSkinDataTransferRoll.hideElementsChk.state = false
-- hideThem = RsSkinDataTransferRoll.hideElementsChk.state
-- hideElementFaces hideThem
-- RsSkinDataTransferRoll.hideElementsChk.state = true
-- hideThem = RsSkinDataTransferRoll.hideElementsChk.state
-- hideElementFaces hideThem
if (isValidNode mjrTarget) do --for if calling via the prep tool
(
--messagebox "BING!"
local templateObj = getNodeByName "templateMesh"
if (isValidNode templateObj) do
(
sourceObj = templateObj
pickedObj sourceObj 1
getSourceObjBtn.text = sourceObj.name
targetObj = mjrTarget
pickedObj targetObj 2
getTargetObjBtn.text = targetObj.name
--now clear any misc selected verts
clearVertBtn vertPickBtnA01
clearVertBtn vertPickBtnB01
)
)
registerRedrawViewsCallback RStransferSkinDataDrawCallback
completeRedraw()
)
on RsSkinDataTransferRoll close do
(
hideElementFaces false
-- Remove temporary template-mesh:
local tempNode = getNodeByName "templateMesh"
if (tempNode != undefined) do
(
print ("Deleting "+tempNode.name)
delete tempNode
skinXFerComplete = true
)
unregisterRedrawViewsCallback RStransferSkinDataDrawCallback
completeRedraw()
)
)
--------------
-- TESTY --
--------------
createDialog RsSkinDataTransferRoll
--clearListener()
--blah = gRsSkinDataTransfer.copyVerts()