Files
blender-portable-repo/scripts/addons/Datablock-Tools-2-master/DatablockTools.py
T
2026-03-17 14:30:01 -06:00

122 lines
4.0 KiB
Python

bl_info = {
"name": "Datablock Tools",
"author": "Mackenzie Crawford, Vitor Balbio",
"version": (2, 2, 1),
"blender": (2, 80, 0),
"location": "View3D > Object > Datablock Tools",
"description": "Some tools to handle datablocks",
"warning": "",
"tracker_url": "",
"category": "3D View"}
import bpy
import re
class CleanImagesOP(bpy.types.Operator):
#replace the ".0x" images with the original and mark this to remove in next load
bl_idname = "object.clean_images"
bl_label = "Clean Images Datablocks"
@classmethod
def poll(cls, context):
return context.selected_objects is not None
def execute(self, context):
ImageList = []
#get full image name including extension
for i in bpy.data.images:
ImageList.append([i.name,i])
for obj in bpy.context.selected_objects:
for uv in obj.data.uv_textures.items():
for faceTex in uv[1].data:
if (not (faceTex.image is None)):
image = faceTex.image
if (bool(re.search(r'\.(\d){3}', image.name))): #if an image is set, and its name contains a . followed by 3 digits
replaced = False
for ima_name, ima in ImageList:
if (image.name.startswith(ima_name) and (".0" not in ima_name)):
faceTex.image.user_clear()
faceTex.image = ima
replaced = True
if (replaced == False):
#we didn't find a match, rename this one
image.name = image.name.rsplit(".", 1)[0] #splits on the last . in the image name and returns the left part. Allows handling of names with multiple .s
return {'FINISHED'}
class CleanMaterialsOP(bpy.types.Operator):
#replace the ".0x" materials with the original and mark this to remove in next load
bl_idname = "object.clean_materials"
bl_label = "Clean Materials Datablocks"
@classmethod
def poll(cls, context):
return context.selected_objects is not None
def execute(self, context):
matlist = bpy.data.materials
for obj in bpy.context.selected_objects:
for mat_slt in obj.material_slots:
if (mat_slt.material != None and bool(re.search(r'\.(\d){3}', mat_slt.material.name))): #if a material is set, and its name contains a . followed by 3 digits
replaced = False
for mat in matlist:
if ((mat.name == mat_slt.material.name.rsplit(".", 1)[0]) and (not bool(re.search(r'\.(\d){3}', mat.name)))):
mat_slt.material = mat
replaced = True
if replaced == False:
#we didn't find a match, rename this one
mat_slt.material.name = mat_slt.material.name.rsplit(".", 1)[0] #splits on the last . in the material name and returns the left part. Allows handling of names with multiple .s
return {'FINISHED'}
class RemoveAllMaterialsOP(bpy.types.Operator):
#removes all materials from selected objects
bl_idname = "object.remove_materials"
bl_label = "Remove All Materials Datablocks"
@classmethod
def poll(cls, context):
return context.selected_objects is not None
def execute(self, context):
for obj in bpy.context.selected_objects:
#iterate through materials list and remove each sequentially
obj.active_material_index = 0
for i in range(len(obj.material_slots)):
bpy.ops.object.material_slot_remove({'object': obj})
return {'FINISHED'}
class DatablockToolsMenu(bpy.types.Menu):
bl_label = "Datablock Tools"
bl_idname = "VIEW_MT_datablock_tools"
def draw(self, context):
layout = self.layout
layout.operator("object.clean_materials")
layout.operator("object.remove_materials")
layout.operator("object.clean_images")
layout.operator("object.set_instance")
def draw_item(self, context):
layout = self.layout
layout.menu(DatablockToolsMenu.bl_idname)
classes = (CleanMaterialsOP, RemoveAllMaterialsOP, CleanImagesOP, DatablockToolsMenu)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
bpy.types.VIEW3D_MT_object.append(draw_item)
def unregister():
from bpy.utils import unregister_class
for cls in reverse(classes):
unregister_class(cls)
bpy.types.VIEW3D_MT_object.remove(draw_item)
if __name__ == "__main__":
register()