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

387 lines
11 KiB
Plaintext
Executable File

/*
Props CSV
*/
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
struct propCSVobjStruct
(
vals = #(),
section = "[NO SECTION]",
isProp = false,
-- Headers supported by this structure (as function, so not stored by every instance of struct)
fn getHeaders = #("Name", "Section", "Parent Area", "Grandparent Area", "Tri Count", "Instance Count", \
"Texture Count", "Shader Count", "Lod Distance", "TXD Name", "Mover Collision", \
"Weapons Collision", "Camera Collision", "River Collision"),
fn getClasses = #(string, string, string, string, integer, integer, \
integer, integer, integer, string, integer, \
integer, integer, integer),
fn getHeaderNames = for item in (propCSVobjStruct.getHeaders()) collect ((RsRemoveSpaces item) as name)
)
struct propCSVParserStruct
(
--sync latest map_objects.csv file
mapObjsFilename = "x:/gta5/assets_ng/reports/asset_usage/map_objects.csv",
--FUNCTIONS
on create do
(
gRsPerforce.connect()
gRsPerforce.p4.run "sync" #(mapObjsFilename)
),
fn parse =
(
local retVal = #()
local objPropNames = propCSVobjStruct.getHeaderNames()
local objPropClasses = propCSVobjStruct.getClasses()
local f = undefined
local maxlen = 0
try
(
f = openfile mapObjsFilename
--find end of file length for progress
seek f #eof
maxlen = filepos f
seek f 0
)
catch
(
return retVal
)
-- Read first line, match it up against the struct-headers:
local thisLine = readline f
local headerNames = for item in (filterString thisLine ",") collect ((RsRemoveSpaces (trimLeft item)) as name)
local headerValIdxs = for item in headerNames collect (findItem objPropNames item)
local usedHeaderNums = #{}
local headerClasses = #()
-- See if any headers weren't found in list:
for n = 1 to headerValIdxs.count do
(
local idx = headerValIdxs[n]
if (idx != 0) do
(
usedHeaderNums[n] = true
headerClasses[n] = objPropClasses[idx]
)
)
local objNum = 0
::propCSVParserUI.prgProgress.value = 0
local sectionIdx = findItem headerNames #section
local grandparentAreaIdx = findItem headerNames #grandparent_area
while not eof f do
(
local newStruct = propCSVobjStruct()
newStruct.vals.count = objPropNames.count
local vals = newStruct.vals
local thisLine = readline f
local rowData = filterString thisLine ","
rowData = for item in rowData collect (trimLeft item)
for headerNum = usedHeaderNums do
(
local stringVal = rowData[headerNum]
local setClass = headerClasses[headerNum]
vals[headerValIdxs[headerNum]] = (stringVal as setClass)
)
newStruct.section = rowData[sectionIdx]
newStruct.isProp = matchPattern rowData[grandparentAreaIdx] pattern:"props"
-- Only update progress-bar every so often:
if (mod objNum 100) == 0 do
(
local currentPos = filePos f
::propCSVParserUI.prgProgress.value = (100.0 * currentPos / maxlen)
)
append retVal newStruct
objNum += 1
)
::propCSVParserUI.prgProgress.value = 100.0
-- hide progress-bar:
::propCSVParserUI.prgProgress.pos.y -= 1000
try
(
close f
)
catch(messageBox "Could not close file stream" title:"Error")
return retVal
)
)
--///////////////////////////////////////////////////////////////////
-- UI
--///////////////////////////////////////////////////////////////////
try(DestroyDialog propCSVParserUI) catch()
rollout propCSVParserUI "Prop Report Data"
(
local sectionRows
--create prop parser
local propCSVParser = propCSVParserStruct()
----------------------------------------------------------------------------------
-- CONTROLS
----------------------------------------------------------------------------------
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:propCSVParserUI.width
local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"Prop Report Parser" filename:(getThisScriptFilename())
--dotNetControl lstPropList "RsCustomDataGridView" height:500 align:#center
dotNetControl lstPropList "System.Windows.Forms.DataGridView" height:500 align:#center
dotNetControl prgProgress "System.Windows.Forms.ProgressBar" width:1100 align:#center offset:[0, -40]
--dotNetControl dncPropList "System.Windows.Forms.ListView"
group ""
(
dropdownlist ddlSection "Section:" align:#left across:2
button btnSelect "Select highlighted objects"
)
------------------------------------------------------------------------------------
-- 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"
fn arrangeCtrls size:[propCSVParserUI.width, propCSVParserUI.height] =
(
lstPropList.width = size.x - 25
lstPropList.height = size.y - 44
--barProgress.width = size.x - barProgress.pos.x - 54
--lnkHelp.pos.x = size.x - 40
)
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 = [1290, 500]
arrangeCtrls size:startSize
local colNum
local headers = propCSVobjStruct.getHeaders()
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
banner.setup()
windows.processPostedMessages()
)
fn sectionSelector num =
(
lstPropList.Rows.Clear()
for rowData in sectionRows[num] do
(
lstPropList.rows.add rowData
)
print sectionRows[num].count
)
fn update =
(
lstPropList.Rows.Clear()
-- Populate listview
local objList = propCSVParser.parse()
local sectionNames = #("[ALL]")
sectionRows = #(#())
-- Only include Prop objects:
for item in objList where item.isProp do
(
local rowData = item.vals
local rowSection = item.section
-------------------------------
--Filter the data by Section:
-------------------------------
local findNum = findItem sectionNames rowSection
if (findNum == 0) do
(
append sectionNames rowSection
append sectionRows #()
findNum = sectionNames.count
)
append sectionRows[1] rowData
append sectionRows[findNum] rowData
)
objList = undefined
gc light:true
-- Sort section-names:
local sectionData = for n = 1 to sectionNames.count collect (dataPair name:sectionNames[n] rows:sectionRows[n])
fn sortSections v1 v2 = (striCmp v1.name v2.name)
qsort sectionData sortSections
sectionNames = for item in sectionData collect item.name
sectionRows = for item in sectionData collect item.rows
--populate section list
ddlSection.items = sectionNames
-- Set to default [ALL] section:
sectionSelector 1
)
fn selectByNames names =
(
local selObjs = #()
local refObjs = for obj in objects where isRsRef obj collect obj
for objName in names do
(
local getObj = getNodeByName objName
if (getObj != undefined) do
(
appendIfUnique selObjs getObj
)
local getRefs = for obj in refObjs where (matchPattern obj.objectName pattern:objName) collect obj
join selObjs getRefs
)
if selObjs.count != 0 do
(
clearSelection()
select selObjs
max zoomext sel all
)
)
-----------------------------------------------
--Events dear boy
-----------------------------------------------
on lstPropList SortCompare e do
(
local val1 = e.CellValue1
e.SortResult = if isKindOf val1 number then (val1 - e.CellValue2) else (striCmp val1 e.CellValue2)
e.Handled = True
)
on lstPropList CellMouseDoubleClick e do
(
--get row
if (e.RowIndex >= 0) do
(
local cellName = lstPropList.rows.item[e.RowIndex].cells.item[0].value
--select and frame name object if possible
selectByNames #(cellName)
)
)
on btnSelect pressed do
(
local getNames = #()
--get selected rows
selectedItems = lstPropList.selectedRows
selectedItemsIt = selectedItems.getenumerator()
while selectedItemsIt.movenext() != false do --select the ones that match in the scene
(
append getNames selectedItemsIt.current.cells.item[0].value
)
selectByNames getNames
)
on ddlSection selected arg do sectionSelector arg
on propCSVParserUI open do
(
init()
update()
)
)
--createDialog
createDialog propCSVParserUI width:1290 height:625 style:#(#style_titlebar, #style_border, #style_sysmenu, #style_minimizebox)