-- -- File:: rockstar/helpers/scenestats.ms -- Description:: Gta Scene Statistics -- -- Author:: Greg Smith 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) )