602 lines
17 KiB
Plaintext
Executable File
602 lines
17 KiB
Plaintext
Executable File
--url:bugstar:463942
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
|
|
|
|
struct TextureData
|
|
(
|
|
name,
|
|
type,
|
|
path,
|
|
propTexture,
|
|
alpha,
|
|
hdsplit,
|
|
imgData
|
|
)
|
|
|
|
|
|
try( destroyDialog PropHDSplit_UI)catch()
|
|
rollout PropHDSplit_UI "Prop HD Splitter"
|
|
(
|
|
local headers = #("Name", "Type", "Path", "Alpha", "Prop Texture", "Width", "Height", "HDSplit")
|
|
local txSizes = #("128", "256", "512", "1024", "2048")
|
|
local tcsPathRoot = RsConfigGetTCSMapsRoot()
|
|
local regex = dotnetclass "System.Text.RegularExpressions.Regex"
|
|
local textures = #()
|
|
local listTextures = #()
|
|
local feedback = undefined
|
|
local changeListNum = undefined
|
|
|
|
----------------------------------------------------------------------------------
|
|
-- CONTROLS
|
|
----------------------------------------------------------------------------------
|
|
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:PropHDSplit_UI.width
|
|
local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"PropTexture HDSplitter" filename:(getThisScriptFilename())
|
|
|
|
dropdownlist ddl_txSize "Min Texture Size:" items:txSizes width:(1000 * 0.5 - 20)
|
|
button btn_doAnalysis "Analyse Selected" across:3 align:#left width:(1000 * 0.5 - 20)
|
|
button btn_doChanges "Add HDSplit" width:200 offset:[200, 0]
|
|
button btn_removeHDSplit "Remove HDSplit" width:200
|
|
dotNetControl lstPropList "System.Windows.Forms.DataGridView" align:#center
|
|
|
|
------------------------------------------------------------------------------------
|
|
-- DotNet values:
|
|
------------------------------------------------------------------------------------
|
|
|
|
local textFont, dingFont, textFontBold
|
|
local DNcolour = dotNetClass "System.Drawing.Color"
|
|
|
|
local textCol = (colorMan.getColor #windowText) * 255
|
|
local windowCol = (colorMan.getColor #window) * 255
|
|
local notLoadedCol = if (windowCol[1] < 128) then (windowCol * 1.5) else (windowCol * 0.85)
|
|
|
|
local textColour = DNcolour.FromArgb textCol[1] textCol[2] textCol[3]
|
|
local backColour = DNcolour.FromArgb windowCol[1] windowCol[2] windowCol[3]
|
|
local altBackColour = DNcolour.FromArgb (windowCol[1]-10) (windowCol[2]-10) (windowCol[3]-10)
|
|
--local inSceneBackColour = DNcolour.FromArgb windowCol[1] windowCol[2] (windowCol[3]+64)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn arrangeCtrls size:[PropHDSplit_UI.width, PropHDSplit_UI.height] =
|
|
(
|
|
lstPropList.width = size.x - 25
|
|
lstPropList.height = size.y - 90
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn init =
|
|
(
|
|
lstPropList.SelectionMode = lstPropList.SelectionMode.FullRowSelect
|
|
lstPropList.AllowUserToAddRows = false
|
|
lstPropList.AllowUserToDeleteRows = false
|
|
lstPropList.AllowUserToOrderColumns = true
|
|
lstPropList.AllowUserToResizeRows = false
|
|
lstPropList.AllowUserToResizeColumns = false
|
|
lstPropList.AllowDrop = false
|
|
lstPropList.MultiSelect = true
|
|
lstPropList.ReadOnly = true
|
|
|
|
lstPropList.dock = lstPropList.dock.fill
|
|
lstPropList.DefaultCellStyle.backColor = backColour
|
|
lstPropList.DefaultCellStyle.foreColor = textColour
|
|
lstPropList.AlternatingRowsDefaultCellStyle.BackColor = altBackColour
|
|
|
|
textFont = lstPropList.font
|
|
dingFont = dotNetObject "System.Drawing.Font" "Webdings" textFont.size
|
|
textFontBold = dotnetobject "system.drawing.font" textFont (dotnetclass "system.drawing.fontstyle").bold
|
|
|
|
lstPropList.EnableHeadersVisualStyles = false
|
|
lstPropList.ColumnHeadersDefaultCellStyle.backColor = backColour
|
|
lstPropList.ColumnHeadersDefaultCellStyle.foreColor = textColour
|
|
lstPropList.ColumnHeadersDefaultCellStyle.font = textFontBold
|
|
lstPropList.ColumnHeadersHeight = 34
|
|
lstPropList.RowHeadersVisible = false
|
|
--lstPropList.AutoSizeColumnsMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnsMode").AllCellsExceptHeader
|
|
|
|
startSize = [PropHDSplit_UI.width - 10, PropHDSplit_UI.height - 40]
|
|
|
|
arrangeCtrls size:startSize
|
|
|
|
local colNum
|
|
--append headers ""
|
|
for item in headers do
|
|
(
|
|
colNum = lstPropList.Columns.add item item
|
|
lstPropList.Columns.item[colNum].minimumWidth = 75
|
|
lstPropList.Columns.item[colNum].autoSizeMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnMode").AllCellsExceptHeader
|
|
)
|
|
|
|
local firstCol = lstPropList.Columns.item[0]
|
|
--local lastCol = lstPropList.Columns.item[colNum]
|
|
|
|
firstCol.width = 160
|
|
--lastCol.AutoSizeMode = lastCol.AutoSizeMode.AllCellsExceptHeader
|
|
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn getVarTextures mat =
|
|
(
|
|
varTextures = #()
|
|
counter = 1
|
|
for i = 1 to (RstGetVariableCount mat) do
|
|
(
|
|
if (RstGetVariableType mat i) == "texmap" then
|
|
(
|
|
append varTextures (DataPair var:i subtex:counter)
|
|
counter += 1
|
|
)
|
|
)
|
|
|
|
varTextures
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn getAlphaTexture mat Idx =
|
|
(
|
|
--get texture count for the material
|
|
textureCount = (for i = 1 to (RstGetVariableCount mat) where (RstGetVariableType mat i) == "texmap" collect i).count
|
|
|
|
--get the var textures lookup
|
|
local varTextures = getVarTextures mat
|
|
|
|
--format "mat:% idx:% count:%\n" mat idx texCount
|
|
|
|
numTextures = getNumSubTexmaps mat
|
|
hasAlpha = if numTextures == (2 * textureCount) then true else false
|
|
|
|
--print numTextures
|
|
if hasAlpha and numTextures > 1 then
|
|
(
|
|
local textureSlot = (for item in varTextures where (item.var == idx) collect item.subtex)[1]
|
|
local alphaTextureSlot = textureCount + textureSlot
|
|
|
|
local alpha = getSubTexmap mat alphaTextureSlot
|
|
|
|
if alpha != undefined then
|
|
(
|
|
return alpha.filename
|
|
)
|
|
else
|
|
(
|
|
return ""
|
|
)
|
|
)
|
|
else return ""
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn getTexPlusAlpha mat index =
|
|
(
|
|
rgbTex = RstGetVariable mat index
|
|
alphaTex = getAlphaTexture mat index
|
|
|
|
return (DataPair rgb:rgbTex alpha:alphaTex)
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn getTexture mat =
|
|
(
|
|
|
|
matTextures = #()
|
|
|
|
for i = 1 to (RstGetVariableCount mat) do
|
|
(
|
|
if (RstGetVariableType mat i) == "texmap" then
|
|
(
|
|
case (RstGetVariableName mat i) of
|
|
(
|
|
"Diffuse Texture":
|
|
(
|
|
append matTextures (DataPair type:"Diffuse" texture:(getTexPlusAlpha mat i))
|
|
)
|
|
|
|
"Bump Texture":
|
|
(
|
|
append matTextures (DataPair type:"Normal" texture:(getTexPlusAlpha mat i))
|
|
)
|
|
|
|
"Specular Texture":
|
|
(
|
|
append matTextures (DataPair type:"Specular" texture:(getTexPlusAlpha mat i))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
--return
|
|
matTextures
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn isPropTexture tex =
|
|
(
|
|
return (matchPattern tex pattern:"*Textures\Props*" ignoreCase:true)
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn isHDSplitSet texName =
|
|
(
|
|
--get tcs
|
|
tcsPath = tcsPathRoot + (tolower texName) + ".tcs"
|
|
if doesFileExist tcsPath == false then
|
|
(
|
|
gRsPerforce.sync #(tcsPath)
|
|
)
|
|
if doesFileExist tcsPath == false then return false
|
|
xmlDoc = XMlDocument()
|
|
xmlDoc.init()
|
|
xmlDoc.load ( tcsPath )
|
|
xmlRoot = xmlDoc.document.DocumentElement
|
|
imageSplitHDNode = xmlRoot.getElementsByTagName "imageSplitHD"
|
|
|
|
if imageSplitHDNode.count != 1 then return false else return true
|
|
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn buildTextureDataObject theTex =
|
|
(
|
|
txData = TextureData()
|
|
txData.name = getFilenameFile theTex.texture.rgb
|
|
txData.alpha = getFilenameFile theTex.texture.alpha
|
|
txData.type = theTex.type
|
|
txData.path = theTex.texture.rgb
|
|
txData.propTexture = isPropTexture theTex.texture.rgb
|
|
txData.hdsplit = isHDSplitSet (txData.name + txData.alpha)
|
|
txData.imgData = openBitmap theTex.texture.rgb
|
|
|
|
return txData
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn textureUnique tex =
|
|
(
|
|
local exists = for item in listTextures where item[1] == (getFilenameFile tex) collect item
|
|
|
|
if exists.count == 0 then return true else return false
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn checkinReminder =
|
|
(
|
|
messageBox ("Changed tcs are in changelist: " + (changeListNum as String))
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
fn doAnalysis =
|
|
(
|
|
lstPropList.Rows.Clear()
|
|
textures = #()
|
|
listTextures = #()
|
|
materialIDs = #()
|
|
listMaterialIDs = #()
|
|
|
|
theTextures = #()
|
|
for obj in $selection where superClassOf obj == GeometryClass do
|
|
(
|
|
--find the textures on the object
|
|
objMat = obj.material
|
|
matIds = getAppliedMaterials obj
|
|
|
|
--Check obj has a material
|
|
if objMat == undefined then
|
|
(
|
|
messageBox ("Object: " + obj.name + " Has no material assigned, ignoring.")
|
|
continue
|
|
)
|
|
|
|
if classOf objMat != MultiMaterial then
|
|
(
|
|
theTexList = getTexture objMat
|
|
for theTex in theTexList do
|
|
(
|
|
if theTex.texture.rgb != undefined then
|
|
(
|
|
if (findItem theTextures theTex.texture.rgb) == 0 then --not seen before
|
|
(
|
|
append textures (buildTextureDataObject theTex)
|
|
append theTextures theTex
|
|
)
|
|
)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
for id in matIds do
|
|
(
|
|
--check for a none material
|
|
if objMat[id] == undefined then continue
|
|
|
|
theTexList = getTexture objMat[id]
|
|
for theTex in theTexList do
|
|
(
|
|
if theTex.texture.rgb != undefined then --try and sync from p4
|
|
(
|
|
gRsPerforce.sync #(theTex.texture.rgb)
|
|
)
|
|
if doesFileExist theTex.texture.rgb == false then append theTextures ("MISSING:"+theTex.texture.rgb)
|
|
|
|
if (findItem theTextures theTex.texture.rgb) == 0 then --not seen before
|
|
(
|
|
append textures (buildTextureDataObject theTex)
|
|
append theTextures theTex.texture.rgb
|
|
append materialIDs id
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
--test for size
|
|
for t=1 to textures.count do
|
|
(
|
|
local tex = textures[t]
|
|
--check their dimensions
|
|
--img = openbitmap tex
|
|
--rowString = stringstream ""
|
|
--ones over 512 on both sides and live in the prop txtures folder prompt to convert to hdsplit texture process.
|
|
|
|
minTxSize = ddl_txSize.selected as Integer
|
|
if tex.imgData == undefined then
|
|
(
|
|
hasAlpha = if tex.alpha != "" then hasAlpha = true else false
|
|
--print tex.alpha
|
|
|
|
texName = ""
|
|
if hasAlpha then
|
|
(
|
|
texName = tex.name + tex.alpha
|
|
)
|
|
else
|
|
(
|
|
texName = tex.name
|
|
)
|
|
append listMaterialIDs materialIDs[t]
|
|
append listTextures #(tex.name, tex.type, tex.path, tex.propTexture, "ERROR", "ERROR", tex.hdsplit)
|
|
)
|
|
else if tex.imgData.width > minTxSize and tex.imgData.height > minTxSize then --check location
|
|
(
|
|
--format "% % PropTexture:%" tex.name tex.path tex.propTexture to:rowString
|
|
hasAlpha = if tex.alpha != "" then true else false
|
|
--print tex.alpha
|
|
combinedTexName = ""
|
|
if hasAlpha then
|
|
(
|
|
combinedTexName = tex.name + tex.alpha
|
|
)
|
|
else
|
|
(
|
|
combinedTexName = tex.name
|
|
)
|
|
append listMaterialIDs materialIDs[t]
|
|
append listTextures #(combinedTexName, tex.type, tex.path, hasAlpha, tex.propTexture, tex.imgData.width, tex.imgData.height, tex.hdsplit)
|
|
)
|
|
)
|
|
|
|
--update ui list
|
|
--lst_txResults.items = listTextures
|
|
for row=1 to listTextures.count do
|
|
(
|
|
local thisRow = listTextures[row]
|
|
local rowId = lstPropList.Rows.add thisRow
|
|
lstPropList.Rows.item[rowId].tag = listMaterialIDs[row]
|
|
)
|
|
)
|
|
|
|
-------------------------------
|
|
-- Events dear boy
|
|
-------------------------------
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
on btn_doAnalysis pressed do
|
|
(
|
|
doAnalysis()
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
on btn_doChanges pressed do
|
|
(
|
|
--get the list selection
|
|
selectedItems = lstPropList.selectedRows
|
|
selectedItemsIt = selectedItems.getenumerator()
|
|
|
|
--create new changelist for the changed tcs
|
|
if (changeListNum == undefined) then
|
|
(
|
|
changeListNum = (gRsPerforce.createChangeList "PropHDSplitter Changed TCS Files")
|
|
)
|
|
|
|
while selectedItemsIt.movenext() != false do
|
|
(
|
|
--if selectedItemsIt.current.cells.item[6].value == false then
|
|
--(
|
|
local texName = selectedItemsIt.current.cells.item[0].value
|
|
local matId = selectedItemsIt.current.tag
|
|
--get the tcs for the textures
|
|
local tcsPath = tcsPathRoot + (tolower texName) + ".tcs"
|
|
|
|
--sync latest
|
|
gRsPerforce.sync #(tcsPath)
|
|
|
|
|
|
if doesFileExist tcsPath != false then --make sure the tcs is local
|
|
(
|
|
--print tcsPath
|
|
|
|
--modify it with <imageSplitHD value="true" />
|
|
xmlDoc = XMlDocument()
|
|
xmlDoc.init()
|
|
xmlDoc.load ( tcsPath )
|
|
xmlRoot = xmlDoc.document.DocumentElement
|
|
|
|
if xmlRoot != undefined then
|
|
(
|
|
--check if it has the node already
|
|
local hasImageHDSplit = RsGetXmlElement xmlRoot "imageSplitHD"
|
|
|
|
if (hasImageHDSplit != undefined) then
|
|
(
|
|
--create the imageSplit node
|
|
imageSplitHD = xmlDoc.createElement "imageSplitHD"
|
|
imageSplitHDAttr = xmlDoc.createAttribute "value"
|
|
imageSplitHDAttr.value = "true"
|
|
imageSplitHD.setAttributeNode imageSplitHDAttr
|
|
|
|
--check for existing imageSplit nodes
|
|
imageSplitNodes = xmlRoot.getElementsByTagName "imageSplitHD"
|
|
if imageSplitNodes.count == 0 then
|
|
(
|
|
xmlRoot.appendChild imageSplitHD
|
|
)
|
|
else --lets remove the imageSplit duplicate nodes and replace with a fresh singular one
|
|
(
|
|
for i = (xmlRoot.childNodes.count - 1) to 0 by -1 do
|
|
(
|
|
thisNode = xmlRoot.childNodes.itemOf[i]
|
|
if thisNode.name == "imageSplitHD" then
|
|
(
|
|
xmlRoot.removeChild thisNode
|
|
)
|
|
)
|
|
--make sure we have at least one imageSplitHD node added
|
|
xmlRoot.appendChild imageSplitHD
|
|
)
|
|
gRsPerforce.add_or_edit #( tcsPath ) silent:false
|
|
xmlDoc.save ( tcsPath )
|
|
gRsPerforce.addToChangelist changeListNum tcsPath
|
|
)
|
|
else
|
|
(
|
|
--create the imageSplit node
|
|
imageSplitHD = xmlDoc.createElement "imageSplitHD"
|
|
imageSplitHDAttr = xmlDoc.createAttribute "value"
|
|
imageSplitHDAttr.value = "true"
|
|
imageSplitHD.setAttributeNode imageSplitHDAttr
|
|
|
|
xmlRoot.appendChild imageSplitHD
|
|
|
|
gRsPerforce.add_or_edit #( tcsPath ) silent:false
|
|
xmlDoc.save ( tcsPath )
|
|
gRsPerforce.addToChangelist changeListNum tcsPath
|
|
|
|
)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
if feedback == undefined then feedback = newscript()
|
|
format "Couldn't find this tcs file locally or in p4: % matID: % \n" tcsPath matId to:feedback
|
|
)
|
|
--)
|
|
)
|
|
|
|
--re-analyse the props
|
|
doAnalysis()
|
|
|
|
--remind checkin
|
|
checkinReminder()
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
on btn_removeHDSplit pressed do
|
|
(
|
|
--get the list selection
|
|
selectedItems = lstPropList.selectedRows
|
|
selectedItemsIt = selectedItems.getenumerator()
|
|
|
|
--create new changelist for the changed tcs
|
|
if (changeListNum == undefined) then
|
|
(
|
|
changeListNum = (gRsPerforce.createChangeList "PropHDSplitter Changed TCS Files")
|
|
)
|
|
|
|
while selectedItemsIt.movenext() != false do
|
|
(
|
|
local texName = selectedItemsIt.current.cells.item[0].value
|
|
local matId = selectedItemsIt.current.tag
|
|
--get the tcs for the textures
|
|
local tcsPath = tcsPathRoot + (tolower texName) + ".tcs"
|
|
|
|
--sync latest
|
|
gRsPerforce.sync #(tcsPath)
|
|
|
|
if doesFileExist tcsPath != false then --make sure the tcs is local
|
|
(
|
|
--Remove the <imageSplitHD value="true" />
|
|
xmlDoc = XMlDocument()
|
|
xmlDoc.init()
|
|
xmlDoc.load ( tcsPath )
|
|
xmlRoot = xmlDoc.document.DocumentElement
|
|
|
|
if xmlRoot != undefined then
|
|
(
|
|
local nodeOfInterest = RsGetXmlElement xmlRoot "imageSplitHD"
|
|
if nodeOfInterest != undefined then
|
|
(
|
|
format "tcs: % has node: % REMOVING\n" tcsPath nodeName
|
|
|
|
--check it out
|
|
gRsPerforce.add_or_edit tcsPath
|
|
gRsPerforce.addToChangelist changeListNum tcsPath
|
|
|
|
xmlroot.removechild nodeOfInterest
|
|
|
|
xmlDoc.save tcsPath
|
|
)
|
|
|
|
)
|
|
)
|
|
else
|
|
(
|
|
if feedback == undefined then feedback = newscript()
|
|
format "Couldn't find this tcs file locally or in p4: % matID: % \n" tcsPath matId to:feedback
|
|
)
|
|
)
|
|
|
|
--re-analyse the props
|
|
doAnalysis()
|
|
|
|
checkinReminder()
|
|
)
|
|
|
|
--/////////////////////////////////////////
|
|
--
|
|
--/////////////////////////////////////////
|
|
on PropHDSplit_UI open do
|
|
(
|
|
banner.setup()
|
|
init()
|
|
if gRsPerforce.connected() == false then gRsPerforce.connect()
|
|
)
|
|
)
|
|
|
|
createDialog PropHDSplit_UI width:1250 height:550 style:#(#style_titlebar, #style_border, #style_sysmenu, #style_minimizebox)
|