2025-07-01

This commit is contained in:
2026-03-17 14:30:01 -06:00
parent f9a22056dd
commit 62b5978595
4579 changed files with 1257472 additions and 0 deletions
@@ -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()
@@ -0,0 +1,57 @@
# Datablock-Tools-2
Updated version of Datablock Tools for Blender https://blenderartists.org/forum/showthread.php?320593-Datablock-Tools
Datablock Tools provides an easy way to remove duplicated material or UV image datablocks ("image.png.001", etc), typically created when copy-pasting objects. This reduces memory footprint and also makes editing materials a lot easier.
## Usage
All datablock tools can be found under Object -> Datablock Tools.
* **Clean Images Datablocks:** Removes duplicated UV images from selected objects. If an original image is found ("image.png" instead of "image.png.001"), all duplicate instances will be replaced with the original. Otherwise, one instance is renamed to removed the .xxx suffix
* **Clean Materials Datablocks:** Removes duplicated materials from selected objects. If an original material is found ("material.png" instead of "material.png.001"), all duplicate instances will be replaced with the original. Otherwise, one instance is renamed to removed the .xxx suffix
* **Remove All Materials Datablocks:** Removes all materials from selected objects.
* **Set As Instance:** Converts all *selected* objects into instances of the *active* object. Any change to the geometry or materials of a single instance will affect all instances of the object.
## Changelog
### 2.2.1
* Remove "set as instance" tool. Blender includes an equivalent tool built-in anyway, no point duplicating code
### 2.2
* Update for Blender 2.80 API. Still compatible with 2.7x
### 2.1
* Fixed fatal bug with image datablock clean on objects with incomplete unwrapping
* If image datablock has no "original" version (without .xxx suffix), rename it to become that
* Image datablock cleaner now uses regex search, like the material cleaner
* Support image/material names with multiple periods, preserves image extensions
* Code styling and commenting improvements for future maintainability
* Text and layout tweaks
* Tool to remove all materials from an object
### 2.0
* First version by Mackenzie Crawford, taking over as de facto developer of apparently orphaned project
* Update for Blender 2.78 onwards
* Switch to regex-based datablock name comparisons
* In absence of a "virgin" material (not image yet) datablock, rename one of the existing duplicates instead of leaving all duplicates unchanged
* Restructure program and translate comments to English for better maintainability in the future
### 1.0, 1.1
* Original release by Vitor Balbio. See BlenderArtists thread [here](https://blenderartists.org/t/datablock-tool/595316) and deprecated Blender Wiki page [here](https://archive.blender.org/wiki/index.php/Extensions:2.6/Py/Scripts/3D_interaction/Datablock_Tools/)