Common function for actually deleting an object from the blend_data.
authorLukas Tönne <lukas.toenne@gmail.com>
Wed, 10 Dec 2014 13:53:51 +0000 (14:53 +0100)
committerLukas Tönne <lukas.toenne@gmail.com>
Wed, 10 Dec 2014 13:53:51 +0000 (14:53 +0100)
This replaces previous limited functions for clearing groups, which is
less reliable and fails in corner cases.

object_physics_meadow/blob.py
object_physics_meadow/patch.py
object_physics_meadow/util.py

index b16bc83..75e261c 100644 (file)
@@ -42,24 +42,9 @@ def blob_objects(context):
 def blob_group_clear(context):
     settings = _settings.get(context)
     blob_group = settings.blob_group(context)
-    scene = context.scene
     
-    if not blob_group:
-        return
-    
-    # local list copy to avoid messing up the iterator
-    objects = [ob for ob in blob_group.objects]
-    
-    for ob in objects:
-        scene.objects.unlink(ob)
-        blob_group.objects.unlink(ob)
-        
-        # note: this can fail if something still references the object
-        # we try to unlink own pointers above, but users might add own
-        if ob.users == 0:
-            bpy.data.objects.remove(ob)
-        else:
-            print("Warning: could not remove object %r" % ob.name)
+    if blob_group:
+        delete_objects(context, blob_group.objects)
 
 def blob_group_assign(context, blobob):
     settings = _settings.get(context)
@@ -256,8 +241,6 @@ def setup_blob_duplis(context, groundob, display_radius):
     global blobs
     assert(blobs)
     
-    scene = context.scene
-    
     groundob.data.calc_tessface()
     patches = [ob for ob in patch_objects(context) if blobs[ob.meadow.blob_index] is not None]
     
@@ -297,8 +280,5 @@ def setup_blob_duplis(context, groundob, display_radius):
                 # move to the blob center
                 ob.matrix_world = Matrix.Translation(blob.loc)
         
-    # unlink unused patch objects
-    # (does not delete them, but removes from the scene)
-    while del_patches:
-        ob = del_patches.pop()
-        scene.objects.unlink(ob)
+    # delete unused patch objects
+    delete_objects(context, del_patches)
index bf41840..f00c274 100644 (file)
@@ -25,13 +25,6 @@ from bpy_extras import object_utils
 from object_physics_meadow import settings as _settings
 from object_physics_meadow.util import *
 
-# supported relation types between patch objects
-# yields (data, property) pairs to object pointer properties
-def object_relations(ob):
-    for md in ob.modifiers:
-        if md.type == 'PARTICLE_INSTANCE':
-            yield md, "object"
-
 #-----------------------------------------------------------------------
 
 def patch_objects(context):
@@ -43,29 +36,9 @@ def patch_objects(context):
 def patch_group_clear(context):
     settings = _settings.get(context)
     patch_group = settings.patch_group(context)
-    scene = context.scene
-    
-    if not patch_group:
-        return
     
-    # local list copy to avoid messing up the iterator
-    objects = [ob for ob in patch_group.objects]
-    
-    # unlink objects to avoid invalid pointers when deleting them
-    for ob in objects:
-        for data, prop in object_relations(ob):
-            setattr(data, prop, None)
-    
-    for ob in objects:
-        scene.objects.unlink(ob)
-        patch_group.objects.unlink(ob)
-        
-        # note: this can fail if something still references the object
-        # we try to unlink own pointers above, but users might add own
-        if ob.users == 0:
-            bpy.data.objects.remove(ob)
-        else:
-            print("Warning: could not remove object %r" % ob.name)
+    if patch_group:
+        delete_objects(context, patch_group.objects)
 
 def patch_group_assign(context, patchob):
     settings = _settings.get(context)
index b2e8998..3437bf3 100644 (file)
@@ -48,6 +48,46 @@ def select_single_object(ob):
 
 #-----------------------------------------------------------------------
 
+# supported relation types between patch objects
+# yields (data, property) pairs to object pointer properties
+def object_relations(ob):
+    for md in ob.modifiers:
+        if md.type == 'PARTICLE_INSTANCE':
+            yield md, "object"
+
+def delete_objects(context, objects):
+    scene = context.scene
+    
+    obset = set(objects)
+    
+    while obset:
+        ob = obset.pop()
+        
+        #remove from groups
+        for g in bpy.data.groups:
+            if ob in g.objects.values():
+                g.objects.unlink(ob)
+        
+        # unlink from other objects
+        for relob in bpy.data.objects:
+            for data, prop in object_relations(relob):
+                if getattr(data, prop, None) == ob:
+                    setattr(data, prop, None)
+        
+        # unlink from scenes
+        for scene in bpy.data.scenes:
+            if ob in scene.objects.values():
+                scene.objects.unlink(ob)
+        
+        # note: this can fail if something still references the object
+        # we try to unlink own pointers above, but users might add own
+        if ob.users == 0:
+            bpy.data.objects.remove(ob)
+        else:
+            print("Warning: could not remove object %r" % ob.name)
+
+#-----------------------------------------------------------------------
+
 class Profiling():
     def __init__(self, name):
         self.name = name