70
$\begingroup$

I'm testing different materials in the same object, and finally the file has a lot of unnecessary material, is there any command that performs the cleaning of these materials automatically? in short, is it possible to make them disappear from the file?

$\endgroup$
1
68
$\begingroup$

After unlinking your materials, save your file. Then reload it with Ctrl+Shift+O.

$\endgroup$
6
  • 1
    $\begingroup$ How to unlink materials? Is it right-clicking them in the outliner and pressing "unlink" as shown in blender.stackexchange.com/questions/2362/… ? If yes, this seems to not be enough. I have lots of unused materials in my list after reloading. $\endgroup$
    – qubodup
    May 15 '18 at 10:21
  • $\begingroup$ The fastest way (for me, at least), is from the material datablock in the Properties Editor. Shift+click the X on the datablock widget and it should unlink that material from everything in your .blend file. $\endgroup$
    – Fweeb
    May 15 '18 at 11:49
  • $\begingroup$ This is not a systematic way of solving the issue. In some cases, it might not be a good idea to close and open the .blend file especially if you have lots of back-up materials and other data blocks that you keep assigning to your objects and render them because the unlinked materials will also get lost once you re-open the file. Redefining the materials and all other unlinked stuff will be computationally expensive as well. So the easiest way is to remove the materials using this Python script after you unlink the unwanted ones. $\endgroup$
    – Amir
    Oct 26 '18 at 13:48
  • 1
    $\begingroup$ @Amir, There are multiple solutions to many problems (as shown in the responses to this question) and there are certainly different situations where one solution is more beneficial than another. We simply disagree on what constitutes as "easiest". $\endgroup$
    – Fweeb
    Oct 30 '18 at 12:20
  • $\begingroup$ I found that SHIFT + CLICK on all unwated textures, then save, then reload did the trick for me. Simply unlinking always left some remains. $\endgroup$
    – Fiddy Bux
    Mar 28 '19 at 21:52
61
$\begingroup$

How about the well hidden deathray button?

Go to the outliner, choose "Orphan Data" instead of "All Scenes" and hit "Purge All".

purgatory

$\endgroup$
5
  • 6
    $\begingroup$ This is the way to go. $\endgroup$ Mar 27 '18 at 0:16
  • 1
    $\begingroup$ It amazes me how long I waited to research this. So grateful for your post, this is what I was looking for. Sometimes closing/opening a file doesn't get rid of unused data, besides, if you have other data types beside material data, this really is the way to get it purged. Thanks! $\endgroup$
    – PoxBox
    May 3 '18 at 17:11
  • $\begingroup$ This is absolutely the way to go. Although, to prevent Blender 2.8 complaining about not being able to pack certain images, I had to turn off the 'packing on save', do the death-ray purge, save & reopen, then re-enable my pack option. All in all a heck of a lot quicker than shift clicking on every image I didn't want, or that came with an untidy FBX. $\endgroup$
    – Fiddy Bux
    Oct 26 '19 at 19:22
  • $\begingroup$ This is the intended way to remove any unused objects (including materials) from blend file. $\endgroup$
    – J. Wrong
    Nov 4 '19 at 13:51
  • $\begingroup$ Life saver..... $\endgroup$
    – EPurpl3
    Feb 24 at 8:05
27
$\begingroup$

Unused Materials will disappear as soon as you save and re-open the file. These are listed with a 0 next to their name.

To make a material lose all its users (hence have 0 users and be removed the next time you open that file), press Shift and left click on the X icon next to the materials' name on Material Properties.

$\endgroup$
1
  • 11
    $\begingroup$ What a bizzare methodology ... $\endgroup$
    – Jammer
    Dec 29 '14 at 17:16
21
$\begingroup$

running this code will do it :)

import bpy

for material in bpy.data.materials:
    if not material.users:
        bpy.data.materials.remove(material)

Just to clarify what this code does:

for material in bpy.data.materials:

This line iterates over all data blocks in the "materials" data set. Blender has data sets like these for various types of objects;

bpy.data.objects
bpy.data.textures
etc...

It's worth exploring these as they are Blender's way of exposing the data you're looking for in an easy-to-get-to data structure.

if not material.users:

This line basically asks whether the "users" array in the "material" data block is not valid, aka, whether it's empty. If it is, this statement will return True; in other words this material is not being used by any other data blocks and is thus not fulfilling any purpose in the file other than take up space. This would be the same condition as would be fulfilled if you "clear users" and then save and re-open a file.

bpy.data.materials.remove(material)

removes the given data block from the materials array.

hopes this little elaboration helped :)

$\endgroup$
1
  • $\begingroup$ I think you need to edit materials.remove to bpy.data.materials.remove. The current code doesn't work unless you update to what I am pointing out. $\endgroup$ Aug 14 '16 at 14:30
7
$\begingroup$

This is also a useful button if you want to remove unassigned materials from an object:

enter image description here

But, they don't immediately disappear from the file unless you save and re-open Ctrl+Shift+O the file.

enter image description here

And, they also don't get removed from the file if there's one or more other objects using them.

$\endgroup$
1
$\begingroup$

The following solution will work too, but is more risky because it has to reload the file loosing undo-redo stack too, this is why I honestly like the Haunt_House's answer more than mine (in fact it is the one I'd use).

I use the v2.78 and I installed the Amaranth add-on from: https://pablovazquez.art/amaranth/ and the shortcut is:

Ctrl + Shift + W

that saves and reload the file at once, cleaning it from all unused data users (materials etc...). Of course it is possible to click on Save and then on Revert under the File menu. Also it is even possible to close and reopen Blender and the file you want tu purge.

Notice: This operation will delete the undo redo stack too.

Screenshots for Blender v275 and v278 (see last item of the file menu):

275 278

$\endgroup$
9
  • 1
    $\begingroup$ On Blender 2.77.1 hash 2e553f7 I don't think the context is sensitive: AFAIK, it is enough to use the shortcut I provided to obtain that result (on win 7 works perfectly I don't know about other OSs). Of course I didn't tried every possible context ;-) Of course it is possible to use the menu with the mouse. In this case the context is Info; Menu: File > Save & Reload Ctrl Shift W See the attached screenshot: oi63.tinypic.com/4smw0h.jpg (May be the image will be deleted after a while cause is uploaded onto an external website) $\endgroup$ Jun 25 '16 at 1:19
  • 2
    $\begingroup$ In 2.78 That menu is not there. Is it an addon? $\endgroup$
    – Leander
    Dec 29 '16 at 7:04
  • 1
    $\begingroup$ It is from an addon most likely this one $\endgroup$
    – batFINGER
    Mar 27 '18 at 2:13
  • 1
    $\begingroup$ One more thing, can use "Load Factory Settings" to see what is and what isn't from an addon. As long as you don't save user prefs / startup file etc it's non-destructive of your setup. $\endgroup$
    – batFINGER
    Mar 27 '18 at 3:08
  • 1
    $\begingroup$ NP. Have to admit It was with trepidation (and backup) I tested it. It came up in an answer that used the load factory settings operator to clean up a file after each iteration of a batch operation. $\endgroup$
    – batFINGER
    Mar 28 '18 at 6:20
1
$\begingroup$

Under All Scenes, switch to Blender File. Go to Materials, Right-Click, Delete. Works in 2.79.

$\endgroup$
0
$\begingroup$

If you want to do it using Blender's Python API you can use the following. Just make sure you unlink the unwanted materials before doing this:

        toRemove = [block for block in bpy.data.materials if block.users == 0]
        for block in toRemove:
            bpy.data.materials.remove(block)
$\endgroup$
2
  • $\begingroup$ @batFINGER Oops ... Sorry my bad. I literally copied this code snippet from the class I have written. No need for having self honestly. It's just my personal preference. $\endgroup$
    – Amir
    Mar 27 '18 at 2:50
  • 2
    $\begingroup$ Would explain about not iterating over the list you are removing from. For no particular reason I like to use while to_remove: bpy.data.materials.remove(to_remove.pop()) $\endgroup$
    – batFINGER
    Mar 27 '18 at 2:56
0
$\begingroup$

I remove everything in the set at the start with Blender python. Corrected post: this first snippet removes all materials.

materialsInScene = list(bpy.data.materials)
for eachMat in materialsInScene:
    bpy.data.materials.remove(eachMat)    

The next code snippets remove all meshes and all objects.

meshesInScene = list(bpy.data.meshes)
for eachMesh in meshesInScene:
    bpy.data.meshes.remove(eachMesh)

removeThese = bpy.context.copy()
removeThese['selected_objects'] = list(bpy.context.scene.objects)
bpy.ops.object.delete(removeThese)
$\endgroup$
1
  • $\begingroup$ Question is only re unused materials. Not every scene object, and every material and mesh in blend. $\endgroup$
    – batFINGER
    Feb 12 at 18:00

Not the answer you're looking for? Browse other questions tagged or ask your own question.