Page 1 of 2 12 LastLast
Results 1 to 20 of 32
  1. #1

    Orphan Slayer - Clears Scenes and Removes Unused Objects

    I'm working on this tool for clearing scenes and removing unused objects from a Blender project. Not sure whether or not I'm reinventing any wheels here but ..... here it is!

    Code:
    # orphan_slayer.py (c) 2011 Phil Cote (cotejrp1)
    #
    # ***** BEGIN GPL LICENSE BLOCK *****
    #
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software Foundation,
    # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ***** END GPL LICENCE BLOCK *****
    
    bl_info = {
        'name': 'Orphan Slayer',
        'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
        'version': (0,1),
        "blender": (2, 5, 9),
        "api": 35853,
        'location': 'VIEW 3D -> TOOLS',
        'description': 'Deletes objects from a scene and from the bpy.data modules',
        'warning': '', # used for warning icon and text in addons panel
        'category': 'System'}
    
    import bpy, random, time
    from pdb import set_trace
    
        
    class DeleteSceneObsOp(bpy.types.Operator):
        '''.'''
        bl_idname = "ba.delete_scene_obs"
        bl_label = "Delete Scene Objects"
    
        def execute(self, context):
            for ob in context.scene.objects:
                context.scene.objects.unlink(ob)
            return {'FINISHED'}
    
    
    class DeleteOrphansOp(bpy.types.Operator):
        
        bl_idname="ba.delete_data_obs"
        bl_label="Delete Orphans"
        
        def execute(self, context):
            target_coll = eval("bpy.data." + context.scene.mod_list)
            print("chosen target collection: " + str(target_coll))
            print( "size of target collection: %d" % len(target_coll) )
            for item in target_coll:
                if item.users == 0:
                    target_coll.remove(item)
            
            return {'FINISHED'}
        
    
    class OrphanSlayerPanel( bpy.types.Panel ):
        
        bl_label = "Orphan Slayer"
        bl_space_type = "VIEW_3D"
        bl_region_type = "TOOLS"
        bl_context = "objectmode"
        
        def draw( self, context ):
            scn = context.scene
            
            layout = self.layout
            col = layout.column()
            layout.column().prop(scn, "mod_list")
            col.operator("ba.delete_scene_obs")
            col.operator("ba.delete_data_obs")
        
    
    def register():
    
        mod_data = [tuple(["actions"]*3), tuple(["armatures"]*3), 
                     tuple(["cameras"]*3), tuple(["curves"]*3),
                     tuple(["fonts"]*3), tuple(["grease_pencil"]*3),
                     tuple(["groups"]*3), tuple(["images"]*3),
                     tuple(["lamps"]*3), tuple(["lattices"]*3),
                     tuple(["libraries"]*3), tuple(["materials"]*3),
                     tuple(["meshes"]*3), tuple(["metaballs"]*3),
                     tuple(["node_groups"]*3), tuple(["objects"]*3),
                     tuple(["sounds"]*3), tuple(["texts"]*3), 
                     tuple(["textures"]*3),]
        
        
        bpy.types.Scene.mod_list = bpy.props.EnumProperty(name="Orphan Target", 
                                                            items=mod_data, 
                                                            description="Module choice made for orphan deletion")
        bpy.utils.register_class(DeleteSceneObsOp)
        bpy.utils.register_class(DeleteOrphansOp)
        bpy.utils.register_class(OrphanSlayerPanel)
        
    
    def unregister():
        bpy.utils.unregister_class(DeleteSceneObsOp)
        bpy.utils.unregister_class(DeleteOrphansOp)
        bpy.utils.unregister_class(OrphanSlayerPanel)
    
    
    if __name__ == "__main__":
        register()



  2. #2
    Member tungee's Avatar
    Join Date
    Nov 2007
    Location
    Germany Frankfurt
    Posts
    1,421
    Thank you!
    I needed to destroy old materials for the cycles render engine lately , very handy!
    In the end, only blender will surrender
    i7 4770 - 2x GTX 780 ti- 32GB



  3. #3
    Glad you found it useful, Tungee.

    A few quick changes to the script....
    1. Dumped the silly name. Changed it to "Orphan Cleanup". (still officially Orphan Slayer in Github)
    2. Dumped the "Delete scene objects" button. It didn't really need to be there and had potential for being mistaken for a "delete by type" button.

    Here's the update.

    Code:
    # orphan_cleanup.py (c) 2011 Phil Cote (cotejrp1)
    #
    # ***** BEGIN GPL LICENSE BLOCK *****
    #
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software Foundation,
    # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ***** END GPL LICENCE BLOCK *****
    
    bl_info = {
        'name': 'Orphan Slayer',
        'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
        'version': (0,1),
        "blender": (2, 5, 9),
        "api": 35853,
        'location': 'VIEW 3D -> TOOLS',
        'description': 'Deletes unused objects from the bpy.data modules',
        'warning': '', # used for warning icon and text in addons panel
        'category': 'System'}
    
    import bpy, random, time
    from pdb import set_trace
    
    class DeleteOrphansOp(bpy.types.Operator):
        '''Remove all orphaned objects of a selected type from the project.'''
        bl_idname="ba.delete_data_obs"
        bl_label="Delete Orphans"
        
        def execute(self, context):
            target = context.scene.mod_list
            target_coll = eval("bpy.data." + target)
            
            num_deleted = 0
            
            for item in target_coll:
                if item.users == 0:
                    target_coll.remove(item)
                    num_deleted += 1
            
            msg = "Removed %d orphaned %s objects" % (num_deleted, target)
            self.report( { 'INFO' }, msg  )
            return {'FINISHED'}
        
    
    class OrphanCleanupPanel( bpy.types.Panel ):
        '''Main Panel for Orphan Cleanup script'''
        bl_label = "Orphan Cleanup"
        bl_space_type = "VIEW_3D"
        bl_region_type = "TOOLS"
        bl_context = "objectmode"
        
        def draw( self, context ):
            scn = context.scene
            layout = self.layout
            new_col = self.layout.column
            
            new_col().column().prop(scn, "mod_list")
            new_col().column().operator("ba.delete_data_obs")
        
    
    def register():
    
        mod_data = [tuple(["actions"]*3), tuple(["armatures"]*3), 
                     tuple(["cameras"]*3), tuple(["curves"]*3),
                     tuple(["fonts"]*3), tuple(["grease_pencil"]*3),
                     tuple(["groups"]*3), tuple(["images"]*3),
                     tuple(["lamps"]*3), tuple(["lattices"]*3),
                     tuple(["libraries"]*3), tuple(["materials"]*3),
                     tuple(["meshes"]*3), tuple(["metaballs"]*3),
                     tuple(["node_groups"]*3), tuple(["objects"]*3),
                     tuple(["sounds"]*3), tuple(["texts"]*3), 
                     tuple(["textures"]*3),]
        
        
        bpy.types.Scene.mod_list = bpy.props.EnumProperty(name="Target", 
                               items=mod_data, 
                               description="Module choice made for orphan deletion")
    
        bpy.utils.register_class(DeleteOrphansOp)
        bpy.utils.register_class(OrphanCleanupPanel)
        
    
    def unregister():
        bpy.utils.unregister_class(OrphanCleanupPanel)
        bpy.utils.unregister_class(DeleteOrphansOp)
    
    
    if __name__ == "__main__":
        register()



  4. #4
    Good works. instead of individualorphan, im look forward deleting "All" orphan could be nice.


    example


    mod_data = [tuple(["actions"]*3), tuple(["armatures"]*3), tuple(["cameras"]*3), tuple(["curves"]*3), tuple(["fonts"]*3), tuple(["grease_pencil"]*3), tuple(["groups"]*3), tuple(["images"]*3), tuple(["lamps"]*3), tuple(["lattices"]*3), tuple(["libraries"]*3), tuple(["materials"]*3), tuple(["meshes"]*3), tuple(["metaballs"]*3), tuple(["node_groups"]*3), tuple(["objects"]*3), tuple(["sounds"]*3), tuple(["texts"]*3), tuple(["textures"]*3),tuple(["All"]*3) ]
    Drop menu "All" inserted.may be "while" or "for" loop used.

    Thank you!
    Last edited by MetalDX; 09-Oct-11 at 05:16.



  5. #5
    Welcome to the forums MetalDX. I'm a little hesitant to add the all feature because it seems like it would make it a little too powerful. I think it's better that the artist think through what resources they do and don't want to get rid of even as orphans are concerned.



  6. #6
    this is very helpful, i was wondering.. for stripping blend files down, cleaning them up..
    the UV image editor stores image names etc.. render result,
    and the names of the textures that you have used thus far in the bulding process(yes i used thus

    anyhow, could you orphan slay these words in the uv image editor?

    UV image editor1.JPG

    for some reason appending the meshes out of the blend file doesnt work either.. <br>
    those uv editor words come with it.. strange..
    Last edited by holyenigma74; 21-Oct-11 at 16:15.



  7. #7
    Oh i think i figured it out.. <br>
    IF you orphan slay the material and textures then save and append the meshes into a fresh file,<br>
    you will only get the names of the stuff in the current file.<br>
    there should be a button (Remove all materials and textures, Strip Blend File)
    then after you click it it will say "are you sure, all materials and textures in the blend file will be removed"<br>
    (a safety feature)
    Last edited by holyenigma74; 21-Oct-11 at 16:37.



  8. #8
    An interesting idea. I never thought to do anything that would mess with the blend file itself, just the project in memory. I'll look into it and see what I can do.



  9. #9
    Got back to this project today and did some updates so it could delete speakers in 2.6. Also updated the deletion message so users know how many non-orphaned assets remain for a particular type.

    Holyenigma. You don't need to save into a new file in order to remove images. After poking around, I discovered you can shift click the 'X' in that image list in the UV editor. That should unlink and thus orphan them. Then you can use my tool to get rid of them like any other resource.

    As for the stripping all textures and materials from a blend file on disk, that goes a little beyond the scope of what I was going for in this add-on. It's not a bad idea, just one that I think would be best done with a separate tool. Here's the update at any rate.

    Code:
    # orphan_cleanup.py (c) 2011 Phil Cote (cotejrp1)
    #
    # ***** BEGIN GPL LICENSE BLOCK *****
    #
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software Foundation,
    # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ***** END GPL LICENCE BLOCK *****
    
    bl_info = {
        'name': 'Orphan Cleanup',
        'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
        'version': (0,2),
        "blender": (2, 6, 0),
        "api": 41098,
        'location': 'VIEW 3D -> TOOLS',
        'description': 'Deletes unused objects from the bpy.data modules',
        'warning': 'Know what it is you are deleting. Check datablocks view within outliner if there are any doubts!', # used for warning icon and text in addons panel
        'category': 'System'}
    
    import bpy, random, time
    from pdb import set_trace
    
    mod_data = [tuple(["actions"]*3), tuple(["armatures"]*3), 
                     tuple(["cameras"]*3), tuple(["curves"]*3),
                     tuple(["fonts"]*3), tuple(["grease_pencil"]*3),
                     tuple(["groups"]*3), tuple(["images"]*3),
                     tuple(["lamps"]*3), tuple(["lattices"]*3),
                     tuple(["libraries"]*3), tuple(["materials"]*3),
                     tuple(["meshes"]*3), tuple(["metaballs"]*3),
                     tuple(["node_groups"]*3), tuple(["objects"]*3),
                     tuple(["sounds"]*3), tuple(["texts"]*3), 
                     tuple(["textures"]*3),]
    
    if bpy.app.version[1] >= 60:
        mod_data.append( tuple(["speakers"]*3), )
    
    
    class DeleteOrphansOp(bpy.types.Operator):
        '''Remove all orphaned objects of a selected type from the project.'''
        bl_idname="ba.delete_data_obs"
        bl_label="Delete Orphans"
        
        def execute(self, context):
            target = context.scene.mod_list
            target_coll = eval("bpy.data." + target)
            
            num_deleted = len([x for x in target_coll if x.users==0])
            num_kept = len([x for x in target_coll if x.users==1])
            
            for item in target_coll:
                if item.users == 0:
                    target_coll.remove(item)
            
            msg = "Removed %d orphaned %s objects. Kept %d non-orphans" % (num_deleted, target,
                                                                num_kept)
            self.report( { 'INFO' }, msg  )
            return {'FINISHED'}
        
    
    class OrphanCleanupPanel( bpy.types.Panel ):
        '''Main Panel for Orphan Cleanup script'''
        bl_label = "Orphan Cleanup"
        bl_space_type = "VIEW_3D"
        bl_region_type = "TOOLS"
        bl_context = "objectmode"
        
        def draw( self, context ):
            scn = context.scene
            layout = self.layout
            new_col = self.layout.column
            
            new_col().column().prop(scn, "mod_list")
            new_col().column().operator("ba.delete_data_obs")
        
    
    def register():
        
        
        bpy.types.Scene.mod_list = bpy.props.EnumProperty(name="Target", 
                               items=mod_data, 
                               description="Module choice made for orphan deletion")
    
        bpy.utils.register_class(DeleteOrphansOp)
        bpy.utils.register_class(OrphanCleanupPanel)
        
    
    def unregister():
        bpy.utils.unregister_class(OrphanCleanupPanel)
        bpy.utils.unregister_class(DeleteOrphansOp)
    
    
    if __name__ == "__main__":
        register()



  10. #10
    Member Carrozza's Avatar
    Join Date
    Feb 2008
    Location
    Italy
    Posts
    1,250
    Interesting script. Thanks!



  11. #11
    Member Carrozza's Avatar
    Join Date
    Feb 2008
    Location
    Italy
    Posts
    1,250
    Just a quick feedback after trying this script: I experience an heavy flickering effect while choosing which type of object I want to be cleaned. The menu content is hardly readable, it shows up and disappear continuously.

    Edit: nevermind, probably an issue on my side because I got the same weird flickering with the standard W menu. Gonna reboot and see if it happen again.
    Last edited by Carrozza; 31-Oct-11 at 05:50.



  12. #12
    Member Hammers's Avatar
    Join Date
    Aug 2007
    Location
    Queensland, Australia
    Posts
    657
    Oh yeah! I was having annoying issues with packing a file for Greenbutton - Solved! Thanks so much. We love you orphan slayer
    My animated music video for the Marphoi Project: King of Majesty
    Bullet-based physics marble machine animation: Sisyphus Engine No.1
    My latest showreel



  13. #13
    Member 3pointEdit's Avatar
    Join Date
    Sep 2005
    Location
    Brisbane, Australia
    Posts
    8,485
    Can this kill screen view setups too? I have a couple that crash blender in a project with dubious scenes.
    Cheers, David ___________"awesome in space and other places".
    ________Follow me on twitter @3pointedit
    _____________ Check the Youtube Channel for tutorials. Or my Sketchbook



  14. #14
    Originally Posted by 3pointEdit View Post
    Can this kill screen view setups too? I have a couple that crash blender in a project with dubious scenes.
    I'm not sure how I would pull that off. For all the other types that this tool supports, it assumes the existence of a remove() function as part of the data list. The list of screens doesn't come with a remove option. I wish it did because I think it's a really good idea.



  15. #15
    This script is one of my absolute favourites but I've encountered an inability to remove Grease Pencil orphans.
    Blender 2.61.2 r43328 Linux64

    Here's the error incase you'd like to look into it:

    File "~/.blender/2.61/scripts/addons/orphan_cleanup.py", line 65, in execute
    target_coll.remove(item)
    AttributeError: 'bpy_prop_collection' object has no attribute 'remove'

    location:<unknown location>:-1

    location:<unknown location>:-1

    Thanks
    青目鬼



  16. #16
    Member
    Join Date
    Mar 2006
    Location
    none
    Posts
    942
    thanks,very usefull script.

    You don't need to save into a new file in order to remove images. After poking around, I discovered you can shift click the 'X' in that image list in the UV editor. That should unlink and thus orphan them. Then you can use my tool to get rid of them like any other resource.
    please add this usage note as part of download.



  17. #17
    Member
    Join Date
    May 2015
    Location
    Montevideo, Uruguay
    Posts
    2
    Hi, I'm new here as well as in Blender, I've tried to install this addon, but Report an error. I'll be doing something wrong?



  18. #18
    Just an fyi:
    I've been away from Blender for way too long and I admit I've let myself get a bit rusty. That being said, I started working on a new git branch update on orphan slayer. It's absolutely a buggy untested WIP right now but here's the url to that in case anyone is curious.

    https://github.com/pcote/orphan_slay..._datablock_set



  19. #19
    Update:
    A somewhat closer to comprehensive set of options for deletable datablocks. I wasn't able to test everything because I don't know how to create every data block out there under "normal" circumstances. Here's the update at any rate.
    Code:
    # orphan_cleanup.py (c) 2011 Phil Cote (cotejrp1)
    #
    # ***** BEGIN GPL LICENSE BLOCK *****
    #
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software Foundation,
    # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ***** END GPL LICENCE BLOCK *****
    
    bl_info = {
        'name': 'Orphan Cleanup',
        'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
        'version': (0,2),
        "blender": (2, 7, 6),
        'location': 'VIEW 3D -> TOOLS',
        'description': 'Deletes unused objects from the bpy.data modules',
        'warning': 'Know what it is you are deleting. Check datablocks view within outliner if there are any doubts!', # used for warning icon and text in addons panel
        'category': 'System'}
    
    """
    Special note on image removal.
    It's not necessary to save into a new file in order to remove images.
    Shift-click the X in the image list in the UV editor.  That should unlink and thus
    orphan them.  From there, you can use this tool to get rid of the images just like
    you would any other resource.
    """
    
    import bpy, random, time
    
    mod_data = [tuple(["actions"]*3),
                tuple(["armatures"]*3),
                tuple(["brushes"]*3),
                tuple(["cameras"]*3),
                tuple(["curves"]*3),
                tuple(["fonts"]*3),
                tuple(["grease_pencil"]*3),
                tuple(["groups"]*3),
                tuple(["images"]*3),
                tuple(["lamps"]*3),
                tuple(["lattices"]*3),
                tuple(["libraries"]*3),
                tuple(["linestyles"]*3),
                tuple(["materials"]*3),
                tuple(["masks"]*3),
                tuple(["meshes"]*3),
                tuple(["metaballs"]*3),
                tuple(["movieclips"]*3),
                tuple(["node_groups"]*3),
                tuple(["objects"]*3),
                tuple(["particles"]*3),
                tuple(["sounds"]*3),
                tuple(["scenes"]*3),
                tuple(["speakers"]*3),
                tuple(["texts"]*3),
                tuple(["textures"]*3),
                tuple(["worlds"]*3),
    ]
    
    
    
    class DeleteOrphansOp(bpy.types.Operator):
        '''Remove all orphaned objects of a selected type from the project'''
        bl_idname="ba.delete_data_obs"
        bl_label="Delete Orphans"
        
        def execute(self, context):
            target = context.scene.mod_list
            target_coll = eval("bpy.data." + target)
            
            num_deleted = len([x for x in target_coll if x.users==0])
            num_kept = len([x for x in target_coll if x.users==1])
            
            for item in target_coll:
                if item.users == 0:
                    target_coll.remove(item)
            
            msg = "Removed %d orphaned %s objects. Kept %d non-orphans" % (num_deleted, target,
                                                                num_kept)
            self.report( { 'INFO' }, msg  )
            return {'FINISHED'}
        
    
    class OrphanCleanupPanel( bpy.types.Panel ):
        '''Main Panel for Orphan Cleanup script'''
        bl_label = "Orphan Cleanup"
        bl_space_type = "VIEW_3D"
        bl_region_type = "TOOLS"
        bl_context = "objectmode"
        
        def draw( self, context ):
            scn = context.scene
            layout = self.layout
            new_col = self.layout.column
            
            new_col().column().prop(scn, "mod_list")
            new_col().column().operator("ba.delete_data_obs")
            
            
            
        
    
    def register():
        #set_trace()
        #screen_names = [ (screen.name, screen.name, screen.name ) 
        #                    for screen in bpy.data.screens ]
        #bpy.types.Scene.screen_names = bpy.props.EnumProperty(name="Views",
        #                        items=screen_names,
        #                        description = "Possible views to delete"
        #)
        bpy.types.Scene.mod_list = bpy.props.EnumProperty(name="Target", 
                               items=mod_data, 
                               description="Module choice made for orphan deletion")
    
        bpy.utils.register_class(DeleteOrphansOp)
        bpy.utils.register_class(OrphanCleanupPanel)
        
    
    def unregister():
        bpy.utils.unregister_class(OrphanCleanupPanel)
        bpy.utils.unregister_class(DeleteOrphansOp)
    
    
    if __name__ == "__main__":
        register()



  20. #20
    Another update. Decided to add an "all of the above" option for orphaned datablocks.

    Code:
    # orphan_cleanup.py (c) 2011 Phil Cote (cotejrp1)
    #
    # ***** BEGIN GPL LICENSE BLOCK *****
    #
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software Foundation,
    # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ***** END GPL LICENCE BLOCK *****
    
    bl_info = {
        'name': 'Orphan Cleanup',
        'author': 'Phil Cote, cotejrp1, (http://www.blenderaddons.com)',
        'version': (0,2),
        "blender": (2, 7, 6),
        'location': 'VIEW 3D -> TOOLS',
        'description': 'Deletes unused objects from the bpy.data modules',
        'warning': 'Know what it is you are deleting. Check datablocks view within outliner if there are any doubts!', # used for warning icon and text in addons panel
        'category': 'System'}
    
    """
    Special note on image removal.
    It's not necessary to save into a new file in order to remove images.
    Shift-click the X in the image list in the UV editor.  That should unlink and thus
    orphan them.  From there, you can use this tool to get rid of the images just like
    you would any other resource.
    """
    
    import bpy, random, time
    from collections import namedtuple
    
    
    mod_data = [tuple(["actions"]*3),
                tuple(["armatures"]*3),
                tuple(["brushes"]*3),
                tuple(["cameras"]*3),
                tuple(["curves"]*3),
                tuple(["fonts"]*3),
                tuple(["grease_pencil"]*3),
                tuple(["groups"]*3),
                tuple(["images"]*3),
                tuple(["lamps"]*3),
                tuple(["lattices"]*3),
                tuple(["libraries"]*3),
                tuple(["linestyles"]*3),
                tuple(["materials"]*3),
                tuple(["masks"]*3),
                tuple(["meshes"]*3),
                tuple(["metaballs"]*3),
                tuple(["movieclips"]*3),
                tuple(["node_groups"]*3),
                tuple(["objects"]*3),
                tuple(["particles"]*3),
                tuple(["sounds"]*3),
                tuple(["scenes"]*3),
                tuple(["speakers"]*3),
                tuple(["texts"]*3),
                tuple(["textures"]*3),
                tuple(["worlds"]*3),
                tuple(["everything"]*3),
    ]
    
    
    
    class DeleteOrphansOp(bpy.types.Operator):
        '''Remove all orphaned objects of a selected type from the project'''
        bl_idname="ba.delete_data_obs"
        bl_label="Delete Orphans"
        
        def execute(self, context):    
            
            target = context.scene.mod_list
            every_block_name = 
    [list(x)[0] for x in bpy.types.Scene.mod_list[1]["items"] 
                            if list(x)[0] != "everything"]
            
            def _delete_orphans(target_coll):
                DeletionStats = namedtuple("DeletionStats", ["num_deleted", "num_kept"])
                num_deleted = len([x for x in target_coll if x.users==0])
                num_kept = len([x for x in target_coll if x.users==1])
    
                for item in target_coll:
                    if item.users == 0:
                        target_coll.remove(item)
    
                return DeletionStats(num_deleted, num_kept)
    
            num_deleted, num_kept = 0, 0
            if target == "everything":
                for block_name in every_block_name:
                    target_coll = eval("bpy.data.{}".format(block_name))
                    deleted, kept = _delete_orphans(target_coll)
                    num_deleted += deleted
                    num_kept += kept
    
            else:
                target_coll = eval("bpy.data." + target)
                num_deleted, num_kept = _delete_orphans(target_coll)
            
            msg = "Removed %d orphaned %s objects. Kept %d non-orphans" % (num_deleted, target,
                                                                num_kept)
            self.report( { 'INFO' }, msg  )
            return {'FINISHED'}
        
    
    class OrphanCleanupPanel( bpy.types.Panel ):
        '''Main Panel for Orphan Cleanup script'''
        bl_label = "Orphan Cleanup"
        bl_space_type = "VIEW_3D"
        bl_region_type = "TOOLS"
        bl_context = "objectmode"
        
        def draw( self, context ):
            scn = context.scene
            layout = self.layout
            new_col = self.layout.column
            
            new_col().column().prop(scn, "mod_list")
            new_col().column().operator("ba.delete_data_obs")
            
            
            
        
    
    def register():
        #set_trace()
        #screen_names = [ (screen.name, screen.name, screen.name ) 
        #                    for screen in bpy.data.screens ]
        #bpy.types.Scene.screen_names = bpy.props.EnumProperty(name="Views",
        #                        items=screen_names,
        #                        description = "Possible views to delete"
        #)
        bpy.types.Scene.mod_list = bpy.props.EnumProperty(name="Target", 
                               items=mod_data, 
                               description="Module choice made for orphan deletion")
    
        bpy.utils.register_class(DeleteOrphansOp)
        bpy.utils.register_class(OrphanCleanupPanel)
        
    
    def unregister():
        bpy.utils.unregister_class(OrphanCleanupPanel)
        bpy.utils.unregister_class(DeleteOrphansOp)
    
    
    if __name__ == "__main__":
        register()



Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •