476 lines
14 KiB
Plaintext
Executable File
476 lines
14 KiB
Plaintext
Executable File
|
|
filein "rockstar/export/settings.ms" -- This is fast
|
|
|
|
-- Figure out the project
|
|
theProjectRoot = RsConfigGetProjRootDir()
|
|
theProject = RSConfigGetProjectName()
|
|
theWildWest = RsConfigGetWildWestDir()
|
|
|
|
theProjectConfig = RsConfigGetProjBinConfigDir()
|
|
|
|
toolsRoot = RsConfigGetToolsRootDir()
|
|
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
|
|
|
|
filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_Rigging.ms" )
|
|
|
|
filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_xml.ms" )
|
|
|
|
myPythonPath = "c:\\Autopology\\maxscriptTest\\"
|
|
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
THE WAY I THINK THIS WORKS:
|
|
|
|
((( REQUIRES PYTHON 2.7 STANDALONE , & NUMPY INSTALLED - MAYBE WE CAN DO A PY2EXE ON IT?
|
|
|
|
xmlDescriptor - DUNNO WHAT THIS IS YET
|
|
editName - xml of all verts for the head we want to retopologise
|
|
xmlMaster - xml of all verts for the template head
|
|
masterEdit - output of autopology tool which is the verts contained in xmlMaster which have been transposed to confirm to geo in editName
|
|
**/
|
|
|
|
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
try (destroyDialog AutopologyUI) catch()
|
|
|
|
rollout AutopologyUI "Autopology"
|
|
(
|
|
|
|
local maxDescriptor = undefined
|
|
local maxMaster = undefined
|
|
local maxRig = undefined
|
|
|
|
local xmlDescriptor = undefined
|
|
local xmlMaster = undefined
|
|
local xmlRig = undefined
|
|
|
|
local envelopeFiles = #()
|
|
|
|
local bonePosition = #()
|
|
|
|
fn recurseHierarchyPositions Root =
|
|
(
|
|
append bonePosition Root
|
|
if Root.children.count > 0 do
|
|
(
|
|
for i = 1 to Root.children.count do
|
|
(
|
|
child = Root.children[i]
|
|
recurseHierarchyPositions child
|
|
)
|
|
)
|
|
|
|
return bonePosition
|
|
)
|
|
|
|
fn addBoneToSkin skinMod bones =
|
|
(
|
|
-- we check the modifier is valid
|
|
if classOf skinMod == Skin do
|
|
(
|
|
-- set the rollout panel
|
|
max modify mode
|
|
modPanel.setCurrentObject skinMod
|
|
|
|
-- add the bones
|
|
for each in bones do
|
|
(
|
|
if each != undefined do
|
|
(
|
|
skinOps.addBone skinMod each 1
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
fn exportPosition xmlFile =
|
|
(
|
|
--WILL EXPORT A FILE FOR VERT POSITIONS / CENTRE PIVOTS TO XML
|
|
xmlOut = RSTA_xml_IO()
|
|
xmlOut.xmlFile = xmlFile --make a new file
|
|
xmlOut.new "Geometry"
|
|
|
|
format "Working verts...\n"
|
|
|
|
selectionArray = selection as array
|
|
|
|
for i = 1 to selectionArray.count do
|
|
(
|
|
thisItem = selectionArray[i]
|
|
format (thisItem.name+": "+(classof thisItem.baseObject as string)+"\n")
|
|
|
|
geo = RSTA_xml.makeNode (RSTA_makeSafeSpace thisItem.Name) xmlOut.root
|
|
|
|
if (ClassOf thisItem) == Dummy or (ClassOf thisItem) == Point then
|
|
(
|
|
-- vert = RSTA_xml_makeNode "vert" #() geo
|
|
vert = RSTA_xml.makeNode "vert" #() geo
|
|
vec = thisItem.pos
|
|
vert.innerText = ((vec[1] as string) + " " + (vec[2] as string) + " " + (vec[3] as string))
|
|
)
|
|
else
|
|
(
|
|
if (classof thisItem.baseObject == Editable_Poly) or (classof thisItem.baseObject == Editable_mesh) then
|
|
(
|
|
numVerts = polyop.getNumVerts thisItem
|
|
|
|
for j = 1 to numVerts do
|
|
(
|
|
-- vert = RSTA_xml_makeNode "vert" #() geo
|
|
vert = RSTA_xml.makeNode "vert" geo
|
|
vec = polyOp.getVert thisItem j
|
|
vert.innerText = ((vec[1] as string) + " " + (vec[2] as string) + " " + (vec[3] as string))
|
|
|
|
)
|
|
)
|
|
else
|
|
(
|
|
messagebox ("Skipping "+thisItem.name+" as it is not Editable Poly or Mesh.") title:"Cannot Continue!" beep:true
|
|
format ("Skipping "+thisItem.name+" as it is not Editable Poly or Mesh.\n")
|
|
)
|
|
)
|
|
)
|
|
xmlOut.save()
|
|
)
|
|
|
|
fn importPositions xmlFile =
|
|
(
|
|
-- xml_io = RSTA_xml_IO xmlFile:xmlFile
|
|
-- xml_io.load()
|
|
|
|
xml_io = RSTA_xml_IO()
|
|
xml_io.xmlFile = xmlFile --make a new file
|
|
xml_io.load()
|
|
|
|
-- for i in (RSTA_xml_selectChildren xml_io.root) do
|
|
for i in (rsta_xml.getChildren xml_io.root) do
|
|
(
|
|
geo = getnodebyname i.Name
|
|
if geo != undefined do
|
|
(
|
|
if (ClassOf geo) == Dummy or (ClassOf geo) == Point then
|
|
(
|
|
-- for j in (RSTA_xml_selectChildren i) do
|
|
for j in (rsta_xml.getChildren i) do
|
|
(
|
|
vector = filterString j.InnerText " "
|
|
geo.pos.x = (vector[1] as float)
|
|
geo.pos.y = (vector[2] as float)
|
|
geo.pos.z = (vector[3] as float)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
with redraw off
|
|
try(
|
|
max modify mode
|
|
addModifier geo (Edit_Poly())
|
|
SetCommandPanelTaskMode #create
|
|
vert = 1
|
|
|
|
-- select geo
|
|
-- SetCommandPanelTaskMode #modify
|
|
-- subObjectLevel = 1
|
|
|
|
-- for j in (RSTA_xml_selectChildren i) do
|
|
for j in (rsta_xml.getChildren i) do
|
|
(
|
|
format ("vert: "+(vert as string)+"\n")
|
|
if classof geo.modifiers[1] == Edit_Poly then
|
|
(
|
|
-- select geo
|
|
-- SetCommandPanelTaskMode #modify
|
|
-- subObjectLevel = 1
|
|
|
|
vector = filterString j.InnerText " "
|
|
|
|
polyop.setVert geo vert [(vector[1] as float), (vector[2] as float), (vector[3] as float)]
|
|
|
|
vert += 1
|
|
)
|
|
)
|
|
|
|
format ("Verts set for "+geo.name+"\n")
|
|
)catch(format ("vert rearranging failed for "+geo.name+" :( \n"))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
group "Write Mesh XML : "
|
|
(
|
|
button btnWriteMesh "Write Selection To XML" width:140
|
|
)
|
|
|
|
group "Select Autopology Folder: "
|
|
(
|
|
button btnSelectFolder "Set Folder" width:140 tooltip:"Set Autopology data folder"
|
|
edittext edtFolder
|
|
button btnImportDescriptor "Import Descriptor" width:140
|
|
)
|
|
|
|
group "Autopologise: "
|
|
(
|
|
|
|
button btnRetopologise "Retopologise" width:140
|
|
button btnRig "Rig / Skin" width:140
|
|
|
|
)
|
|
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
on btnWriteMesh pressed do
|
|
(
|
|
--WRITE OUT THE MESHES VERT DATA TO XML
|
|
selectedArray = selection as array
|
|
|
|
if selectedArray.count != 0 then
|
|
(
|
|
sceneName = (maxFilePath + (getFilenameFile maxFileName) + ".autopology"+".xml")
|
|
existing = doesFileExist sceneName
|
|
|
|
if existing == true do
|
|
(
|
|
deleteFile sceneName -- gonna force delete
|
|
)
|
|
exportPosition sceneName
|
|
format ("Write complete.\n")
|
|
)
|
|
else
|
|
(
|
|
messagebox ("Please select your meshes.") title:"Cannot Continue!" beep:true
|
|
format ("Please select your meshes.\n")
|
|
)
|
|
)
|
|
|
|
on btnSelectFolder pressed do
|
|
(
|
|
|
|
initialDirPath = (theProjectRoot + "art/peds/Skeletons/Autopology")
|
|
|
|
makeDir initialDirPath all:true
|
|
-- folderPath = getSavePath caption:"Select Autopology Folder" initialDir:@"X:\rdr3\art\peds\Skeletons\Autopology"
|
|
folderPath = getSavePath caption:"Select Autopology Folder" initialDir:initialDirPath
|
|
if folderPath != undefined do
|
|
(
|
|
edtFolder.text = (folderPath)
|
|
for f in (getFiles (folderPath + "\\*")) do
|
|
(
|
|
/**
|
|
GOD GIVE ME STRENGTH! WHAT THE FUCK ARE THESE DESCRIPTOR FILES ETC AND HOW ARE THEY GENERATED?
|
|
|
|
I 'THINK'(tm) THAT THE DESCRIPTOR IS THE MESH WE WANT OT ADJUST TO FIT TO THE MASTER HEAD.
|
|
**/
|
|
|
|
|
|
if (matchPattern f pattern:"*_descriptor*") then
|
|
(
|
|
if (matchPattern f pattern:"*.max*") then --looks like a low lod of the head mesh
|
|
(
|
|
maxDescriptor = f
|
|
format ("maxDescriptor set to: "+(maxDescriptor as string)+"\n")
|
|
)
|
|
else if (matchPattern f pattern:"*.xml*") then --looks like xml from exportPosition for the descrptor head
|
|
(
|
|
xmlDescriptor = f
|
|
format ("xmlDescriptor set to: "+(xmlDescriptor as string)+"\n")
|
|
)
|
|
)
|
|
else if (matchPattern f pattern:"*_master*") then
|
|
(
|
|
if (matchPattern f pattern:"*.max*") then --looks like the high lod head and teef geo
|
|
(
|
|
maxMaster = f
|
|
format ("maxMaster set to: "+(maxMaster as string)+"\n")
|
|
)
|
|
else if (matchPattern f pattern:"*.xml*") then --looks like xml from exportPosition for the master head
|
|
(
|
|
xmlMaster = f
|
|
format ("xmlMaster set to: "+(xmlMaster as string)+"\n")
|
|
)
|
|
)
|
|
else if (matchPattern f pattern:"*_rig*") then
|
|
(
|
|
if (matchPattern f pattern:"*.max*") then -- the facial rig
|
|
(
|
|
maxRig = f
|
|
format ("maxRig set to: "+(maxRig as string)+"\n")
|
|
)
|
|
else if (matchPattern f pattern:"*.xml*") then -- xml from exportPosition for the rig
|
|
(
|
|
xmlRig = f
|
|
format ("xmlRig set to: "+(xmlRig as string)+"\n")
|
|
)
|
|
)
|
|
else if (matchPattern f pattern:"*.env") do
|
|
(
|
|
|
|
append envelopeFiles f
|
|
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
on btnImportDescriptor pressed do
|
|
(
|
|
if maxDescriptor != undefined then
|
|
(
|
|
mergeMaxFile maxDescriptor
|
|
)
|
|
else
|
|
(
|
|
-- print "ITS NOT FUCKING HERE ASSHOLE"
|
|
format ("Max descriptor not set. Please click Set Folder. \n")
|
|
messagebox ("Max descriptor not set. Please click Set Folder. \n") beep:true
|
|
)
|
|
|
|
)
|
|
|
|
on btnRetopologise pressed do
|
|
(
|
|
if selection.count != 0 then
|
|
(
|
|
editName = (maxFilePath + "Edit.xml")
|
|
masterEditName = (maxFilePath + "MasterEdit.xml")
|
|
|
|
men = doesFileExist masterEditName
|
|
if men == true do
|
|
(
|
|
deleteFile masterEditName
|
|
)
|
|
exportPosition editName
|
|
|
|
xmlDescriptorExists = doesFileExist xmlDescriptor
|
|
if xmlDescriptorExists == true then
|
|
(
|
|
editNameExists = doesFileExist editName
|
|
if editNameExists == true then
|
|
(
|
|
xmlMasterExists = doesFileExist xmlMaster
|
|
|
|
if xmlMasterExists == true then
|
|
(
|
|
|
|
cmd = ("python "+myPythonPath+"autopology.py "+xmlDescriptor+" "+editName+" "+xmlMaster+" "+masterEditName)
|
|
|
|
format ("cmd: "+cmd+"\n")
|
|
executed = doscommand cmd
|
|
|
|
format ("executed: "+(executed as string)+"\n")
|
|
|
|
if executed == 0 then
|
|
(
|
|
mergeMaxFile maxMaster #deleteOldDups
|
|
importPositions masterEditName
|
|
|
|
format ("Retopology Complete.\n")
|
|
)
|
|
else
|
|
(
|
|
format ("Autopology failed.\n")
|
|
messagebox ("Autopology failed.\n") beep:true title:"WARNING!"
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("Couldn't find "+xmlMaster+"\n" )
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("Couldn't find "+editName+"\n" )
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("Couldn't find "+xmlDescriptorExists+"\n" )
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("Please pick something!\n")
|
|
messagebox ("Please pick something!\n") beep:true
|
|
)
|
|
|
|
)
|
|
|
|
on btnRig pressed do
|
|
(
|
|
|
|
editName = (maxFilePath + "Edit.xml")
|
|
RigEditName = (maxFilePath + "RigEdit.xml")
|
|
exportPosition editName
|
|
|
|
xmlDescriptorExists = doesFileExist xmlDescriptor
|
|
if xmlDescriptorExists == true then
|
|
(
|
|
editNameExists = doesFileExist editName
|
|
if editNameExists == true then
|
|
(
|
|
xmlMasterExists = doesFileExist xmlMaster
|
|
|
|
if xmlMasterExists == true then
|
|
(
|
|
masterEditNameExists = doesFileExist masterEditName
|
|
|
|
if masterEditNameExists == true then
|
|
(
|
|
cmd = ("Autopology \"" + xmlDescriptor + "\" \"" + editName + "\" \"" + xmlRig + "\" \"" + RigEditName)
|
|
-- HiddenDOSCommand cmd startpath:@"X:\rdr3\tools\wildwest\script\standalone\Autopology"
|
|
HiddenDOSCommand cmd startpath:@"c:\Autopology\maxscriptTest" exitCode:&exitcode
|
|
|
|
mergeMaxFile maxRig
|
|
importPositions RigEditName
|
|
|
|
for i = 1 to envelopeFiles.count do
|
|
(
|
|
geo = (getNodeByName (getFilenameFile envelopeFiles[i]))
|
|
if geo != undefined do
|
|
(
|
|
-- geoSkin = Skin()
|
|
addModifier geo Skin()
|
|
geo.modifiers[#Skin].bone_Limit = 4
|
|
skelRoot = getNodeByName "SKEL_ROOT"
|
|
bonesArray = recurseHierarchyPositions skelRoot
|
|
addBoneToSkin geo.modifiers[#Skin] bonesArray
|
|
skinOps.LoadEnvelope geo.modifiers[#Skin] envelopeFiles[i]
|
|
)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("Couldn't find "+masterEditName+"\n" )
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("Couldn't find "+xmlMaster+"\n" )
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("Couldn't find "+editName+"\n" )
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("Couldn't find "+xmlDescriptorExists+"\n" )
|
|
)
|
|
|
|
|
|
)
|
|
|
|
)
|
|
|
|
createDialog AutopologyUI |