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

502 lines
14 KiB
Plaintext
Executable File

/*
Wetness fix tool
read csv report
present in listview
filter by open containers
select item will focus material in mateditor and also objects in the scene with the material applied
fix button will apply the old value to the mwetness in the material
*/
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
struct sReportItem
(
containerName = "",
drawableName = "",
materialIndex = 0,
material = "",
shaderPreset = "",
wetnessOld = 0.0,
wetnessNew = 0.0
)
--/////////////////////////////////////////
--
--/////////////////////////////////////////
fn getDrawableMaterialFromSva containerName drawableName matIdx =
(
--matIdx is 0 based so increment by 1
matIdx += 1
-- local sceneConts = for cont in RsMapGetMapContainers() collect cont
--
-- local sceneContsNames = for cont in sceneConts collect (tolower cont.name)
-- local thisCont = findItem sceneContsNames (tolower containerName)
-- if (thisCont == 0) then
-- (
-- return undefined
-- )
local obj = getNodeByName drawableName
if (obj == undefined) then
(
--gRsUlog.LogError (" Does not exist in the scene")
--gRsUlog.Validate()
return undefined
)
---------------------------------------------------------
-- Analyse materials
---------------------------------------------------------
local ids = RsGetMatIdsUsedByObj obj
-- Collect material, its expected index in entity.type, and shader-name:
struct matItemStruct (material, matId, svaMatIdx = 1, shaderName)
local objMat = obj.material
local matItems = #()
case (classOf objMat) of
(
multimaterial:
(
local svaMatIdx = 0
for usedId in ids do
(
svaMatIdx += 1
local subMatIdx = findItem objMat.materialIDlist usedId
if (subMatIdx != 0) do
(
local subMat = objMat.materiallist[subMatIdx]
if (isKindOf subMat Rage_shader) do
(
append matItems (matItemStruct material:subMat matId:usedId svaMatIdx:svaMatIdx shaderName:(RstGetShaderName subMat))
)
)
)
)
Rage_shader:
(
append matItems (matItemStruct material:objMat svaMatIdx:1 shaderName:(RstGetShaderName objMat))
)
)
local matMatch = undefined
for item in matItems where (item.matId == matIdx) do
(
matMatch = item.material
)
--return
matMatch
)
--/////////////////////////////////////////
--
--/////////////////////////////////////////
fn lineProcessor csvLine =
(
local bits = for item in (filterString csvLine ",") collect (trimLeft item)
if bits[1] != "containername" do --its not the column names
(
local reportItem = sReportItem()
reportItem.containerName = bits[1]
reportItem.drawableName = bits[2]
reportItem.materialIndex = bits[3] as Integer
reportitem.shaderPreset = bits[4]
reportItem.wetnessOld = bits[5] as Float
reportItem.wetNessNew = bits[6] as Float
--print "......"
--print (classOf reportItems)
--get the scene material from the materialIdx
reportItem.material = getDrawableMaterialFromSva reportItem.containerName reportItem.drawableName reportItem.materialIndex
append ::WetnessReportUI.wetnessReport.reportItems reportItem
)
)
struct sWetnessReport
(
--reportPath = "x:/gta5/assets/reports/svaDifferences.csv",
reportRoot = "x:/gta5/assets/reports/wetness_check/",
reportPath = "x:/gta5/assets/reports/wetness_check/_citye/downtown_01/dt1_00.csv",
--reportPath = "c:/temp/svaDifferences.csv",
reportItems = #(),
--/////////////////////////////////////////
--
--/////////////////////////////////////////
fn readReport =
(
reportItems = #()
--read the report
format "reading: %\n" reportPath
local csv = CSVReader()
csv.csvFile = reportPath
csv.processingFn = lineProcessor
csv.open()
csv.close()
)
)
--/////////////////////////////////////////
-- UI
--/////////////////////////////////////////
try(destroyDialog WetnessReportUI)catch()
rollout WetnessReportUI "Wetness Fix" width:600 height:825
(
--/////////////////////////////////////////
-- VARIABLES
--/////////////////////////////////////////
local wetnessReport = sWetnessReport()
local headers = #("Container", "Drawable", "Material Name", "Shader Preset", "Wetness Old", "Wetness New")
local firstSelectedObj = undefined
local materialFromRow = undefined
------------------------------------------------------------------------------------
-- DotNet values:
------------------------------------------------------------------------------------
local textFont, dingFont, textFontBold
local DNknownColour = dotNetClass "system.Drawing.KnownColor"
local DNcolour = dotNetClass "System.Drawing.Color"
local selColour = DNcolour.fromKnownColor DNknownColour.MenuHighlight
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])
local sectionRowDict = dotNetObject "RSG.MaxUtils.MaxDictionary"
--/////////////////////////////////////////
-- CONTROLS
--/////////////////////////////////////////
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:WetnessReportUI.width
local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"CHANGEME" filename:(getThisScriptFilename())
edittext edtReportPath text:wetnessReport.reportPath width:(WetnessReportUI.width - 80) across:2
button btnBrowsePath "..." align:#right
dotNetControl lstItemList "System.Windows.Forms.DataGridView" height:700 align:#center
dotNetControl prgProgress "System.Windows.Forms.ProgressBar" width:(WetnessReportUI.width - 20) align:#center
button btnRefreshList "Refresh" across:3
button btnFilterOpenContainer "Show Open Containers"
button btnFixSelected "Fix Selected"
--/////////////////////////////////////////
-- FUNCTIONS
--/////////////////////////////////////////
fn init =
(
lstItemList.SelectionMode = lstItemList.SelectionMode.FullRowSelect
lstItemList.AllowUserToAddRows = false
lstItemList.AllowUserToDeleteRows = false
lstItemList.AllowUserToOrderColumns = true
lstItemList.AllowUserToResizeRows = false
lstItemList.AllowUserToResizeColumns = false
lstItemList.AllowDrop = false
lstItemList.MultiSelect = true
lstItemList.ReadOnly = true
lstItemList.dock = lstItemList.dock.fill
lstItemList.DefaultCellStyle.backColor = backColour
lstItemList.DefaultCellStyle.foreColor = textColour
lstItemList.AlternatingRowsDefaultCellStyle.BackColor = altBackColour
textFont = lstItemList.font
dingFont = dotNetObject "System.Drawing.Font" "Webdings" textFont.size
textFontBold = dotnetobject "system.drawing.font" textFont (dotnetclass "system.drawing.fontstyle").bold
lstItemList.EnableHeadersVisualStyles = false
lstItemList.ColumnHeadersDefaultCellStyle.backColor = backColour
lstItemList.ColumnHeadersDefaultCellStyle.foreColor = textColour
lstItemList.ColumnHeadersDefaultCellStyle.font = textFontBold
lstItemList.ColumnHeadersHeight = 34
lstItemList.RowHeadersVisible = false
--lstItemList.AutoSizeColumnsMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnsMode").AllCellsExceptHeader
startSize = [1290, 500]
--arrangeCtrls size:startSize
local colNum
for item in headers do
(
colNum = lstItemList.Columns.add item item
lstItemList.Columns.item[colNum].minimumWidth = 75
lstItemList.Columns.item[colNum].autoSizeMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnMode").AllCellsExceptHeader
)
local firstCol = lstItemList.Columns.item[0]
--local lastCol = lstItemList.Columns.item[colNum]
firstCol.width = 160
--lastCol.AutoSizeMode = lastCol.AutoSizeMode.AllCellsExceptHeader
windows.processPostedMessages()
)
fn createTest =
(
--lstItemList.rows.add #("CH2_05f", "ch2_05f_Hs02_Dtld", 0, "default", 1.0, 0.55 )
testData = sReportItem()
testData.containerName = "CH2_05f"
testData.drawableName = "ch2_05f_Hs02_Dtld"
testData.materialIndex = 0
testData.shaderPreset = "default"
testData.wetnessOld = 0.055
testData.wetNessNew = 1.0
append wetnessReport.reportItems testData
)
--/////////////////////////////////////////
-- Update the list
--/////////////////////////////////////////
fn updateList list =
(
lstItemList.Rows.Clear()
local listCounter = 1
for item in list do
(
--process material name
materialName = "UNKNOWN"
if (item.material != undefined) then
(
materialName = item.material.name
)
local listNum = lstItemList.rows.add #(item.containerName, item.drawableName, materialName, item.shaderPreset, item.wetnessOld, item.wetNessNew)
lstItemList.rows.item[listNum].tag = listCounter
listCounter += 1
)
)
--/////////////////////////////////////////
-- EVENTS
--/////////////////////////////////////////
--/////////////////////////////////////////
--
--/////////////////////////////////////////
on btnBrowsePath pressed do
(
local chosenPath = getOpenFileName caption:"Report location" filename:wetnessReport.reportPath types:"CSV(*.csv)|*.csv"
if chosenPath != undefined then
(
edtReportPath.text = chosenPath
wetnessReport.reportPath = chosenPath
wetnessReport.readReport()
updateList wetnessReport.reportItems
)
)
on btnRefreshList pressed do
(
wetnessReport.readReport()
updateList wetnessReport.reportItems
)
--/////////////////////////////////////////
-- Filter by open containers
--/////////////////////////////////////////
on btnFilterOpenContainer pressed do
(
containerNames = for item in RsMapGetMapContainers() collect (tolower item.name)
local filterList = #()
for item in wetnessReport.reportItems do
(
for name in containerNames do
(
if (MatchPattern item.containerName pattern:name) then append filterList item
)
)
updateList filterList
)
--/////////////////////////////////////////
--
--/////////////////////////////////////////
on btnFixSelected pressed do
(
if lstItemList.selectedRows.count != 0 then
(
for i=1 to lstItemList.selectedRows.count do
(
local thisRow = lstItemList.selectedRows.item[i-1]
--get the value
local oldWetness = thisRow.cells.item[4].value
local materialName = thisRow.cells.item[2].value
--set the wetness shaderVar to the old value
local obj = getNodeByName thisRow.cells.item[1].value
--get the material
local objMat = obj.material
if ((classOf objMat) == Multimaterial) then
(
for mat in objMat.materialList do
(
if (mat.name == materialName) then
(
for idx=1 to (RstGetVariableCount mat) do
(
if ((RstGetVariableName mat idx) == "Wetness multiplier") do
(
RstSetVariable mat idx oldWetness
)
)
)
)
)
else
(
for idx = 1 to (RstGetVariableCount objMat) do
(
if ((RstGetVariableName objMat idx) == "Wetness multiplier") do
(
RstSetVariable objMat idx oldWetness
)
)
)
)
)
)
--/////////////////////////////////////////
--
--/////////////////////////////////////////
on lstItemList CellMouseDoubleClick e do
(
--get row
if (e.RowIndex >= 0) do
(
local cellName = lstItemList.rows.item[e.RowIndex].cells.item[1].value
--select and frame name object if possible
local obj = getNodeByName cellName
clearSelection()
if (obj != undefined) do
(
select obj
max zoomext sel all
)
)
)
--/////////////////////////////////////////
--
--/////////////////////////////////////////
on lstItemList mouseDown args do
(
local clickPoint = dotNetObject "System.Drawing.Point" args.x args.y
local clickedItem = lstItemList.hitTest args.x args.y
if (clickedItem != undefined) do
(
local rowNum = clickedItem.rowIndex
if (rowNum != -1) and (lstItemList.selectedRows.count != 0) do
(
firstSelectedObj = lstItemList.rows.item[rowNum].cells.item[1].value
local rowTag = lstItemList.rows.item[rowNum].tag
materialFromRow = wetnessReport.reportItems[rowTag].material
local rightClick = args.button.equals args.button.right
if rightClick then
(
-- Rightclick menu:
rcmenu RSmenu_WetnessItem
(
local selRows
menuItem itmSelMaterial "Select material"
-- Select material
on itmSelMaterial picked do
(
--obj = rowNum
print "selecting material"
print firstSelectedObj
if not MatEditor.isOpen() do
(
MatEditor.open()
)
local obj = getNodeByName firstSelectedObj
if (obj != undefined) then
(
if (materialFromRow == undefined) then --use the obj.material
(
meditMaterials[1] = obj.material
)
else
(
meditMaterials[1] = materialFromRow
)
)
)
)
popUpMenu RSmenu_WetnessItem
)
)
)
)
--/////////////////////////////////////////
--
--/////////////////////////////////////////
on WetnessReportUI open do
(
init()
banner.setup()
--createTest()
gRsPerforce.sync (wetnessReport.reportRoot + "....csv")
wetnessReport.readReport()
updateList wetnessReport.reportItems
)
)
createDialog WetnessReportUI