[Bf-extensions-cvs] [e74f7ad9] blender-v2.90-release: BlenderKit: fix appending of assets

Vilém Duha noreply at git.blender.org
Tue Aug 4 13:36:14 CEST 2020


Commit: e74f7ad92d166cd087e3cab1e2ff14936215d036
Author: Vilém Duha
Date:   Sat Aug 1 20:15:33 2020 +0200
Branches: blender-v2.90-release
https://developer.blender.org/rBAe74f7ad92d166cd087e3cab1e2ff14936215d036

BlenderKit: fix appending of assets

This would unnecessarily create full copies instead of linked objects (as linked data, not linked from outer file)

===================================================================

M	blenderkit/download.py

===================================================================

diff --git a/blenderkit/download.py b/blenderkit/download.py
index a93611c0..545b06f2 100644
--- a/blenderkit/download.py
+++ b/blenderkit/download.py
@@ -316,6 +316,18 @@ def append_asset(asset_data, **kwargs):  # downloaders=[], location=None,
                 al = 'LINK'
             else:
                 al = 'APPEND'
+                if asset_data['assetType'] == 'model':
+                    source_parent = get_asset_in_scene(asset_data)
+                    parent, new_obs = duplicate_asset(source=source_parent, **kwargs)
+                    parent.location = kwargs['model_location']
+                    parent.rotation_euler = kwargs['model_rotation']
+                    # this is a case where asset is already in scene and should be duplicated instead.
+                    # there is a big chance that the duplication wouldn't work perfectly(hidden or unselectable objects)
+                    # so here we need to check and return if there was success
+                    # also, if it was successful, no other operations are needed , basically all asset data is already ready from the original asset
+                    if new_obs:
+                        bpy.ops.wm.undo_push_context(message='add %s to scene' % asset_data['name'])
+                        return
 
         # first get conditions for append link
         link = al == 'LINK'
@@ -333,7 +345,7 @@ def append_asset(asset_data, **kwargs):  # downloaders=[], location=None,
                     return
 
                 if link:
-                    parent, newobs = append_link.link_collection(file_names[-1],
+                    parent, new_obs = append_link.link_collection(file_names[-1],
                                                                  location=downloader['location'],
                                                                  rotation=downloader['rotation'],
                                                                  link=link,
@@ -342,7 +354,7 @@ def append_asset(asset_data, **kwargs):  # downloaders=[], location=None,
 
                 else:
 
-                    parent, newobs = append_link.append_objects(file_names[-1],
+                    parent, new_obs = append_link.append_objects(file_names[-1],
                                                                 location=downloader['location'],
                                                                 rotation=downloader['rotation'],
                                                                 link=link,
@@ -356,21 +368,21 @@ def append_asset(asset_data, **kwargs):  # downloaders=[], location=None,
 
         elif kwargs.get('model_location') is not None:
             if link:
-                parent, newobs = append_link.link_collection(file_names[-1],
+                parent, new_obs = append_link.link_collection(file_names[-1],
                                                              location=kwargs['model_location'],
                                                              rotation=kwargs['model_rotation'],
                                                              link=link,
                                                              name=asset_data['name'],
                                                              parent=kwargs.get('parent'))
             else:
-                parent, newobs = append_link.append_objects(file_names[-1],
+                parent, new_obs = append_link.append_objects(file_names[-1],
                                                             location=kwargs['model_location'],
                                                             rotation=kwargs['model_rotation'],
                                                             link=link,
                                                             name=asset_data['name'],
                                                             parent=kwargs.get('parent'))
 
-            #scale Empty for assets, so they don't clutter the scene.
+            # scale Empty for assets, so they don't clutter the scene.
             if parent.type == 'EMPTY' and link:
                 bmin = asset_data['bbox_min']
                 bmax = asset_data['bbox_max']
@@ -733,6 +745,66 @@ def try_finished_append(asset_data, **kwargs):  # location=None, material_target
     return done
 
 
+def get_asset_in_scene(asset_data):
+    '''tries to find an appended copy of particular asset and duplicate it - so it doesn't have to be appended again.'''
+    scene = bpy.context.scene
+    for ob in bpy.context.scene.objects:
+        ad1 = ob.get('asset_data')
+        if not ad1:
+            continue
+        if ad1.get('assetBaseId') == asset_data['assetBaseId']:
+            return ob
+    return None
+
+
+def check_all_visible(obs):
+    '''checks all objects are visible, so they can be manipulated/copied.'''
+    for ob in obs:
+        if not ob.visible_get():
+            return False
+    return True
+
+
+def check_selectible(obs):
+    '''checks if all objects can be selected and selects them if possible.
+     this isn't only select_hide, but all possible combinations of collections e.t.c. so hard to check otherwise.'''
+    for ob in obs:
+        ob.select_set(True)
+        if not ob.select_get():
+            return False
+    return True
+
+
+def duplicate_asset(source, **kwargs):
+    '''Duplicate asset when it's already appended in the scene, so that blender's append doesn't create duplicated data.'''
+
+    # we need to save selection
+    sel = utils.selection_get()
+    bpy.ops.object.select_all(action='DESELECT')
+
+    # check visibility
+    obs = utils.get_hierarchy(source)
+    if not check_all_visible(obs):
+        return None
+    # check selectability and select in one run
+    if not check_selectible(obs):
+        return None
+
+    # duplicate the asset objects
+    bpy.ops.object.duplicate(linked=True)
+
+
+    nobs = bpy.context.selected_objects[:]
+    #get parent
+    for ob in nobs:
+        if ob.parent not in nobs:
+            parent = ob
+            break
+    # restore original selection
+    utils.selection_set(sel)
+    return parent , nobs
+
+
 def asset_in_scene(asset_data):
     '''checks if the asset is already in scene. If yes, modifies asset data so the asset can be reached again.'''
     scene = bpy.context.scene
@@ -746,10 +818,10 @@ def asset_in_scene(asset_data):
             asset_data['file_name'] = ad['file_name']
             asset_data['url'] = ad['url']
 
-            #browse all collections since linked collections can have same name.
+            # browse all collections since linked collections can have same name.
             for c in bpy.data.collections:
                 if c.name == ad['name']:
-                    #there can also be more linked collections with same name, we need to check id.
+                    # there can also be more linked collections with same name, we need to check id.
                     if c.library and c.library.get('asset_data') and c.library['asset_data']['assetBaseId'] == id:
                         return 'LINKED'
             return 'APPENDED'



More information about the Bf-extensions-cvs mailing list