2025-07-01
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user