Files
gtav-src/tools_ng/wildwest/script/3dsMax/General_tools/TexTXD.ms
T
2025-09-29 00:52:08 +02:00

404 lines
12 KiB
Plaintext
Executable File

--TexTXD
-- url:bugstar:313343
--Neil Gregory
-----------------------------------------------------------------------------
-- Uses
-----------------------------------------------------------------------------
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
filein "rockstar/util/material.ms" -- loaded on startup by startup.ms
-- .Net ListView Control
--filein ( (getdir #maxroot) + "stdplugs/stdscripts/NET_ListViewWrapper.ms" )
-----------------------------------------------------------------------------
-- .Net Initialisation
-----------------------------------------------------------------------------
dotNet.loadAssembly "System.Windows.Forms.dll"
dotNet.loadassembly "MaxCustomControls.dll"
RS_CustomDataGrid()
struct TextureObject
(
name, --bare name
path, --file path
width, --pixels
height, --pixels
size, --KB
txdList = #(), --TXDs belongs to
fn getArea =
(
return (width * height)
)
)
-----------------------------------------------------------------------------
-- Rollout
-----------------------------------------------------------------------------
try (DestroyDialog TXDSpy_UI)catch()
rollout TXDSpy_UI "Texture Map TXD Statistics"
(
-----------------------------------------------------------------------------------------
-- Script-scope Variables
-----------------------------------------------------------------------------------------
local appTitle = "Texture Map TXD Statistics"
local sceneTXDTextures = #()
local objectTextures = #() --#(name: val:#(tdxlist), memory, area )
local txdList = RsGetSceneTxdList()
local txdAttrIdx = getattrindex "Gta Object" "TXD"
local pieHeaders = #(#("ID", 30), #("Object", 100), #("Texture Name", 150), #("Mem Share", 150))
local affinityHeaders = #(#("ID", 30), #("Texture Name", 150))
local DNcolour = dotNetClass "System.Drawing.Color"
local textCol = (colorMan.getColor #windowText) * 255
local windowCol = (colorMan.getColor #window) * 255
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)
-----------------------------------------------------------------------------------------
-- UI Widgets and Layout
-----------------------------------------------------------------------------------------
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:TXDSpy_UI.width
local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"TextureTXDUsage" filename:(getThisScriptFilename())
--button btnUpdate "Update" align:#left width:100 across:3
group ""
(
dropdownlist ddl_TXDList "SceneTXDs:" items:txdList tooltip:"Scene TXD selector"
checkButton btnAffinity "Object Texture Affinity" align:#left tooltip:"Textures common amongst object selection"
)
--hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Texture_TXD_Stats" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255)
--dotNetControl lstView "System.Windows.Forms.DataGridView" height:(300-65)
dotNetControl lstView "RsCustomDataGridView" width:595 height:(300-65) offset:[-10, 0]
progressbar barProgress
--button btnClose "Close" align:#right width:100
-----------------------------------------------------------------------------------------
-- Functions
-----------------------------------------------------------------------------------------
fn buildSceneTextureObjects =
(
--lets build the textureObjects for those in the sscene TXDs
for txd in txdList do
(
texmaplist = #()
RsGetTexMapsByTxdNameNoStrip texmaplist #() #() #() txd
for tex in texmaplist do
(
tex = (filterString tex "+")[1] --in case of a double texture take the first bitmap path
texName = getFileNameFile tex
--print texName
--add to dict
texExists = (for tex in sceneTXDTextures where tex.name == texName collect tex)[1]
--format "texExists: % \n" texExists
if texExists == undefined then
(
txObj = TextureObject()
txObj.name = texName
txObj.path = tex
texBmp = if doesFileExist tex then openBitmap tex
if texBmp != undefined then
(
txObj.width = texBmp.width
txObj.height = texBmp.height
)
txObj.size = (getfilesize tex) / 1024
free texBmp
txObj.txdList = append txObj.txdList txd
append sceneTXDTextures (DataPair name:texName obj:txObj)
)
else --this texture object already exists, update its txd list
(
append texExists.obj.txdList txd
)
--get the file path
--RsGetTexMapTextures tex
)
)
)
fn TXDSpy =
(
if btnAffinity.checked == true then
(
TXDSpy_UI.columnHeaders "affinity"
TXDSpy_UI.sharedTextures()
return true
)
TXDSpy_UI.columnHeaders "pie"
--lstView.ListViewItemSorter = dotNetObject "GenericEditor.cListViewColumnNullSorter"
lstView.rows.Clear()
textureData = #()
txdList = RsGetSceneTxdList()
--Now match the selection with the built array/dict to determine usage and efficiency
--get the textures on the selection and match against the sceneTXDs
for obj in $selection do
(
objectTextures = #()
objTex = #()
RsGetTexMapsFromMaterial obj obj.material objTex #() #()
--RsGetTexMapListForMat $.material objectTex matIdList:matIDs
--TXDTextures = #()
--give the number of matches and % of memory for each texture on the selected object
TXDMatches = #()
memCompare = #()
areaCompare = undefined
for tex in objTex do
(
tex = (filterString tex "+")[1] --in case of a double texture take the first bitmap path
--Texture properties
--see if the object texture exists already in sceneTXDTextures and retrieve its propertes from there
texArea = undefined
texMemory = undefined
texObj = (for texItem in sceneTXDTextures where texItem.obj.name == tex collect texItem.obj)[1]
if texObj == undefined then continue
texArea = texObj.getArea()
texMemory = texObj.size
--now collect up all the texture area and memory for each TXD the texture is used in and compare to its own properties
TXDareaShare = 0
TXDmemShare = 0
--format "tex: % texObj: % \n" tex texObj.txdList
--get the txd match
objectTXD = tolower (getAttr obj txdAttrIdx)
UITXD = ddl_TXDList.selected
TXD = (for txd in texObj.txdList where UITXD == txd collect txd)[1]
--format "TXD: % \n" TXD
if TXD != undefined then --for txd in texObj.txdList where (getAttr obj txdAttrIdx) == txd do
(
texTXDTotalArea = 0
texTXDTotalMem = 0
--get the txd textures
TXDTextures = #()
RsGetTexMapsByTxdName TXDTextures #() #() #() TXD srcobjlist:#(obj)
--get the textureObjects for those textures
TXDTextureObjs = #()
for tex in TXDTextures do
(
--find the object
texObj = (for texItem in sceneTXDTextures where texItem.obj.name == tex collect texItem.obj)[1]
if texObj != undefined then
(
texTXDTotalArea += texObj.getArea()
texTXDTotalMem += texObj.size
)
)
--TXDareaShare = (texArea * (100.0 / texTXDTotalArea))
TXDmemShare = (texMemory * (100.0 / texTXDTotalMem))
if TXDmemShare < 0 or TXDmemShare > 100 then TXDmemShare = "--"
)
append objectTextures (DataPair name:obj.name props:#(tex, TXD, "TXDareaShare", TXDmemShare))
)
append textureData objectTextures
--TXDMatches = makeUniqueArray TXDMatches
--format "TXDMatches: %\n" TXDMatches
--format "objectTextures: %\n" objectTextures
)
count = 0
for objTx in textureData do
(
--random
--lstView.RowsDefaultCellStyle.backColor = DNcolour.FromArgb (random (windowCol[1]-30) windowCol[1]) (random (windowCol[2]-30) windowCol[2]) (random (windowCol[3]-30) windowCol[3])
objRowCol = DNcolour.FromArgb (random (windowCol[1]-40) windowCol[1]) (random (windowCol[2]-40) windowCol[2]) (random (windowCol[3]-40) windowCol[3])
for tex in objTx do
(
rowID = lstView.rows.Add #( count, tex.name, tex.props[1], tex.props[4] as Integer)
lstView.rows.item[rowId].DefaultCellStyle.backColor = objRowCol
count += 1
)
)
--print the number (and if expanded the names) of the shared textures used between any random selection of objects.
)
fn sharedTextures =
(
--clear the decks
lstView.rows.Clear()
if $selection.count < 2 then return false
commonTextures = #()
textureLib = #()
--get the textures from each object
for obj in $selection where isKindOf obj GeometryClass do
(
objectTextures = #()
objTex = #()
RsGetTexMapsFromMaterial obj obj.material objTex #() #()
print objTex
append textureLib (DataPair obj:obj textures:objTex)
)
--now boil em up to extract the common textures.
--texture centric obj arrays
for lib in textureLib do
(
--print lib
for tex in lib.textures do
(
for sibling in textureLib where sibling != lib do
(
for sibTex in sibling.textures where tex == sibTex do
(
append commonTextures tex
)
)
)
)
commonTextures = makeUniqueArray commonTextures
--format "common Textures: % \n" commonTextures
--format "count: % \n" commonTextures.count
count = 0
for tex in commonTextures do
(
lstView.rows.Add #( count, tex)
count += 1
)
)
fn columnHeaders mode =
(
--lvops.ClearColumns lstView
lstView.columns.Clear()
case mode of
(
"pie":
(
for item in pieHeaders do
(
num = lstView.columns.Add item[1] item[1]
lstView.columns.Item[num].minimumWidth = item[2]
lstView.columns.Item[num].autoSizeMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnMode").AllCellsExceptHeader
)
)
"affinity":
(
for item in affinityHeaders do
(
num = lstView.columns.Add item[1] item[1]
lstView.columns.Item[num].minimumWidth = item[2]
lstView.columns.Item[num].autoSizeMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnMode").AllCellsExceptHeader
)
)
default:
(
for item in pieHeaders do
(
num = lstView.columns.Add item[1] item[1]
lstView.columns.Item[num].minimumWidth = item[2]
lstView.columns.Item[num].autoSizeMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnMode").AllCellsExceptHeader
)
)
)
)
fn init =
(
format "listView: % \n" lstView
lstView.AllowUserToAddRows = false
lstView.AllowUserToDeleteRows = false
lstView.AllowUserToOrderColumns = true
lstView.AllowUserToResizeRows = false
lstView.AllowUserToResizeColumns = false
lstView.AllowDrop = false
lstView.MultiSelect = true
lstView.ReadOnly = true
lstView.AutoSizeColumnsMode = (dotNetClass "DataGridViewAutoSizeColumnsMode").Fill
lstView.dock = lstView.dock.fill
lstView.DefaultCellStyle.backColor = backColour
lstView.DefaultCellStyle.foreColor = textColour
lstView.SelectionMode = (dotNetClass "DataGridViewSelectionMode").FullRowSelect
--lstView.AlternatingRowsDefaultCellStyle.BackColor = altBackColour
)
-----------------------------------------------------------------------------------------
-- Events dear boy
-----------------------------------------------------------------------------------------
on btnUpdate pressed do
(
columnHeaders "pie"
TXDSpy()
)
on btnAffinity changed arg do
(
if arg then
(
columnHeaders "affinity"
sharedTextures()
)
else
(
columnHeaders "pie"
TXDSpy()
)
)
fn ddlSelector item =
(
columnHeaders "pie"
TXDSpy()
)
on ddl_TXDList selected item do ddlSelector item
/*
on lstView ColumnClick args do
(
sorting = dotNetClass "System.Windows.Forms.SortOrder"
lstView.Sorting = sorting.Ascending
lstView.ListViewItemSorter = dotNetObject "GenericEditor.cListViewColumnIntSorter" args.Column
lstView.Sort()
)
*/
on TXDSpy_UI open do
(
banner.setup()
init()
columnHeaders "pie"
buildSceneTextureObjects()
callbacks.removeScripts id:#TexTXD
callbacks.addScript #SelectionSetChanged "TXDSpy_UI.TXDSpy()" id:#TexTXD
TXDSpy()
)
on TXDSpy_UI close do
(
callbacks.removeScripts id:#TexTXD
)
)
CreateDialog TXDSpy_UI width:600 height:400 \
--TXDSpy()