Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVilém Duha <vilda.novak@gmail.com>2020-08-01 21:15:33 +0300
committerVilém Duha <vilda.novak@gmail.com>2020-08-04 14:35:48 +0300
commite74f7ad92d166cd087e3cab1e2ff14936215d036 (patch)
tree6f2804f497bb11b573fe11b384885af3dd3d7355
parent9adfdc230051f15db24a8bc32c4828e57353513f (diff)
BlenderKit: fix appending of assets
This would unnecessarily create full copies instead of linked objects (as linked data, not linked from outer file)
-rw-r--r--blenderkit/download.py86
1 files changed, 79 insertions, 7 deletions
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'