1
$\begingroup$

I have a scene which is taxing my computer memory such that blender is almost unusable (not even talking about render here, just UI). I know I have a few very expensive objects, but it's been a few years since I worked on this project so I have to hunt around and try to remember which ones are large. How can I quickly identify the heavy hitters, so that I can either delete or rework them and basically to make my project leaner and easier to work with? (I'll focus on render later)

I keep trying to use the status line, bottom right, but I think it shows stats for my entire project, not the selected object or object hierarchy.
enter image description here

$\endgroup$
4
  • $\begingroup$ blender.stackexchange.com/questions/218229/… $\endgroup$ Nov 29, 2021 at 21:09
  • $\begingroup$ Thx Allen, I will check that out. On another site I found this python script (or variation) that does what I need import bpy from bpy import context sumfaces = [] for o in context.scene.objects: if o.type != 'MESH': continue me = o.data verts = len(me.vertices) edges = len(me.edges) faces = len(me.polygons) sumfaces.append(faces) print("%s: verts:%d edges:%d polys %d" % (o.name, verts, edges, faces)) print("total polys %d" % sum(sumfaces)) $\endgroup$
    – Jon
    Nov 29, 2021 at 22:33
  • 1
    $\begingroup$ Jon, feel free to post as a self-answer $\endgroup$ Nov 29, 2021 at 23:17
  • 1
    $\begingroup$ Added a much better answer, a long time coming. $\endgroup$
    – Jon
    Feb 18, 2022 at 22:50

1 Answer 1

5
$\begingroup$

I've written this script that helped me a lot with my last project. As a new blender user it's too easy for me to bloat my projects w/o knowing where the bloat is. This inspector lists out my project so it is more knowable. To use this script in Blender 3.0 you will have to follow the instructions here Blender 3.0.1 How to import 'tabulate' into script to pip3 install the tabulate import.

import bpy,os
from bpy import context
from tabulate import tabulate
import operator
import sys
import numbers

import os
print("PYTHONPATH:", os.environ.get('PYTHONPATH'))
print("PATH:", os.environ.get('PATH'))

#
#  Sorts a table based on a col tuple
#
def sort_table(table, cols):
    """ sort a table by multiple columns
        table: a list of lists (or tuple of tuples) where each inner list 
               represents a row
        cols:  a list (or tuple) specifying the column numbers to sort by
               e.g. (1,0) would sort by column 1, then by column 0
    """
    for col in reversed(cols):
        table = sorted(table, key=operator.itemgetter(col))
    return table


#
#  Takes a table and for all numbers in the table
#  formats them with commas and returns a new table
#
def insertCommas(table):
    newTable = []
    for row in table:
        resultsRow = []
        for col in row:
            if isinstance( col, numbers.Number):
                newCol = '{:,}'.format(col)
            else:
                newCol = col
            resultsRow.append(newCol)
            
        newTable.append( resultsRow)
                
    return newTable
    
#
#  Prints a table and summary of all project meshes, including total and unique total (dups vs linked)
#    
iTotalVerts = 0
iTotalUniqueVerts = 0
iTotalEdges = 0
iTotalUniqueEdges = 0
iTotalFaces = 0
iTotalUniqueFaces = 0

resultsTable = []
totalObjects = 0 
totalDups = 0

# 
# First build a table of all items and their names/addresses
# so that we can understand when we have a 'linked' object
#    
name_dict = {}
address_dict = {}
for o in context.scene.objects:
    if o.type != 'MESH':
        continue
   
    name_dict[o.name] = o.data.as_pointer() 
    address_dict[o.data.as_pointer()] = o.name
       

#print("name_dict " + str(name_dict))
#print("\n")

#
#  Now build the list of objects and sizes and look up dup counts
#

for o in context.scene.objects:
    if o.type != 'MESH':
        continue
    
    name_dict[o.name] = o.data.as_pointer()
    obj_mesh = o.data
    
    resultsRow = []
    me = o.data
    verts = len(me.vertices)
    edges = len(me.edges)
    faces = len(me.polygons)
    
    iTotalVerts += verts
    iTotalEdges += edges
    iTotalFaces += faces
   
    resultsRow.append(o.name)
    resultsRow.append(verts)
    resultsRow.append(edges)
    resultsRow.append(faces)
    
    address = o.data.as_pointer()
    
    dupCount = 0     
    address = name_dict[ o.name ]
    for each in name_dict:
        #print( "Looking for address " + str(address) + " comparing with " + str(name_dict[each]))
        
        if address == name_dict[each]:
            dupCount = dupCount + 1
            
    resultsRow.append(dupCount)
    if dupCount > 1:
        resultsRow.append(str(o.data.as_pointer()))
        totalDups = totalDups + 1
    else:
        resultsRow.append("")
        iTotalUniqueVerts += verts
        iTotalUniqueEdges += edges
        iTotalUniqueFaces += faces
        
    
    resultsTable.append(resultsRow)
    totalObjects = totalObjects +1

print("address_dicts = " + str(address_dict))
sortedResultsTable = sort_table( resultsTable, (1,0))
formattedAndSortedTable = insertCommas( sortedResultsTable )

headers = ["Name", "Verts", "Edges", "Faces", "Link Count", "Linked to"] 
print(tabulate(formattedAndSortedTable, headers=headers, stralign="right"))


strTotalObjects = '{:,}'.format(totalObjects)
strTotalDups = '{:,}'.format(totalDups)
strTotalVerts = '{:,}'.format( iTotalVerts)
strTotalEdges = '{:,}'.format( iTotalEdges)
strTotalFaces = '{:,}'.format( iTotalFaces)
strTotalVertsUnique = '{:,}'.format(iTotalUniqueVerts)
strTotalEdgesUnique = '{:,}'.format(iTotalUniqueEdges)
strTotalFacesUnique = '{:,}'.format(iTotalUniqueFaces)


summaryOutput = "\nSummary: Objects: " + strTotalObjects + "/" + strTotalDups + ", Unique: " + '{:,}'.format(len(address_dict)) + ", Verts: " + strTotalVerts + "/" + strTotalVertsUnique + ", Edges: " + strTotalEdges + "/" + strTotalEdgesUnique + ", Faces: " + strTotalFaces + "/" +strTotalFacesUnique
print( summaryOutput) 
print( "\nNote: Total/Unique, Totals include all linked objects, Unique only counts unique objects")

Here is a sample of the output, nicely tabulated, a list of all Meshes and their vert/edge/face sizes as well as a 'linked' count and the memory address (for recognizing dup objects). The summary shows the totals for both all objects and just unique objects. This information makes it easy for me to find large objects and/or objects that are better served as dups. I see no way in the Blender UI to know if a particular object is a duplicate or a linked object. This gives me that visibility too! :-)

ENJOY!

enter image description here

And Updated output

--------------------------------------  -------  -------  -------  ------------  -----------
                              FogPlane        4        4        1             1
                          FogPlane.001        4        4        1             1
flying-sparrow-silhouette-25-424287647        4        4        1             1
                      lonemountain_sky        4        4        1             1
                              iceberg3        7       12        7             1
                              iceberg8        7       12        7             1
                              iceberg1        8       18       12             1
                              iceberg2        8       15        9             1
                              iceberg4        8       12        6             1
                              iceberg5        8       15        9             1
                              iceberg6        8       15        9             1
                              iceberg7        8       18       12             1
                              iceberg9        8       12        6             1
                                  rock        8       18       12             1
                             iceberg10       10       24       16             1
                         Landscape.006   10,526   20,815   10,290             1
                         Landscape.003   13,720   27,158   13,439             1
                         Landscape.004   13,720   27,158   13,439             1
                             Landscape   16,384   32,512   16,129             1
                         Landscape.001   16,384   32,512   16,129             1
                         Landscape.005   16,384   32,512   16,129             1
                         Landscape.007   16,384   32,512   16,129             1
                              IcePlane   17,689   35,112   17,424             1
                                 Ocean   17,689   35,112   17,424             1
                         Landscape.002   20,535   40,451   19,921             1
                              tree.004   31,928   55,972   24,044             1
                              tree.009   36,556   49,198   16,880             1
                         MainLandscape   42,084  125,428   83,345             1
                              tree.002   43,372   76,012   32,640             1
                            leaves.001   47,054   63,219   21,646             1
                                leaves   57,180   76,934   26,388             1
                              tree.005   66,940   90,270   31,048             1
                                  tree   71,384   95,904   32,836             1
                              tree.008  140,382  188,353   64,382             1
                              tree.001  193,644  359,728  177,948             1
                              tree.007  204,526  252,671   78,250             1
                              tree.003  330,782  413,827  126,434             1
                              tree.006  338,582  423,615  129,438             1

Summary: Objects: 38/0, Unique: 38, Verts: 1,763,933/1,763,933, Edges: 2,587,172/2,587,172, Faces: 1,001,841/1,001,841

Note: Total/Unique, Totals include all linked objects, Unique only counts unique objects
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .