122 lines
4.0 KiB
Python
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() |