Files
gtav-src/tools_ng/dcc/current/max2012/scripts/rockstar/helpers/scenestats.ms
T
2025-09-29 00:52:08 +02:00

1802 lines
52 KiB
Plaintext
Executable File

--
-- File:: rockstar/helpers/scenestats.ms
-- Description:: Gta Scene Statistics
--
-- Author:: Greg Smith <greg.smith@rockstarnorth.com
-- Author:: Luke Openshaw <luke.openshaw@rockstarnorth.com
-- Date:: 31/1/2007
--
-----------------------------------------------------------------------------
try (DestroyDialog RsSceneStatsRoll) catch ()
-----------------------------------------------------------------------------
-- Uses
-----------------------------------------------------------------------------
--filein "rockstar/export/settings.ms"
filein "pipeline/export/maps/mapsetup.ms"
-----------------------------------------------------------------------------
-- Globals
-----------------------------------------------------------------------------
struct RsSceneStats_objInfo
(
Private
TexStructs = #(),
Public
showName = "", objName = "", filename = "",
obj, instances = #(), row,
materials = #(), matIds = #(),
faces = 0, collFaces = 0, shaders = 0,
lodDistance, txd, txdTexCount,
modelSize = "unknown", txdsize = "unknown", totalSize = "unknown",
volume = 0,
faceDensity = 0,
refDef,
isLod = false,
isRef = false,
isIref = false,
isProp = false,
isInterior = false,
memDensity = "unknown", txdPercent,
commonCount, uniqueCount, nonUniqueCount,
fn GetTexStructs = (return TexStructs),
-- Functions to provide names and values for object-list columns:
fn getColNames = #("Name", "Instances", "Textures", "Faces", "Coll Faces", "LOD Dist", "TXD Name", "TXD Textures", "Shaders", "Volume", "Face Density", "TXD %", "Model Size (k)", "TXD Size (k)", "Total Size (k)", "Mem Density"),
fn getColVals = #(showName, instances.count, texStructs.count, faces, collFaces, loddistance, txd, txdTexCount, shaders, volume, faceDensity, txdPercent, modelSize, txdsize, totalSize, memDensity)
)
struct RsSceneStats_objTexInfo
(
name, texmap,
row,
faces = 0,
width, height, size,
matids = #(),
objStructs = #(),
objFaces = #(),
showObjs, showObjCount, showInstCount, showMatId, showTXDCount,
-- Functions to provide names and values for texture-list columns:
fn getColNames = #("Name", "Faces", "Width", "Height", "Size (k)", "MatID", "Objects", "Instances", "TXDs"),
fn getColVals = #(name, faces, width, height, size, showMatId, showObjCount, showInstCount, showTXDCount)
)
-----------------------------------------------------------------------------
-- Rollouts
-----------------------------------------------------------------------------
rollout RsSceneStatsRoll "Scene Stats"
(
--////////////////////////////////////////////////////////////
-- interface
--////////////////////////////////////////////////////////////
hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Scene_Stats" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255)
groupBox grpUpdate "Objects:" align:#left offset:[0,-20] height:55 width:666
checkbox chkIncludeRefs "Include RsRefs" checked:true pos:(grpUpdate.pos + [10,16])
checkbox chkIncludeStnd "Include Standard" offset:[110,-20] checked:true
checkbox chkFragmentChildren "Frag Children" offset:[222,-20]
checkbox chkFileData "File Data" offset:[316,-20] checked:true enabled:false
radioButtons rdoSelAll "" labels:#("Selection", "All") columns:1 offset:[384,-28] align:#left
local btnWidth = 100
button cmdUpdate "v Update List v" align:#left width:btnWidth pos:[470,18]
button cmdRefresh "v Refresh List v" align:#left width:btnWidth pos:[570,18]
button cmdSaveCurrent "Save To File" align:#left width:btnWidth pos:(cmdRefresh.pos + [btnWidth + 20,0])
button cmdSaveReport "Save Report" align:#left width:btnWidth pos:(cmdSaveCurrent.pos + [btnWidth + 10,0])
dotNetControl barProgress "Windows.Forms.Progressbar" width:(grpUpdate.width - 12) height:8 pos:(grpUpdate.pos + [6, grpUpdate.height - 14])
dotNetControl dnObjectList "RsCustomDataGridView" pos:(grpUpdate.pos + [0,grpUpdate.height - 1])
label lblTextures "Selected Object's Textures:" align:#left
dotNetControl dnTextureList "RsCustomDataGridView" align:#left
bitmap bmpTex offset:[200,-300] width:200 height:200
local btnWidth = 200
button cmdSelectFaces "Show Selected Texture Faces On:" align:#left width:btnWidth
dropdownlist lstObjectNames width:btnWidth
button cmdSelectObj "Select Object" align:#left width:btnWidth
button cmdEdit "Edit in Photoshop" align:#left width:btnWidth
button cmdPerforce "Perforce check-out" align:#left width:btnWidth
button btnRefreshTx "Refresh" align:#left width:btnWidth height:60
local texCtrls = #(cmdSelectFaces, lstObjectNames, cmdSelectObj, cmdEdit, cmdPerforce, btnRefreshTx)
--edittext dnCountText readOnly:true height:40
dotNetControl dnCountText "MaxCustomControls.MaxTextBox"
local startSize
local selObjList = #()
local selObjTexInfoList = #()
local showTexInfoList = #()
------------------------------------------------------------------------------------
-- 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]
--////////////////////////////////////////////////////////////
-- methods
--////////////////////////////////////////////////////////////
fn GetIniRolloutSize =
(
RsSettingsReadValue "RsStatsRoll" "size" [1150, 520]
)
fn GetTextureWidth texMap =
(
width = 0
try
(
width = texMap.bitmap.width
)
catch
(
)
width
)
fn GetTextureHeight texMap =
(
height = 0
try
(
height = texMap.bitmap.height
)
catch
(
)
height
)
fn GetTextureSize texMap =
(
size = (getfilesize texMap.filename) / 1024
size
)
fn GetTextureMatID matid =
(
result = 0
if matid == -1 then
(
result = 0
)
else
(
result = matid
)
result
)
fn GetTextureFaces obj matid faces =
(
result = 0
if matid == -1 then
(
result = obj.mesh.numFaces
)
else
(
result = faces
)
result
)
fn RsGetTexMapsInfoFromMaterialSceneStats objStruct allTexNames allTexStructs mat: matid:-1 faces:0 faceidlist: getFileData:true =
(
local obj = objStruct.obj
if (mat == unsupplied) do (mat = obj.material)
if (obj != undefined) and (mat != undefined) do
(
case classOf mat of
(
MultiMaterial:
(
local matlist = #()
local faceCountList = #()
local faceIDLists = #()
--[R.G] Here we are passing a mesh copy of the obj. Important because we end up with a editable_mesh bit array.
RsMatGetMapIdsUsedOnObjectWithCount (copy obj.mesh) matlist mat:mat polycount:faceCountList faceidlists:faceIDLists
for i = 1 to matlist.count do
(
local matidx = finditem mat.materialIDList matlist[i]
if matidx != 0 then
(
RsGetTexMapsInfoFromMaterialSceneStats objStruct allTexNames allTexStructs mat:mat.materiallist[matidx] matId:matlist[i] faces:faceCountList[i] faceidlist:(faceIDLists[i] as bitArray) getFileData:getFileData
)
)
)
XRef_Material:
(
RsGetTexMapsInfoFromMaterialSceneStats objStruct allTexNames allTexStructs mat:(mat.getsrcitem()) faceidlist:faceidlist getFileData:getFileData
)
default:
(
append objStruct.materials mat
append objStruct.matIds matId
local numTexMap = getNumSubTexmaps mat
for i = 1 to numTexMap do
(
local subTexMap = getSubTexmap mat i
if classof subTexMap == DistanceAlphaMap then
(
--print "validation check 8"
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if classof subTexMap == Bitmaptexture then
(
local TexFilename = SubTexMap.Filename
if (TexFilename != undefined) and (TexFilename != "") do
(
local texMapName = toLower (getFilenameFile TexFilename)
local texMatId = GetTextureMatID matId
local useTexStruct
local idxTex = finditem allTexNames texMapName
local addForObj = true
if idxTex == 0 then
(
useTexStruct = RsSceneStats_objTexInfo()
useTexStruct.name = texMapName
useTexStruct.texMap = subTexMap
if getFileData do
(
useTexStruct.width = GetTextureWidth subTexMap
useTexStruct.height = GetTextureHeight subTexMap
useTexStruct.Size = GetTextureSize subTexMap
)
append allTexNames texMapName
append allTexStructs useTexStruct
idxTex = allTexStructs.count
)
else
(
useTexStruct = allTexStructs[idxTex]
local objTexIdx = findItem useTexStruct.objStructs useTexStruct
-- Has this texturemap been applied to this object already, from another material?
if (objTexIdx != 0) do
(
-- Don't process further if this texturemap has already been found on this materialId:
local objTexMatIdx = findItem useTexStruct.matIds texMatId
if (objTexMatIdx != 0) do
(
addForObj = false
)
)
)
-- Only add new matId data:
if addForObj do
(
useTexStruct.faces += (GetTextureFaces obj matid faces)
append useTexStruct.objStructs objStruct
append useTexStruct.objFaces faceIdList
append useTexStruct.matIds texMatId
appendIfUnique (objStruct.GetTexStructs()) useTexStruct
)
)
)
)
)
)
)
)
--
-- fn: sceneStatsGetFilename
-- desc:Returns the filename with either .zip or not depending on
-- if it finds the file with .zip at the end
--
fn sceneStatsGetFilename basename ext =
(
f = basename + ext
if (not doesFileExist f ) do
(
f = basename + ( substring ext 1 (ext.count - 4) )
)
f
)
fn UpdateObjectInfo objlist includeRefs:chkIncludeRefs.checked includeStnd:chkIncludeStnd.checked includeFragChilds:chkFragmentChildren.checked getFileData:chkFileData.checked updateProgress:true =
(
barProgress.value = 0.0
local idxTXD = getattrindex "Gta Object" "TXD"
local idxLODDistance = getattrindex "Gta Object" "LOD distance"
local objList = for obj in objlist where (not isKindOf obj Container) and (getattrclass obj == "Gta Object") collect obj
local objNameList = #()
local objStructList = #()
local sceneFilename = getFilenameFile maxfilename
-- Collect initial filtered object-data:
for obj in objList do
(
local objStruct = RsSceneStats_objInfo obj:obj instances:#(obj) objName:obj.name filename:sceneFilename
local objParent = obj.parent
-- Skip/include Frag Children?
if (not includeFragChilds) and (not ((objParent == undefined) or (isKindOf objParent Helper))) do continue
local isNew = true
local sourceObj
case of
(
-- Ref objects:
((objStruct.isRef = isRsRef obj includeDelegates:true) or (objStruct.isIRef = isRsInternalRef obj)):
(
if includeRefs do
(
local objName = obj.objectname
local nameIdx = finditem objNameList (toLower objName)
-- Refs don't have collision:
objStruct.collFaces = "NA"
if (nameIdx == 0) then
(
-- Add new struct for ref:
objStruct.objName = objName
append objStructList objStruct
append objNameList (toLower objName)
case of
(
(objStruct.isRef):
(
objStruct.showName = objName + " {Ref}"
objStruct.refDef = RsRefFuncs.getRefDefByName objName
if getFileData do
(
objStruct.filename = getFilenameFile obj.filename
)
)
(objStruct.isIRef):
(
objStruct.showName = objName + " {IRef}"
sourceObj = obj.getSourceObj()
)
)
)
else
(
-- Add to ref instances:
objStruct = objStructList[nameIdx]
append objStruct.instances obj
isNew = false
)
)
)
-- Standard objects:
((isKindOf obj Editable_Mesh) or (isKindOf obj Editable_Poly)):
(
if includeStnd do
(
sourceObj = obj
append objStructList objStruct
append objNameList undefined
objStruct.showName = gRsMapExportFragments.getNonFragmentName objStruct.objName
objStruct.isLod = RsIsAnyLOD obj
)
)
)
-- Process model found in scene:
if (sourceObj != undefined) do
(
-- Get "LOD Dist"
objStruct.lodDistance = getattr obj idxLODDistance
-- Get txd for standard/iref objects:
objStruct.txd = toUpper (getattr sourceObj idxTXD)
-- Set obj filename to container's, if used:
local objCont = Containers.IsInContainer sourceObj
if (objCont != undefined) do
(
--format "Object Is In Container: %\n" objCont.name
objStruct.filename = RsContFuncs.getContFilename objCont
if (maxfilenameForObj != undefined) then
(
objStruct.filename = getFilenameFile objStruct.filename
)
else
(
-- Need to make a guess that the filename will be the container name
objStruct.filename = objCont.Name
if (objStruct.filename == "") do
(
format "Unable to find filename for object in container\n"
)
)
)
)
)
-- Set values for RsRefs:
(
local refStructs = for item in objStructList where (item.refDef != undefined) collect item
-- Get indexes for prop-dir maxfiles:
local propFileNums = #{}
propFileNums.count = RSrefData.maxFiles.count
for n = 1 to RSrefData.maxFiles.count do
(
propFileNums[n] = matchPattern RSrefData.maxFiles[n] pattern:"*props*"
)
-- Make sure that relevant RsRef txd/lod-data is loaded:
local refDefs = for item in refStructs collect item.refDef
RsRefFuncs.loadTxds refDefs
RsRefFuncs.loadLodDistances refDefs
for item in refStructs do
(
local refDef = item.refDef
item.txd = toUpper refDef.txd
item.isInterior = (refDef.objType == #milo)
item.isProp = propFileNums[refDef.maxFileNum]
item.lodDistance = refDef.lodDistance
)
)
-- Set values for all items:
for objStruct in objStructList do
(
local obj = objStruct.obj
-- Set number of faces:
if isProperty obj "mesh" do
(
local useMesh = copy obj.mesh
objStruct.faces = useMesh.numFaces
)
-- Collision faces:
if (isKindOf objStruct.collFaces number) do
(
for subobj in obj.children where isKindOf subObj Col_Mesh do
(
objStruct.collFaces += getCollPolyCount subobj
)
)
-- volume
local dimensions = obj.max - obj.min
objStruct.volume = dimensions.x * dimensions.y * dimensions.z
-- face density
if (objStruct.faces != 0) do
(
objStruct.faceDensity = (objStruct.faces as float) / objStruct.volume
)
if getFileData and (isKindOf objStruct.filename string) do
(
local baseFilename = RsConfigGetCacheDir() + "maps/" + objStruct.filename + "/" + objStruct.objName
local checkExts = #(".idr.zip", ".ift.zip")
local getModelSize = 0
for ext in checkExts while (getModelSize == 0) do
(
getModelSize = getFileSize (sceneStatsGetFilename basefilename ext)
)
if (getModelSize != 0) do
(
getModelSize /= 1024
objStruct.modelSize = getModelSize as integer
objStruct.memDensity = (getModelSize as float) / objStruct.volume
)
)
)
local allTexNames = #()
local allTexStructs = #()
-- Per-obj texture-list bits:
pushPrompt "Getting object textures..."
--local timeStart = timeStamp()
for objNum = 1 to objStructList.count while not keyboard.escPressed do
(
if updateProgress then barProgress.value = 100.0 * objNum / objStructList.count
local objStruct = objStructList[objNum]
RsGetTexMapsInfoFromMaterialSceneStats objStruct allTexNames allTexStructs getFileData:getFileData
-- Get shader-count:
objStruct.shaders = objStruct.materials.count
)
--format "Time taken: %s\n" ((timeStamp() - timeStart) / 1000.0)
popPrompt()
barProgress.value = 100.0
if keyboard.escPressed do return #()
-- Clear .materials values, as they're no longer required:
objStructList.materials = undefined
-- Get TXD-data:
(
local txdFilenames = #()
local txdItemLists = #()
local mapCacheDir = RsConfigGetCacheDir() + "maps/"
-- Collect items per Txd filename:
for item in objStructList where (item.txd != undefined) do
(
local txdBaseFilename = mapCacheDir + item.filename + "/" + item.txd
local txdFileIdx = finditem txdFilenames txdBaseFilename
if (txdFileIdx == 0) do
(
append txdFilenames txdBaseFilename
append txdItemLists #()
txdFileIdx = txdFilenames.count
)
append txdItemLists[txdFileIdx] item
)
for n = 1 to txdFilenames.count do
(
local txdItems = txdItemLists[n]
local txdBaseFilename = txdFilenames[n]
local txdTexNames = #()
for item in txdItems do
(
local texNames = for texItem in (item.GetTexStructs()) collect texItem.name
join txdTexNames texNames
)
txdTexNames = makeUniqueArray txdTexNames
-- Set txdTexcount for all txd-objects:
local txdTexCount = txdTexNames.count
txdItems.txdTexCount = txdTexCount
-- Set TXD % for each object:
for objStruct in txdItems do
(
objStruct.txdPercent = 0.01 * (integer (10000 * float (objStruct.GetTexStructs()).count / txdTexCount))
)
-- Set txdSize for all txd-objects:
local txdSize
if getFileData and (isKindOf txdBaseFilename string) and (txdBaseFilename != "") do
(
local txdFilename = sceneStatsGetFilename txdBaseFilename ".itd.zip"
txdSize = getFileSize txdFilename
)
if (isKindOf txdSize number) and (txdSize != 0) do
(
txdSize /= 1024
txdItems.txdSize = txdSize as integer
)
)
)
-- Final processing of list:
for objStruct in objStructList do
(
-- totalsize
if (isKindOf objStruct.modelSize number) and (isKindOf objStruct.txdSize number) do
(
objStruct.totalSize = objStruct.modelSize + objStruct.txdSize
)
)
return objStructList
)
fn showObjsInList objList =
(
dnObjectList.Rows.Clear()
dnTextureList.Rows.Clear()
for objStruct in objList do
(
local rowData = objStruct.getColVals()
local newRowNum = dnObjectList.Rows.add rowData
local newRow = dnObjectList.rows.item[newRowNum]
newRow.tag = dotNetMXSValue objStruct
objStruct.row = newRow
)
dnObjectList.AutoResizeColumns()
dnObjectList.ClearSelection()
)
fn updateObjectList selected:(rdoSelAll.state == 1) =
(
local objs = if selected then selection else objects
selObjList = UpdateObjectInfo objs
showObjsInList selObjList
)
fn UpdateSelectedTextures =
(
local selRowCount = dnObjectList.SelectedRows.Count
-- Don't Update if nothing is selected
if (selRowCount != 0) do
(
-- Disable the texture-controls, they'll be reactivated once a selection is made:
texCtrls.enabled = false
cmdSelectObj.text = "Select Object"
local selRows = dnObjectList.SelectedRows
local selObjStructs = #()
for n = 0 to (selRowCount - 1) do
(
local tag = dnObjectList.SelectedRows.item[n].tag
if (tag != undefined) do append selObjStructs tag.value
)
local objCount = selRows.Count
showTexInfoList = #()
-- Get the texturemap structs from each selected object:
for i = 0 to (objCount - 1) where (selRows.Item[i].tag != undefined) do
(
local objStruct = selRows.Item[i].tag.value
if (objStruct != undefined) then
(
for texStruct in (objStruct.GetTexStructs()) do
(
local texIdx = findItem showTexInfoList texStruct
if (texIdx == 0) do
(
append showTexInfoList texStruct
texStruct.showMatId = #()
texStruct.showObjs = #()
texIdx = showTexInfoList.count
)
local objIdx = findItem texStruct.objStructs objStruct
appendIfUnique texStruct.showMatId texStruct.matIds[objIdx]
appendIfUnique texStruct.showObjs objStruct
objStruct.commonCount = objStruct.uniqueCount = objStruct.nonUniqueCount = 0
)
)
)
local commonCount = 0
local uniqueCount = 0
local nonUniqueCount = 0
for texStruct in showTexInfoList do
(
local texTxdList = makeUniqueArray (for objStruct in texStruct.showObjs collect objStruct.txd)
texStruct.showTxdCount = texTxdList.count
texStruct.showObjCount = texStruct.showObjs.count
local instances = #()
for objStruct in texStruct.showObjs do
(
join instances objStruct.instances
)
texStruct.showInstCount = instances.count
case texStruct.showObjCount of
(
-- Texture is used on all objects:
objCount:
(
commonCount += 1
--nonUniqueCount += 1
for objStruct in texStruct.showObjs do
(
objStruct.commonCount += 1
--objStruct.nonUniqueCount += 1
)
)
-- Texture is used on only one object:
1:
(
uniqueCount += 1
for objStruct in texStruct.showObjs do
(
objStruct.uniqueCount += 1
)
)
-- Texture is used on multiple objects:
default:
(
nonUniqueCount += 1
for objStruct in texStruct.showObjs do
(
objStruct.nonUniqueCount += 1
)
)
)
texStruct.showMatId = if (texStruct.showMatId.count > 1) then "Multiple" else texStruct.showMatId[1]
)
-- Write out the stats for each object selected and the common texture count.
local showText = stringStream ""
fn plural val = if (val == 1) then "" else "s"
case objCount of
(
0:
(
format "Select from Objects list to see texture-stats" objCount to:showText
)
1:
(
format "Selected object has % texture%" commonCount (plural commonCount) to:showText
)
Default:
(
format "Selected % objects have:\r\n" objCount to:showText
format " % texture% on only one object\r\n" uniqueCount (plural uniqueCount) to:showText
format " % texture% on multiple objects\r\n" nonUniqueCount (plural nonUniqueCount) to:showText
format " % texture% in common (on all objects)\r\n\r\n" commonCount (plural commonCount) to:showText
for item in selObjStructs do
(
format "%: " item.showName to:showText
if (item.uniqueCount != 0) do
(
format "% unique" item.uniqueCount to:showText
)
if (item.nonUniqueCount != 0) do
(
format "% non-unique " item.nonUniqueCount to:showText
)
if (item.commonCount != 0) do
(
format "% common " item.commonCount to:showText
)
format "\r\n" to:showText
)
)
)
dnCountText.Text = showText as string
dnCountText.SelectionStart = 0
dnCountText.SelectionLength = 0
-- Remove/add the texture-list:
dnTextureList.Rows.Clear()
for texInfo in showTexInfoList do
(
local rowData = texInfo.getColVals()
local newRowNum = dnTextureList.Rows.add rowData
local newRow = dnTextureList.rows.item[newRowNum]
newRow.tag = dotNetMXSValue texInfo
texInfo.row = newRow
)
dnTextureList.AutoResizeColumns()
dnTextureList.ClearSelection()
)
)
-- Shows copies of meshes arranged in a line, plus objects showing counts (if not undefined)
fn showArrangedObjs items counts:#() =
(
-- Delete existing temp-objects:
delete $TmpStats*
-- Find scene-objects' bounds:
local maxSize = [0,0,0]
if (objects.count != 0) then
(
local objMaxes = for obj in geometry collect obj.max
for n = 1 to 3 do
(
local axisVals = for item in objMaxes collect item[n]
maxSize[n] = amax axisVals
)
)
local idxDontExport = GetAttrIndex "Gta Object" "Dont Export"
local objPadding = 1.0
local counterSize = 0.1
local placePoint = [maxSize.x + 10.0, maxSize.y + 10.0, 0]
local newObjs = #()
for itemNum = 1 to items.count do
(
local item = items[itemNum]
local obj = item.obj
if not isProperty obj #mesh do continue
local objCount = counts[itemNum]
-- Create copy-object, set as non-export:
local copyObj = editable_mesh name:("TmpStatsMesh: " + item.objName) wireColor:obj.wireColor
setAttr copyObj idxDontExport true
copyObj.mesh = obj.mesh
copyObj.material = obj.material
update copyObj
local objMin = copyObj.min
local objMax = copyObj.max
-- Move object:
copyObj.pos = placePoint - objMin
local objSize = objMax - objMin
local objCentre = copyObj.center
local baseRect = rectangle name:("TmpStats_Base: " + item.objName) wireColor:green width:objSize.x length:objSize.y pos:[objCentre.x, objCentre.y, 0]
local groupObjs = #(copyObj, baseRect)
if (objCount != undefined) do
(
-- Add number-column object:
local segs = if (isKindOf objCount integer) then objCount else 1
local counterObj = prism pos:(copyObj.pos + objMin) name:("TmpStats_Count: " + item.objName) wireColor:green side1Length:counterSize side2Length:counterSize side3Length:counterSize height:(objCount * counterSize) heightsegs:segs
append groupObjs counterObj
-- Add value-string:
local textObj = text pos:(copyObj.pos + objMin) name:("TmpStats_Text: " + item.objName) wireColor:green size:(counterSize * 3) text:(objCount as string)
textObj.pos.y -= (textObj.max.y - textObj.min.y + counterSize)
append groupObjs textObj
)
local newGrp = group groupObjs name:("TmpStats: " + item.objName)
append newObjs newGrp
-- Set next place-point:
placePoint.x += (objSize.x + objPadding)
)
-- Zoom extents to new objects:
if (newObjs.count != 0) do
(
local oldSel = selection as array
select newObjs
max zoomext sel
clearSelection()
select oldSel
)
)
--////////////////////////////////////////////////////////////
-- events
--////////////////////////////////////////////////////////////
on cmdSaveReport pressed do
(
barProgress.value = 0.0
saveFilename = getsavefilename caption:"Save report to:" filename:"out.csv" types:"Comma Seperated (*.csv)|*.csv"
if saveFilename == undefined then return 0
local saveFile = openfile saveFilename mode:"wb"
if saveFile == undefined then return 0
local allobj = #()
RsGetMapObjectsWithXrefs rootnode.children allobj
for obj in rootnode.children where isKindOf obj container do
(
RsGetMapObjectsWithXrefs obj.children allObj
)
-- create blocks
BlockNames = #()
BlockSelSets = #()
BlockAreas = #()
BlockObjects = #()
idxBlockID = getattrindex "Gta Object" "BlockID"
idxBlockIDMilo = getattrindex "Gta MILOTri" "BlockID"
for obj in allobj do
(
local blockName = case getattrclass obj of
(
"Gta Object":(toLower (getattr obj idxBlockID))
"Gta MILOTri":(toLower (getattr obj idxBlockIDMilo))
default:""
)
if (blockName == "") do (blockName = "(unassigned)")
local blockIdx = finditem BlockNames blockName
if blockIdx == 0 then
(
local objFoundList = getNodeByName blockName exact:true all:true
local objValid = #()
areaValue = 0.0
for objFound in objFoundList do
(
if isKindOf objFound GtaBlock do
(
append objValid objFound
areaValue = objFound.plane.length * objFound.plane.width
)
)
append BlockNames blockName
append BlockSelSets #()
append BlockAreas areaValue
append BlockObjects objValid
blockIdx = BlockNames.count
)
append BlockSelSets[blockIdx] obj
)
local blockTotalFaces = #()
local blockTotalCollFaces = #()
local blockTotalModelSize = #()
local blockTotalTXDSize = #()
local blockTotalTXDCount = #()
local blockTotalLodSize = #()
local blockTotalInteriorSize = #()
local blockTotalPropSize = #()
local blockTotalRefSize = #()
for i = 1 to BlockNames.count do
(
local objList = UpdateObjectInfo BlockSelSets[i] includeRefs:true includeStnd:true updateProgress:false
local blockName = BlockNames[i]
barProgress.value = ((i as float) / BlockNames.count) * 100.0
format "Block: %\n\n" blockName to:saveFile
format "Name,Textures,Faces,Collision Faces,LOD Distance,Model Size (k),TXD Name,TXD Size (k),TXD Textures,Shaders,Volume (m^3),Face Density (n/m^3),Mem Density (k/m^3),TXD \%,Is Lod,Is Ref,Is Prop,Is Interior\n" to:saveFile
local currTotalFaces = 0
local currTotalCollFaces = 0
local currTotalModelSize = 0
local currTotalTXDSize = 0
local currTotalLodSize = 0
local currTotalInteriorSize = 0
local currTotalPropSize = 0
local currTotalRefSize = 0
local blockTxds = #()
for obj in objList do
(
local thisTotalFaces = obj.faces
local thisTotalCollFaces = obj.collFaces
local thisTotalModelSize = obj.modelSize
local thisTotalTXDSize = obj.txdsize
if (isKindOf thisTotalFaces number) do currTotalFaces += thisTotalFaces
if (isKindOf thisTotalCollFaces number) do currTotalCollFaces += thisTotalCollFaces
if (isKindOf thisTotalModelSize number) then
(
currTotalModelSize += thisTotalModelSize
if obj.islod do currTotalLodSize += thisTotalModelSize
if obj.isRef do currTotalRefSize += thisTotalModelSize
if obj.isprop do currTotalPropSize += thisTotalModelSize
if obj.isInterior do currTotalInteriorSize += thisTotalModelSize
)
if finditem blockTxds obj.txd == 0 do
(
append blockTxds obj.txd
if (isKindOf thisTotalTXDSize number) do
(
currTotalTXDSize += thisTotalTXDSize
if obj.islod do currTotalLodSize += thisTotalTXDSize
if obj.isRef do currTotalRefSize += thisTotalTXDSize
if obj.isprop do currTotalPropSize += thisTotalTXDSize
if obj.isInterior do currTotalInteriorSize += thisTotalTXDSize
)
)
local valList = #(obj.showName, (obj.GetTexStructs()).count, obj.faces, obj.collFaces, obj.lodDistance, obj.modelSize, obj.txd, obj.txdsize, obj.txdTexCount,
obj.shaders, obj.volume, obj.faceDensity, obj.memDensity, obj.txdPercent, obj.isLod, obj.isRef, obj.isProp, obj.isInterior)
for n = 1 to valList.count do
(
format "%%" valList[n] (if (n == valList.count) then "\n" else ",") to:saveFile
)
)
append blockTotalFaces currTotalFaces
append blockTotalCollFaces currTotalCollFaces
append blockTotalModelSize currTotalModelSize
append blockTotalTXDSize currTotalTXDSize
append blockTotalLodSize currTotalLodSize
append blockTotalRefSize currTotalRefSize
append blockTotalPropSize currTotalPropSize
append blockTotalInteriorSize currTotalInteriorSize
append blockTotalTXDCount blockTxds.count
format ("\n\n") to:saveFile
)
format ("Block Summary\n\n") to:saveFile
format ("Name,Object Count,TXD Count,Total Face Count,Total Collision Face Count,Total Model Size (k),Total TXD Size (k),Total (k),Lod Size (k),Ref Size (k),Prop Size (k),Interior Size (k),Volume (m^2),Faces/m^2,Coll Faces/m^2,Memory/m^2\n") to:saveFile
local totalObjectCount = 0
local totalTXDCount = 0
local totalFaceCount = 0
local totalCollFaceCount = 0
local totalModelSize = 0
local totalTXDSize = 0
local totalVolume = 0
local totalLodSize = 0
local totalRefSize = 0
local totalPropSize = 0
local totalInteriorSize = 0
for i = 1 to BlockNames.count do
(
local hasArea = (BlockAreas[i] != -1.0)
if hasArea do
(
totalObjectCount += BlockSelSets[i].count
totalTXDCount += blockTotalTXDCount[i]
totalFaceCount += blockTotalFaces[i]
totalCollFaceCount += blockTotalCollFaces[i]
totalModelSize += blockTotalModelSize[i]
totalTXDSize += blockTotalTXDSize[i]
totalVolume += BlockAreas[i]
totalLodSize += blockTotalLodSize[i]
totalRefSize += blockTotalRefSize[i]
totalPropSize += blockTotalPropSize[i]
totalInteriorSize += blockTotalInteriorSize[i]
)
local valList = #(BlockNames[i], BlockSelSets[i].count, blockTotalTXDCount[i], blockTotalFaces[i], blockTotalCollFaces[i], blockTotalModelSize[i], blockTotalTXDSize[i],
(blockTotalTXDSize[i] + blockTotalModelSize[i]), blockTotalLodSize[i], blockTotalRefSize[i], blockTotalPropSize[i], blockTotalInteriorSize[i], BlockAreas[i])
if hasArea then
(
join valList #(float blockTotalFaces[i] / BlockAreas[i], float blockTotalCollFaces[i] / BlockAreas[i], float (blockTotalTXDSize[i] + blockTotalModelSize[i]) / BlockAreas[i])
)
else
(
join valList #(0,0,0)
)
local valList = #()
for n = 1 to valList.count do
(
format "%%" valList[n] (if (n == valList.count) then "\n" else ",") to:saveFile
)
)
local valList = #("TOTAL (without unasssigned)", totalObjectCount, totalTXDCount, totalFaceCount, totalCollFaceCount, totalModelSize, totalTXDSize, (totalModelSize + totalTXDSize), totalLodSize,
totalRefSize, totalPropSize, totalInteriorSize, totalVolume, float totalFaceCount / totalVolume, float totalCollFaceCount / totalVolume, float (totalModelSize + totalTXDSize) / totalVolume)
for n = 1 to valList.count do
(
format "%%" valList[n] (if (n == valList.count) then "\n" else ",") to:saveFile
)
close saveFile
mapName = getFilenameFile maxfilename
RsCopyFilename = RsConfigGetCacheDir() + "mapstats_details/" + mapName + ".csv"
RsMakeSurePathExists RsCopyFilename
copyfile saveFilename RsCopyFilename
RsTotalFilename = RsConfigGetCacheDir() + "mapstats/" + mapName + ".csv"
saveFile = openfile RsTotalFilename mode:"w"
if saveFile != undefined then
(
format "Name,Object Count,TXD Count,Total Face Count,Total Collision Face Count,Total Model Size (k),Total TXD Size (k),Total (k),Lod Size (k),Ref Size (k),Prop Size (k),Interior Size (k),Volume (m^2),Faces/m^2,Coll Faces/m^2,Memory/m^2\n" to:saveFile
for i = 1 to BlockNames.count do
(
local valList = #(BlockNames[i], BlockSelSets[i].count, blockTotalTXDCount[i], blockTotalFaces[i], blockTotalCollFaces[i], blockTotalModelSize[i], blockTotalTXDSize[i],
(blockTotalTXDSize[i] + blockTotalModelSize[i]), blockTotalLodSize[i], blockTotalRefSize[i], blockTotalPropSize[i], blockTotalInteriorSize[i], BlockAreas[i])
if (BlockAreas[i] != -1.0) then
(
join valList #(float blockTotalFaces[i] / BlockAreas[i], float blockTotalCollFaces[i] / BlockAreas[i], float (blockTotalTXDSize[i] + blockTotalModelSize[i]) / BlockAreas[i])
)
else
(
join valList #(0,0,0)
)
local valList = #()
for n = 1 to valList.count do
(
format "%%" valList[n] (if (n == valList.count) then "\n" else ",") to:saveFile
)
)
close saveFile
)
RsTotalFilename = RsConfigGetCacheDir() + "mapstats/blockmap/" + mapName + ".csv"
RsMakeSurePathExists RsTotalFilename
saveFile = openfile RsTotalFilename mode:"w"
if (saveFile != undefined) do
(
format ("VER2\n") to:saveFile
for i = 1 to BlockNames.count do
(
if BlockNames[i] == "(unassigned)" then continue
local valList = #(BlockNames[i],BlockObjects[i].count)
for blockObj in BlockObjects[i] do
(
join valList #(blockObj.pos.x, blockObj.pos.y, (blockObj.rotation as eulerangles).z, blockObj.plane.length, blockObj.plane.width)
)
join valList #(BlockNames[i], BlockSelSets[i].count, blockTotalTXDCount[i], blockTotalFaces[i], blockTotalCollFaces[i], blockTotalModelSize[i], blockTotalTXDSize[i],
(blockTotalTXDSize[i] + blockTotalModelSize[i]), blockTotalLodSize[i], blockTotalRefSize[i], blockTotalPropSize[i], blockTotalInteriorSize[i], BlockAreas[i])
if (BlockAreas[i] != -1.0) then
(
join valList #(float blockTotalFaces[i] / BlockAreas[i], float blockTotalCollFaces[i] / BlockAreas[i], float (blockTotalTXDSize[i] + blockTotalModelSize[i]) / BlockAreas[i])
)
else
(
join valList #(0,0,0)
)
local valList = #()
for n = 1 to valList.count do
(
format "%%" valList[n] (if (n == valList.count) then "\n" else ",") to:saveFile
)
)
close saveFile
)
format "Saved to: %\n" saveFilename
messageBox ("Report saved to:\n" + saveFilename) title:"Scene-report save completed"
)
on cmdSaveCurrent pressed do
(
saveFilename = getsavefilename caption:"Save report to:" filename:"out.csv" types:"Comma Seperated (*.csv)|*.csv"
if saveFilename == undefined then return 0
saveFile = openfile saveFilename mode:"wb"
if saveFile == undefined then return 0
local colNames = RsSceneStats_objInfo.getColNames()
local colCount = colNames.count
for n = 1 to colCount do
(
format "%%" colNames[n] (if (n == colCount) then "\n" else ",") to:saveFile
)
for i = 0 to (dnObjectList.Rows.Count - 1) do
(
local objStruct = dnObjectList.Rows.Item[i].tag.value
local rowVals = for item in objStruct.getColVals() collect
(
if (item == undefined) then "NA" else (item as string)
)
for n = 1 to colCount do
(
format "%%" (rowVals[n] as string) (if (n == colCount) then "\n" else ",") to:saveFile
)
)
close saveFile
format "Saved to: %\n" saveFilename
messageBox ("List saved to:\n" + saveFilename) title:"List save completed"
)
on cmdUpdate pressed do
(
updateObjectList()
)
on cmdRefresh pressed do
(
--Record our selected rows indexes
SelectedRowIndexList = #()
for RowIndex = 1 to dnObjectList.SelectedRows.Count do
(
SelectedRow = dnObjectList.SelectedRows.Item ( RowIndex - 1 )
Append SelectedRowIndexList SelectedRow.Index
)
--Collect previous objects used
objs = for selObj in selObjList where isValidNode selObj.Obj collect selObj.Obj
--Push the selection back through the system
selObjList = UpdateObjectInfo objs
showObjsInList selObjList
--Reselect the same rows
for SelectedRowIndex in SelectedRowIndexList do
(
try
(
( dnObjectList.Rows.Item SelectedRowIndex ).Selected = true
) catch ()
)
--Update textures
UpdateSelectedTextures()
)
on dnObjectList SelectionChanged args do
(
dnTextureList.ClearSelection()
UpdateSelectedTextures()
)
on dnTextureList SelectionChanged args do
(
lstObjectNames.Items = #()
cmdSelectObj.text = "Select Object"
local selRows = dnTextureList.SelectedRows
local selTags = for n = 0 to (selRows.count - 1) collect selRows.Item[n].tag
local selTexInfos = for tag in selTags where (tag != undefined) collect tag.value
-- Enable/disable texture-controls:
texCtrls.enabled = (selTexInfos.count != 0)
if (selTexInfos.count == 0) do
(
bmpTex.bitmap = bitmap 200 200
return 0
)
local texInfo = selTexInfos[1]
case of
(
(texInfo.Width == texInfo.Height):
(
img = bitmap 200 200
rm = rendermap texInfo.texmap into:img size:[200,200]
bmpTex.bitmap = img
close rm
)
(texInfo.Height > texInfo.Width):
(
height = texInfo.Height as float
heightPercentage = (height / 200.0) as float
newWidth = 200
if heightPercentage != 0 then
(
newWidth = (texInfo.Width / heightPercentage) as float
)
img = bitmap newWidth 200
rm = rendermap texInfo.texmap into:img size:[newWidth,200]
bmpTex.bitmap = img
close rm
)
default:
(
width = texInfo.Width as float
widthPercentage = (width / 200.0) as float
newHeight = 200
if widthPercentage != 0 then
(
newHeight = (texInfo.Height /widthPercentage) as float
)
img = bitmap 200 newHeight
rm = rendermap texInfo.texmap into:img size:[200,newHeight]
bmpTex.bitmap = img
close rm
)
)
local objList = #()
for item in selTexInfos do (join objList item.objStructs)
objList = makeUniqueArray (for item in objList where not item.isRef collect (item.showName as string))
-- Add instances-count to Select Objects button:
local instances = #()
for texStruct in selTexInfos do (for objStruct in texStruct.objStructs where objStruct.row.selected do (join instances objStruct.instances))
instances = makeUniqueArray instances
if (instances.count > 1) do (cmdSelectObj.text = "Select objects (" + (instances.count as string) + ")")
-- Disable face-select controls if list is empty:
if (objList.count == 0) do
(
cmdSelectFaces.enabled = false
lstObjectNames.enabled = false
)
lstObjectNames.items = objList
)
-- Select object-instances on double-clicking a row:
on dnObjectList DoubleClick sender arg do
(
local clickItem = sender.hitTest arg.x arg.y
local rowIdx = clickItem.RowIndex
if (rowIdx != -1) do
(
local objData = dnObjectList.Rows.Item[rowIdx].tag.value
local selObjs = for obj in objData.instances where isValidNode obj collect obj
if selObjs.count != 0 do
(
select selObjs
max zoomext sel
)
)
)
-- Called when dnObjectList is clicked:
on dnObjectList CellMouseUp sender arg do
(
local rowIdx = arg.rowIndex
if (rowIdx < 0) do return false
local clickRow = sender.Rows.Item[rowIdx]
-- If (right)clicked cell is unselected, replace selection with it:
if not clickRow.Selected do
(
sender.ClearSelection()
clickRow.Selected = True
)
local rightClick = arg.button.equals arg.button.right
if rightClick do
(
-- Rightclick menu:
rcmenu RSmenu_SceneStatsObjList
(
local selRows = #()
menuItem itmSelObjs "Select Objects"
menuItem itmArrangeObjs "Visual Arrangement"
on itmSelObjs picked do
(
local selObjs = #()
for row in selRows do
(
join selObjs row.tag.value.instances
)
selObjs = for obj in selObjs where isValidNode obj collect obj
if (selObjs.count != 0) do
(
select selObjs
max zoomext sel
)
)
on itmArrangeObjs picked do
(
local counts = #()
local sortedColumn = RsSceneStatsRoll.dnObjectList.SortedColumn
if (sortedColumn != undefined) do
(
local colIdx = sortedColumn.Index
counts = for row in selRows collect row.Cells.Item[colIdx].value
for n = 1 to counts.count where (not isKindOf counts[n] number) do (counts[n] = undefined)
)
local objStructs = for row in selRows collect row.Tag.Value
showArrangedObjs objStructs counts:counts
)
on RSmenu_SceneStatsObjList open do
(
-- Get row-tags, in their current order:
local rows = RsSceneStatsRoll.dnObjectList.Rows
for n = 0 to (rows.count - 1) do
(
local row = rows.Item[n]
if row.selected do
(
append selRows row
)
)
)
)
popUpMenu RSmenu_SceneStatsObjList
)
)
fn getSelTexFiles =
(
local selCount = dnTextureList.SelectedRows.count
for n = 0 to (selCount - 1) collect
(
local selRow = dnTextureList.SelectedRows.Item[n]
local selTexStruct = selRow.tag.value
selTexStruct.texMap.filename
)
)
on cmdEdit pressed do
(
local pshop = CreateOLEObject "Photoshop.Application"
pshop.Visible = False
pshop.Visible = True
for selTexFilename in getSelTexFiles() where (doesFileExist selTexFilename) do
(
format "Opening in Photoshop: %\n" selTexFilename
pshop.open selTexFilename
)
releaseOLEObject pshop
)
on cmdPerforce pressed do
(
local selTexFiles = getSelTexFiles()
gRsPerforce.add_or_edit selTexFiles
)
on btnRefreshTx pressed do
(
--object list index
local objIdx = (dnObjectList.SelectedRows.Item[0]).index
--get the selected texture index from the dnTextureList
local txIdx = (dnTextureList.SelectedRows.Item[0]).index
--dnObjectList.
)
fn selectObjs selName: =
(
local doSelFaces = (selName != unsupplied)
clearSelection()
subobjectlevel = 0
if (dnTextureList.SelectedRows.Count < 1) do (return 0)
if (selName == undefined) do (return 0)
local keepLooking = true
local objs = #()
local faceSel = #{}
local selItems = dnTextureList.SelectedRows
local selTexInfos = for n = 0 to (selItems.count - 1) collect selItems.Item[n].tag.value
for texInfo in selTexInfos do
(
for n = 1 to texInfo.objStructs.count
where texInfo.objStructs[n].row.selected and ((not doSelFaces) or (matchPattern texInfo.objStructs[n].showName pattern:selName)) do
(
local selObj = texInfo.objStructs[n].obj
join objs texInfo.objStructs[n].instances
if doSelFaces do
(
faceSel += texInfo.objFaces[n]
)
)
)
objs = makeUniqueArray objs
if (objs.count == 0) do (return 0)
select objs
if doSelFaces do
(
setCommandPanelTaskMode(#modify)
local obj = objs[1]
if (obj.modifiers.count != 0) then
(
local plural = if (obj.modifiers.count == 1) then "" else "s"
messageBox ("Unable to select faces: object has modifier" + plural + " applied") title:("Error: Modifier" + plural + " on object")
)
else
(
--[R.G] Altered this logic so the selection of faces is always done on
-- an editable_mesh level rather than editable_poly.
-- This makes sense because we collect the face bit array while in mesh form earlier in the script.
if (isKindOf obj Editable_Poly) then
(
ConvertTo obj Editable_Mesh
setFaceSelection obj faceSel
ConvertTo obj Editable_Poly
subobjectlevel = 4
)
if (isKindOf obj Editable_Mesh) then
(
setFaceSelection obj faceSel
subobjectlevel = 3
)
)
)
max zoomExt sel
)
on cmdSelectObj pressed do
(
selectObjs()
)
on cmdSelectFaces pressed do
(
selectObjs selName:lstObjectNames.selected
)
on dnObjectList MouseUp Button Shift x y do
(
--UpdateSelectedTextures()
)
on cmdOK pressed do (
DestroyDialog RsSceneStatsRoll
)
fn arrangeCtrls size:[RsSceneStatsRoll.width, RsSceneStatsRoll.height] =
(
dnObjectList.height = (size.y - 100) / 2
dnObjectList.width = size.x - 24
lblTextures.pos = [lblTextures.pos[1], dnObjectList.pos[2] + dnObjectList.height + 10]
dnTextureList.pos = [dnTextureList.pos.x, lblTextures.pos.y + 20]
dnTextureList.width = size.x - 434
dnTextureList.height = size.y - dnTextureList.pos.y - 12
bmpTex.pos = dnTextureList.pos + [dnTextureList.width + 5, 0]
cmdSelectFaces.pos = bmpTex.pos + [bmpTex.width + 4, 0]
lstObjectNames.pos = cmdSelectFaces.pos + [0, 22]
cmdSelectObj.pos = cmdSelectFaces.pos + [0, 50]
cmdEdit.pos = cmdSelectObj.pos + [0, 24]
cmdPerforce.pos = cmdEdit.pos + [0, 24]
btnRefreshTx.pos = cmdPerforce.pos + [0, 24]
dnCountText.pos = bmpTex.pos + [0, bmpTex.height + 4]
dnCountText.Height = size.y - dnCountText.pos.y - 12
dnCountText.Width = size.x - dnCountText.pos.x - 12
lnkHelp.pos.x = size.x - 40
)
fn setupCols ctrl colNames =
(
-- Add blank-named column:
append colNames ""
local colNum
for item in colNames do
(
colNum = ctrl.Columns.add item item
)
local firstCol = ctrl.Columns.item[0]
local lastCol = ctrl.Columns.item[colNum]
firstCol.width = 160
lastCol.AutoSizeMode = lastCol.AutoSizeMode.Fill
)
fn init =
(
barProgress.Style = barProgress.Style.Continuous
barProgress.ForeColor = textColour
dnObjectList.SelectionMode = dnObjectList.SelectionMode.FullRowSelect
dnObjectList.AllowUserToAddRows = false
dnObjectList.AllowUserToDeleteRows = false
dnObjectList.AllowUserToOrderColumns = true
dnObjectList.AllowUserToResizeRows = false
dnObjectList.AllowUserToResizeColumns = true
dnObjectList.AllowDrop = false
dnObjectList.MultiSelect = true
dnObjectList.ReadOnly = true
dnObjectList.dock = dnObjectList.dock.fill
dnObjectList.DefaultCellStyle.backColor = backColour
dnObjectList.DefaultCellStyle.foreColor = textColour
textFont = dnObjectList.font
dingFont = dotNetObject "System.Drawing.Font" "Webdings" textFont.size
textFontBold = dotnetobject "system.drawing.font" textFont (dotnetclass "system.drawing.fontstyle").bold
dnObjectList.EnableHeadersVisualStyles = false
dnObjectList.ColumnHeadersDefaultCellStyle.backColor = backColour
dnObjectList.ColumnHeadersDefaultCellStyle.foreColor = textColour
dnObjectList.ColumnHeadersDefaultCellStyle.font = textFontBold
setupCols dnObjectList (RsSceneStats_objInfo.getColNames())
dnTextureList.SelectionMode = dnTextureList.SelectionMode.FullRowSelect
dnTextureList.AllowUserToAddRows = false
dnTextureList.AllowUserToDeleteRows = false
dnTextureList.AllowUserToOrderColumns = true
dnTextureList.AllowUserToResizeRows = false
dnTextureList.AllowUserToResizeColumns = true
dnTextureList.AllowDrop = false
dnTextureList.MultiSelect = true
dnTextureList.ReadOnly = true
dnTextureList.dock = dnTextureList.dock.fill
dnTextureList.DefaultCellStyle.backColor = backColour
dnTextureList.DefaultCellStyle.foreColor = textColour
dnTextureList.EnableHeadersVisualStyles = false
dnTextureList.ColumnHeadersDefaultCellStyle.backColor = backColour
dnTextureList.ColumnHeadersDefaultCellStyle.foreColor = textColour
dnTextureList.ColumnHeadersDefaultCellStyle.font = textFontBold
setupCols dnTextureList (RsSceneStats_objTexInfo.getColNames())
dnCountText.readOnly = true
dnCountText.multiline = true
dnCountText.scrollbars = dnCountText.ScrollBars.vertical
dnCountText.wordWrap = false
dnCountText.backColor = backColour
dnCountText.foreColor = textColour
startSize = GetIniRolloutSize()
arrangeCtrls size:startSize
)
on chkIncludeRefs changed state do (updateObjectList())
on chkIncludeStnd changed state do (updateObjectList())
on chkFragmentChildren changed state do (updateObjectList())
on chkFileData changed state do (updateObjectList())
on rdoSelAll changed state do (updateObjectList())
on RsSceneStatsRoll open do
(
init()
updateObjectList()
UpdateSelectedTextures()
)
on RsSceneStatsRoll resized pntSize do
(
-- Save the new rollout-size:
RsSettingWrite "RsStatsRoll" "size" pntSize
arrangeCtrls size:pntSize
)
fn create retry:false =
(
destroyDialog RsSceneStatsRoll
RS_CustomDataGrid forceRecompile:retry
local rollSize = RsSceneStatsRoll.GetIniRolloutSize()
CreateDialog RsSceneStatsRoll modal:false width:rollSize.x height:rollSize.y style:#(#style_resizing, #style_titlebar, #style_border, #style_sysmenu )
)
)
(
-- Try to catch if RsCustomDataGrid fails to work:
try (RsSceneStatsRoll.create())
catch (RsSceneStatsRoll.create retry:true)
)