2026-02-16
This commit is contained in:
@@ -30,6 +30,9 @@ from ..utils import compat
|
||||
from .utils import delete
|
||||
from .utils import duplicate
|
||||
|
||||
# Module-level state for inspection delete
|
||||
_inspect_delete_state = None
|
||||
|
||||
|
||||
def _check_library_or_override(datablock):
|
||||
"""Check if datablock is library-linked or override, return error message if so."""
|
||||
@@ -488,115 +491,181 @@ class ATOMIC_OT_inspection_delete(bpy.types.Operator):
|
||||
bl_label = "Delete Data-Block"
|
||||
|
||||
def execute(self, context):
|
||||
atom = bpy.context.scene.atomic
|
||||
atom = context.scene.atomic
|
||||
inspection = atom.active_inspection
|
||||
|
||||
if inspection == 'COLLECTIONS':
|
||||
key = atom.collections_field
|
||||
collections = bpy.data.collections
|
||||
|
||||
if key in collections.keys():
|
||||
collection = collections[key]
|
||||
error = _check_library_or_override(collection)
|
||||
if error:
|
||||
self.report({'ERROR'}, error)
|
||||
return {'CANCELLED'}
|
||||
delete.collection(key)
|
||||
atom.collections_field = ""
|
||||
|
||||
elif inspection == 'IMAGES':
|
||||
key = atom.images_field
|
||||
images = bpy.data.images
|
||||
|
||||
if key in images.keys():
|
||||
image = images[key]
|
||||
error = _check_library_or_override(image)
|
||||
if error:
|
||||
self.report({'ERROR'}, error)
|
||||
return {'CANCELLED'}
|
||||
delete.image(key)
|
||||
atom.images_field = ""
|
||||
|
||||
elif inspection == 'LIGHTS':
|
||||
key = atom.lights_field
|
||||
lights = bpy.data.lights
|
||||
|
||||
if key in lights.keys():
|
||||
light = lights[key]
|
||||
error = _check_library_or_override(light)
|
||||
if error:
|
||||
self.report({'ERROR'}, error)
|
||||
return {'CANCELLED'}
|
||||
delete.light(key)
|
||||
atom.lights_field = ""
|
||||
|
||||
elif inspection == 'MATERIALS':
|
||||
key = atom.materials_field
|
||||
materials = bpy.data.materials
|
||||
|
||||
if key in materials.keys():
|
||||
material = materials[key]
|
||||
error = _check_library_or_override(material)
|
||||
if error:
|
||||
self.report({'ERROR'}, error)
|
||||
return {'CANCELLED'}
|
||||
delete.material(key)
|
||||
atom.materials_field = ""
|
||||
|
||||
elif inspection == 'NODE_GROUPS':
|
||||
key = atom.node_groups_field
|
||||
node_groups = bpy.data.node_groups
|
||||
|
||||
if key in node_groups.keys():
|
||||
node_group = node_groups[key]
|
||||
error = _check_library_or_override(node_group)
|
||||
if error:
|
||||
self.report({'ERROR'}, error)
|
||||
return {'CANCELLED'}
|
||||
delete.node_group(key)
|
||||
atom.node_groups_field = ""
|
||||
|
||||
elif inspection == 'PARTICLES':
|
||||
key = atom.particles_field
|
||||
particles = bpy.data.particles
|
||||
if key in particles.keys():
|
||||
particle = particles[key]
|
||||
error = _check_library_or_override(particle)
|
||||
if error:
|
||||
self.report({'ERROR'}, error)
|
||||
return {'CANCELLED'}
|
||||
delete.particle(key)
|
||||
atom.particles_field = ""
|
||||
|
||||
elif inspection == 'TEXTURES':
|
||||
key = atom.textures_field
|
||||
textures = bpy.data.textures
|
||||
|
||||
if key in textures.keys():
|
||||
texture = textures[key]
|
||||
error = _check_library_or_override(texture)
|
||||
if error:
|
||||
self.report({'ERROR'}, error)
|
||||
return {'CANCELLED'}
|
||||
delete.texture(key)
|
||||
atom.textures_field = ""
|
||||
|
||||
elif inspection == 'WORLDS':
|
||||
key = atom.worlds_field
|
||||
worlds = bpy.data.worlds
|
||||
|
||||
if key in worlds.keys():
|
||||
world = worlds[key]
|
||||
error = _check_library_or_override(world)
|
||||
if error:
|
||||
self.report({'ERROR'}, error)
|
||||
return {'CANCELLED'}
|
||||
delete.world(key)
|
||||
atom.worlds_field = ""
|
||||
|
||||
# Initialize progress tracking
|
||||
atom.is_operation_running = True
|
||||
atom.operation_progress = 0.0
|
||||
atom.operation_status = f"Deleting {inspection.lower()}..."
|
||||
atom.cancel_operation = False
|
||||
|
||||
# Store state in module-level variable for timer processing
|
||||
global _inspect_delete_state
|
||||
_inspect_delete_state = {
|
||||
'inspection': inspection
|
||||
}
|
||||
|
||||
# Start timer for processing (even though it's quick, keep UI responsive)
|
||||
bpy.app.timers.register(_process_inspect_delete_step)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def _process_inspect_delete_step():
|
||||
"""Process inspection delete in steps to avoid blocking the UI"""
|
||||
atom = bpy.context.scene.atomic
|
||||
global _inspect_delete_state
|
||||
|
||||
if _inspect_delete_state is None:
|
||||
return None
|
||||
|
||||
inspection = _inspect_delete_state['inspection']
|
||||
|
||||
# Check for cancellation
|
||||
if atom.cancel_operation:
|
||||
atom.is_operation_running = False
|
||||
atom.operation_progress = 0.0
|
||||
atom.operation_status = "Operation cancelled"
|
||||
atom.cancel_operation = False
|
||||
_inspect_delete_state = None
|
||||
# Force UI update
|
||||
for area in bpy.context.screen.areas:
|
||||
area.tag_redraw()
|
||||
return None
|
||||
|
||||
atom.operation_progress = 50.0
|
||||
|
||||
# Perform deletion
|
||||
try:
|
||||
if inspection == 'COLLECTIONS':
|
||||
key = atom.collections_field
|
||||
collections = bpy.data.collections
|
||||
|
||||
if key in collections.keys():
|
||||
collection = collections[key]
|
||||
error = _check_library_or_override(collection)
|
||||
if error:
|
||||
atom.is_operation_running = False
|
||||
atom.operation_status = ""
|
||||
return None
|
||||
delete.collection(key)
|
||||
atom.collections_field = ""
|
||||
|
||||
elif inspection == 'IMAGES':
|
||||
key = atom.images_field
|
||||
images = bpy.data.images
|
||||
|
||||
if key in images.keys():
|
||||
image = images[key]
|
||||
error = _check_library_or_override(image)
|
||||
if error:
|
||||
atom.is_operation_running = False
|
||||
atom.operation_status = ""
|
||||
return None
|
||||
delete.image(key)
|
||||
atom.images_field = ""
|
||||
|
||||
elif inspection == 'LIGHTS':
|
||||
key = atom.lights_field
|
||||
lights = bpy.data.lights
|
||||
|
||||
if key in lights.keys():
|
||||
light = lights[key]
|
||||
error = _check_library_or_override(light)
|
||||
if error:
|
||||
atom.is_operation_running = False
|
||||
atom.operation_status = ""
|
||||
return None
|
||||
delete.light(key)
|
||||
atom.lights_field = ""
|
||||
|
||||
elif inspection == 'MATERIALS':
|
||||
key = atom.materials_field
|
||||
materials = bpy.data.materials
|
||||
|
||||
if key in materials.keys():
|
||||
material = materials[key]
|
||||
error = _check_library_or_override(material)
|
||||
if error:
|
||||
atom.is_operation_running = False
|
||||
atom.operation_status = ""
|
||||
return None
|
||||
delete.material(key)
|
||||
atom.materials_field = ""
|
||||
|
||||
elif inspection == 'NODE_GROUPS':
|
||||
key = atom.node_groups_field
|
||||
node_groups = bpy.data.node_groups
|
||||
|
||||
if key in node_groups.keys():
|
||||
node_group = node_groups[key]
|
||||
error = _check_library_or_override(node_group)
|
||||
if error:
|
||||
atom.is_operation_running = False
|
||||
atom.operation_status = ""
|
||||
return None
|
||||
delete.node_group(key)
|
||||
atom.node_groups_field = ""
|
||||
|
||||
elif inspection == 'PARTICLES':
|
||||
key = atom.particles_field
|
||||
particles = bpy.data.particles
|
||||
if key in particles.keys():
|
||||
particle = particles[key]
|
||||
error = _check_library_or_override(particle)
|
||||
if error:
|
||||
atom.is_operation_running = False
|
||||
atom.operation_status = ""
|
||||
return None
|
||||
delete.particle(key)
|
||||
atom.particles_field = ""
|
||||
|
||||
elif inspection == 'TEXTURES':
|
||||
key = atom.textures_field
|
||||
textures = bpy.data.textures
|
||||
|
||||
if key in textures.keys():
|
||||
texture = textures[key]
|
||||
error = _check_library_or_override(texture)
|
||||
if error:
|
||||
atom.is_operation_running = False
|
||||
atom.operation_status = ""
|
||||
return None
|
||||
delete.texture(key)
|
||||
atom.textures_field = ""
|
||||
|
||||
elif inspection == 'WORLDS':
|
||||
key = atom.worlds_field
|
||||
worlds = bpy.data.worlds
|
||||
|
||||
if key in worlds.keys():
|
||||
world = worlds[key]
|
||||
error = _check_library_or_override(world)
|
||||
if error:
|
||||
atom.is_operation_running = False
|
||||
atom.operation_status = ""
|
||||
return None
|
||||
delete.world(key)
|
||||
atom.worlds_field = ""
|
||||
except:
|
||||
pass # Handle any errors gracefully
|
||||
|
||||
# Operation complete
|
||||
atom.is_operation_running = False
|
||||
atom.operation_progress = 100.0
|
||||
atom.operation_status = ""
|
||||
|
||||
# Clear state
|
||||
_inspect_delete_state = None
|
||||
|
||||
# Force UI update
|
||||
for area in bpy.context.screen.areas:
|
||||
area.tag_redraw()
|
||||
|
||||
return None # Stop timer
|
||||
|
||||
|
||||
reg_list = [
|
||||
ATOMIC_OT_inspection_rename,
|
||||
ATOMIC_OT_inspection_replace,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -26,61 +26,131 @@ import bpy
|
||||
from ...stats import unused
|
||||
|
||||
|
||||
def collections():
|
||||
def collections(cached_list=None):
|
||||
# removes all unused collections from the project
|
||||
for collection_key in unused.collections_deep():
|
||||
bpy.data.collections.remove(bpy.data.collections[collection_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
collection_keys = cached_list
|
||||
else:
|
||||
collection_keys = unused.collections_deep()
|
||||
|
||||
for collection_key in collection_keys:
|
||||
if collection_key in bpy.data.collections:
|
||||
bpy.data.collections.remove(bpy.data.collections[collection_key])
|
||||
|
||||
|
||||
def images():
|
||||
def images(cached_list=None):
|
||||
# removes all unused images from the project
|
||||
for image_key in unused.images_deep():
|
||||
bpy.data.images.remove(bpy.data.images[image_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
image_keys = cached_list
|
||||
else:
|
||||
image_keys = unused.images_deep()
|
||||
|
||||
for image_key in image_keys:
|
||||
if image_key in bpy.data.images:
|
||||
bpy.data.images.remove(bpy.data.images[image_key])
|
||||
|
||||
|
||||
def lights():
|
||||
def lights(cached_list=None):
|
||||
# removes all unused lights from the project
|
||||
for light_key in unused.lights_deep():
|
||||
bpy.data.lights.remove(bpy.data.lights[light_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
light_keys = cached_list
|
||||
else:
|
||||
light_keys = unused.lights_deep()
|
||||
|
||||
for light_key in light_keys:
|
||||
if light_key in bpy.data.lights:
|
||||
bpy.data.lights.remove(bpy.data.lights[light_key])
|
||||
|
||||
|
||||
def materials():
|
||||
def materials(cached_list=None):
|
||||
# removes all unused materials from the project
|
||||
for light_key in unused.materials_deep():
|
||||
bpy.data.materials.remove(bpy.data.materials[light_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
material_keys = cached_list
|
||||
else:
|
||||
material_keys = unused.materials_deep()
|
||||
|
||||
for material_key in material_keys:
|
||||
if material_key in bpy.data.materials:
|
||||
bpy.data.materials.remove(bpy.data.materials[material_key])
|
||||
|
||||
|
||||
def node_groups():
|
||||
def node_groups(cached_list=None):
|
||||
# removes all unused node groups from the project
|
||||
for node_group_key in unused.node_groups_deep():
|
||||
bpy.data.node_groups.remove(bpy.data.node_groups[node_group_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
node_group_keys = cached_list
|
||||
else:
|
||||
node_group_keys = unused.node_groups_deep()
|
||||
|
||||
for node_group_key in node_group_keys:
|
||||
if node_group_key in bpy.data.node_groups:
|
||||
bpy.data.node_groups.remove(bpy.data.node_groups[node_group_key])
|
||||
|
||||
|
||||
def particles():
|
||||
def particles(cached_list=None):
|
||||
# removes all unused particle systems from the project
|
||||
for particle_key in unused.particles_deep():
|
||||
bpy.data.particles.remove(bpy.data.particles[particle_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
particle_keys = cached_list
|
||||
else:
|
||||
particle_keys = unused.particles_deep()
|
||||
|
||||
for particle_key in particle_keys:
|
||||
if particle_key in bpy.data.particles:
|
||||
bpy.data.particles.remove(bpy.data.particles[particle_key])
|
||||
|
||||
|
||||
def textures():
|
||||
def textures(cached_list=None):
|
||||
# removes all unused textures from the project
|
||||
for texture_key in unused.textures_deep():
|
||||
bpy.data.textures.remove(bpy.data.textures[texture_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
texture_keys = cached_list
|
||||
else:
|
||||
texture_keys = unused.textures_deep()
|
||||
|
||||
for texture_key in texture_keys:
|
||||
if texture_key in bpy.data.textures:
|
||||
bpy.data.textures.remove(bpy.data.textures[texture_key])
|
||||
|
||||
|
||||
def worlds():
|
||||
def worlds(cached_list=None):
|
||||
# removes all unused worlds from the project
|
||||
for world_key in unused.worlds():
|
||||
bpy.data.worlds.remove(bpy.data.worlds[world_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
world_keys = cached_list
|
||||
else:
|
||||
world_keys = unused.worlds()
|
||||
|
||||
for world_key in world_keys:
|
||||
if world_key in bpy.data.worlds:
|
||||
bpy.data.worlds.remove(bpy.data.worlds[world_key])
|
||||
|
||||
|
||||
def objects():
|
||||
def objects(cached_list=None):
|
||||
# removes all unused objects from the project
|
||||
for object_key in unused.objects_deep():
|
||||
bpy.data.objects.remove(bpy.data.objects[object_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
object_keys = cached_list
|
||||
else:
|
||||
object_keys = unused.objects_deep()
|
||||
|
||||
for object_key in object_keys:
|
||||
if object_key in bpy.data.objects:
|
||||
bpy.data.objects.remove(bpy.data.objects[object_key])
|
||||
|
||||
|
||||
def armatures():
|
||||
def armatures(cached_list=None):
|
||||
# removes all unused armatures from the project
|
||||
for armature_key in unused.armatures_deep():
|
||||
bpy.data.armatures.remove(bpy.data.armatures[armature_key])
|
||||
# If cached_list is provided, use it instead of recalculating
|
||||
if cached_list is not None:
|
||||
armature_keys = cached_list
|
||||
else:
|
||||
armature_keys = unused.armatures_deep()
|
||||
|
||||
for armature_key in armature_keys:
|
||||
if armature_key in bpy.data.armatures:
|
||||
bpy.data.armatures.remove(bpy.data.armatures[armature_key])
|
||||
|
||||
Reference in New Issue
Block a user