Ich habe in letzter Zeit öfter Blenderdateien aufräumen müssen. Jedesmal wenn ich mehr als drei mal dasselbe geklickt habe, dachte ich kurz: geht das nicht über ein Skript? So habe ich z.B. mit einem Skript mit fünf Zeilen alle Bilder unlinked.
Ich habe schon häufig gelesen, dass Leute die Bilder aus ihrer Blenderdatei entfernen möchten. Das geht erstaunlich einfach, wenn man ein klein wenig Skripting-Erfahrung hat. Hier ist ein Skript, das die User aller Bilder aus einer Szene auf 0 setzt, wenn man die Datei dann speichert und wieder öffnet, sind sie verschwunden. Hier das vorläufige Skript inklusive Erläuterungen. Beim Kopieren in den Blender Skript-Editor ist zu beachten, dass die Einrückungen korrekt gesetzt sind:
[code:python]import bpy
imgs = bpy.data.images
for image in imgs:
image.user_clear()[/code]
bpy.data.images speichert alle Bilder in einem Array (imgs). Die for-Schleife wird so oft ausgeführt, wie es Bilder in data gibt. user_clear() ist eine Methode um die Anzahl der user auf 0 zu setzen
Manche werden sich jetzt zurecht fragen: "Was, wenn ich manche Bilder behalten will?" Da gibt es eine bessere Methode:
Ich setze vor die Namen der Bilder, die ich behalten möchte, ein bestimmtes Wort - sagen wir: "keep". (Per Hand im Image Editor)
[code:python]import bpy
imgs = bpy.data.images
for image in imgs:
name = image.name
if name[:4] != "keep":
image.user_clear()[/code]
Die Zeile if name[:4] != "keep": checkt die ersten 4 Zeichen des Strings und checkt, ob es sich um die Reihenfolge "keep" handelt. [:n] nimmt die ersten n Buchstaben aus einem String, [n:] die letzten n.
!= bedeutet ungleich, also wenn die ersten 4 Buchstaben nicht "keep" sind, wird das Bild gelöscht.
Wem das zu mühselig ist und wer sowieso schon weiß, dass er nur die Bilder behalten will, die in einer Textur benutzt werden, der kann alle Bilder löschen, die nicht in einer oder mehreren Texturen verwendet werden:
[code:python]import bpy
img_names = []
#Wenn man die Methode append anwenden möchte, muss man sicherstellen, dass man es an eine Liste anhängt. = [] erstellt eine leere Liste
textures = bpy.data.textures
# Speichert die Namen aller Bilder, die in einer Textur verwendet werden, in einer Liste.
for tex in textures:
if tex.type == 'IMAGE':
img_names.append(tex.image.name)
# Die if Abfrage testet, ob der Name eines Bildes nicht in der Liste ist.
imgs = bpy.data.images
for image in imgs:
name = image.name
if name not in img_names:
image.user_clear()[/code]
Vorsicht: alle Referenz- und Hintergrundbilder werden natürlich ebenfalls entfernt.
Da habt ihr's also: ein Skript, das alle Bilder aus euren Blendfiles schmeisst, die nicht in einer Textur verwendet werden:[code:python]import bpy
img_names = []
textures = bpy.data.textures
for tex in textures:
if tex.type == 'IMAGE':
img_names.append(tex.image.name)
imgs = bpy.data.images
for image in imgs:
name = image.name
if name not in img_names:
image.user_clear() [/code]
Da Cycles keine Texture slots benutzt, sondern Nodes, ist das Skript ein wenig komplizierter:
[code:python]import bpy
print('new run')
img_names = []
materials = bpy.data.materials
for mat in materials:
nodes = mat.node_tree.nodes
# print(nodes)
for node in nodes:
if type(node) == bpy.types.ShaderNodeTexImage:
try:
nam = node.image.name
img_names.append(nam)
print("name: " + nam)
except:
print('No texture assigned to this node, no problem though')
imgs = bpy.data.images
for image in imgs:
name = image.name
if name not in img_names:
image.user_clear()
[/code]
Deshalb noch ein wenig mehr information: nodes = mat.node_tree.nodes speichert alle Nodes des aktuellen Materials in einer Liste. Die nächste for-Schleife geht diese Materialien durch und wenn es sich bei einer Node um eine Textur Node handelt, wird der Name des zugehörigen Bildes der Liste img_names angehängt. Ich habe try verwendet, weil nam = node.image.name in manchen Durchgängen der Schleife einen Fehler verursacht hat. Wenn die Möglichkeit besteht, dass so etwas passiert, kann man zur Sicherheit try: verwenden. Wenn es einen Fehler bei dem Versuch gibt, macht Python nur das was hinter except steht. In diesem Fall wird es uns freundlich informieren, dass es bei einem Durchlauf einen Fehler abgewendet hat.
Warnung: Dieses Skript funktioniert nicht, wenn es Materialien gibt, die "use Nodes" ausgeschaltet haben.