cleaning up blender

Recently I had to clean up a lot of my blendfiles. Especially when you append objects that share textures with your existing objects, you wind up with a lot of duplicates.

So I came up with a little script to unlink every image in the file. You can manually link the images to your textures again, and they will not get deleted next time you open your blendfile.

  1.  

bpy.data.images will store all images' names that are used in any texture in an array.
The for loop will be repeated as often as there are image names in imgs.
user_clear() is a built-in method, which will set the number of users of an image, texture, datablock etc. to 0.

Some people may ask: what if I want to keep some of my images? Of course this is a good question. You could "tag" the images you want to keep by hand, by inserting a string at the beginning, let's say "keep".
Then use an if statement, so we only delete those images whose names do not start with "keep".

  1. span style="color: #483d8b;">"keep"

 The line if name[:4] != "keep": checks the first 4 characters in a string and whether they spell "keep". [:n] extracts the first n characters of a string [n:] the last n.
!= means not equal to so if the 4 characters of the name are not "keep", the image will be unlinked.

Still we have to do stuff by hand, which is not the goal when scripting. How about we write a script that removes all images that are not used in a texture slot?

  1. span style="color: #808080; font-style: italic;"># if you want to use the method "append", you have to make sure, you're doing it with a variable that is in fact a list. = [] creates an empty array.
  2. # Stores the names of all images that actually are used in a texture slot in an array (textures)
  3. 'IMAGE':
  4. img_names.append(tex.image.name)
  5.  
  6. # The if statement will check if the image's name appears in the list. If not, it will be unlinked

Careful: all reference and background images will be removed as well.

So there you have it: a script that will unlink every image that is not used in a texture, making the cleanup so much easier.

  1. span style="color: #483d8b;">'IMAGE'

OK, that was for Blender Internal materials, since Cycles works with nodes and not texture slots, the script is a bit more complicated.

  1. span style="color: #483d8b;">'new run''No texture assigned to this node, no problem though'

So here is a little more explanation: nodes = mat.node_tree.nodes stores all nodes of the current material in a list. So the for loop will check every node whether it is a texture node or not. If it is a texture node, its image name will be stored in the array. I used try, because nam = node.image.name raised an error in some cycles of the loop. If you are not sure if all texture nodes actually contain an image, you can use the try method. If your code causes an error, Python will do whatever comes after the except, ignoring the error. In our case it will just notify us that something did not go according to plan, but the script will not be aborted.
Warning: This script will not work if there are materials present that do not have "use Nodes" enabled.