BlenderKit: fix replace model, was broken.

-should also WIP work in selected model panel.
-deleted commented out filtering code
This commit is contained in:
Vilém Duha 2020-06-24 10:20:23 +02:00
parent 8bf7c77ca0
commit 903a0f01b5
6 changed files with 95 additions and 43 deletions

View File

@ -1600,6 +1600,8 @@ class BlenderKitAddonPreferences(AddonPreferences):
layout.prop(self, "max_assetbar_rows")
layout.prop(self, "tips_on_start")
layout.prop(self, "search_in_header")
if bpy.context.preferences.view.show_developer_ui:
layout.prop(self, "use_timers")
# registration

View File

@ -282,7 +282,6 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None,
#
scene = bpy.context.scene
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
if user_preferences.api_key == '':
@ -306,12 +305,12 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None,
sprops.append_link = 'APPEND'
sprops.import_as = 'INDIVIDUAL'
#copy for override
# copy for override
al = sprops.append_link
import_as = sprops.import_as
# set consistency for objects already in scene, otherwise this literally breaks blender :)
ain = asset_in_scene(asset_data)
#override based on history
# override based on history
if ain is not False:
if ain == 'LINKED':
al = 'LINK'
@ -320,7 +319,6 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None,
al = 'APPEND'
import_as = 'INDIVIDUAL'
# first get conditions for append link
link = al == 'LINK'
# then append link
@ -338,11 +336,11 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None,
if sprops.import_as == 'GROUP':
parent, newobs = append_link.link_collection(file_names[-1],
location=downloader['location'],
rotation=downloader['rotation'],
link=link,
name=asset_data['name'],
parent=kwargs.get('parent'))
location=downloader['location'],
rotation=downloader['rotation'],
link=link,
name=asset_data['name'],
parent=kwargs.get('parent'))
else:
parent, newobs = append_link.append_objects(file_names[-1],
@ -360,11 +358,11 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None,
elif kwargs.get('model_location') is not None:
if sprops.import_as == 'GROUP':
parent, newobs = 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'))
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],
location=kwargs['model_location'],
@ -441,7 +439,7 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None,
scene['assets rated'][id] = scene['assets rated'].get(id, False)
parent['asset_data'] = asset_data # TODO remove this??? should write to blenderkit Props?
bpy.ops.wm.undo_push_context(message = 'add %s to scene'% asset_data['name'])
bpy.ops.wm.undo_push_context(message='add %s to scene' % asset_data['name'])
# moving reporting to on save.
# report_use_success(asset_data['id'])
@ -525,7 +523,7 @@ def timer_update(): # TODO might get moved to handle all blenderkit stuff, not
def download_file(asset_data):
#this is a simple non-threaded way to download files for background resolution genenration tool
# this is a simple non-threaded way to download files for background resolution genenration tool
file_name = paths.get_download_filenames(asset_data)[0] # prefer global dir if possible.
if check_existing(asset_data):
@ -552,6 +550,7 @@ def download_file(asset_data):
f.write(data)
return file_name
class Downloader(threading.Thread):
def __init__(self, asset_data, tcom, scene_id, api_key):
super(Downloader, self).__init__()
@ -883,6 +882,11 @@ class BlenderkitDownloadOperator(bpy.types.Operator):
)
asset_index: IntProperty(name="Asset Index", description='asset index in search results', default=-1)
asset_base_id: StringProperty(
name="Asset base Id",
description="Asset base id, used instead of search result index.",
default="")
target_object: StringProperty(
name="Target Object",
description="Material or object target for replacement",
@ -905,14 +909,23 @@ class BlenderkitDownloadOperator(bpy.types.Operator):
def execute(self, context):
s = bpy.context.scene
sr = s['search results']
asset_data = sr[self.asset_index].to_dict() # TODO CHECK ALL OCCURRENCES OF PASSING BLENDER ID PROPS TO THREADS!
if self.asset_index > -1:
# either get the data from search results
sr = s['search results']
asset_data = sr[
self.asset_index].to_dict() # TODO CHECK ALL OCCURRENCES OF PASSING BLENDER ID PROPS TO THREADS!
asset_base_id = asset_data['assetBaseId']
else:
# or from the scene.
asset_base_id = self.asset_base_id
au = s.get('assets used')
if au == None:
s['assets used'] = {}
if asset_data['assetBaseId'] in s.get('assets used'):
asset_data = s['assets used'][asset_data['assetBaseId']].to_dict()
if asset_base_id in s.get('assets used'):
# already used assets have already download link and especially file link.
asset_data = s['assets used'][asset_base_id].to_dict()
atype = asset_data['assetType']
if bpy.context.mode != 'OBJECT' and (
@ -920,9 +933,16 @@ class BlenderkitDownloadOperator(bpy.types.Operator):
bpy.ops.object.mode_set(mode='OBJECT')
if self.replace: # cleanup first, assign later.
obs = utils.get_selected_models()
obs = utils.get_selected_replace_adepts()
print(obs)
for ob in obs:
print('replace attempt ', ob.name)
if self.asset_base_id != '':
# this is for a case when replace is called from a panel, this makes the first of the objects not replacable.
if ob.get('asset_data') is not None and ob['asset_data']['assetBaseId'] == self.asset_base_id:
print('skipping this oneli')
continue;
kwargs = {
'cast_parent': self.cast_parent,
'target_object': ob.name,

View File

@ -262,7 +262,7 @@ def parse_result(r):
#attempt to switch to use original data gradually, since the parsing as itself should become obsolete.
asset_data.update(r)
return asset_data
return asset_data
# @bpy.app.handlers.persistent
@ -338,7 +338,8 @@ def timer_update():
bpy.ops.object.run_assetbar_fix_context()
for r in rdata['results']:
asset_data = parse_result(r)
result_field.append(asset_data)
if asset_data != None:
result_field.append(asset_data)
# results = rdata['results']
s[search_name] = result_field
@ -884,21 +885,6 @@ class Searcher(threading.Thread):
mt('data parsed ')
# filter results here:
# todo remove this in future
# nresults = []
# for d in rdata.get('results', []):
# # TODO this code is for filtering brush types, should vanish after we implement filter in Elastic
# mode = None
# if query['asset_type'] == 'brush':
# for p in d['parameters']:
# if p['parameterType'] == 'mode':
# mode = p['value']
# if query['asset_type'] != 'brush' or (
# query.get('mode') != None and query['mode']) == mode:
# nresults.append(d)
# rdata['results'] = nresults
# print('number of results: ', len(rdata.get('results', [])))
if self.stopped():
utils.p('stopping search : ' + str(query))

View File

@ -435,7 +435,7 @@ class VIEW3D_PT_blenderkit_model_properties(Panel):
layout.label(text=str(ad['name']))
if o.instance_type == 'COLLECTION' and o.instance_collection is not None:
layout.operator('object.blenderkit_bring_to_scene', text='Bring to scene')
layout.label(text='Ratings:')
draw_panel_model_rating(self, context)
draw_asset_context_menu(self, context, ad)
@ -934,8 +934,17 @@ def draw_asset_context_menu(self, context, asset_data):
if aob is None:
aob = bpy.context.selected_objects[0]
op = layout.operator('scene.blenderkit_download', text='Replace Active Models')
#this checks if the menu got called from right-click in assetbar(then index is 0 - x) or
# from a panel(then replacement happens from the active model)
if ui_props.active_index == -3:
#called from addon panel
o = utils.get_active_model()
op.asset_base_id = o['asset_data']['assetBaseId']
else:
op.asset_index = ui_props.active_index
op.asset_type = ui_props.asset_type
op.asset_index = ui_props.active_index
op.model_location = aob.location
op.model_rotation = aob.rotation_euler
op.target_object = aob.name
@ -982,7 +991,6 @@ class OBJECT_MT_blenderkit_asset_menu(bpy.types.Menu):
bl_idname = "OBJECT_MT_blenderkit_asset_menu"
def draw(self, context):
ui_props = context.scene.blenderkitUI
# sr = bpy.context.scene['search results']

View File

@ -838,6 +838,7 @@ class AssetVerificationStatusChange(Operator):
if self.state == 'deleted':
wm = context.window_manager
return wm.invoke_props_dialog(self)
return {'RUNNING_MODAL'}
def register_upload():

View File

@ -77,12 +77,18 @@ def get_active_model():
def get_selected_models():
'''
Detect all hierarchies that contain asset data from selection. Only parents that have actual ['asset data'] get returned
Returns
list of objects containing asset data.
'''
obs = bpy.context.selected_objects[:]
done = {}
parents = []
for ob in obs:
if ob not in done:
while ob.parent is not None and ob not in done and ob.blenderkit.asset_base_id != '' and ob.instance_collection is not None:
while ob.parent is not None and ob not in done and ob.blenderkit.asset_base_id == '' and ob.instance_collection is None:
done[ob] = True
ob = ob.parent
@ -96,6 +102,35 @@ def get_selected_models():
parents = obs
return parents
def get_selected_replace_adepts():
'''
Detect all hierarchies that contain either asset data from selection, or selected objects themselves.
Returns
list of objects for replacement.
'''
obs = bpy.context.selected_objects[:]
done = {}
parents = []
for selected_ob in obs:
ob = selected_ob
if ob not in done:
while ob.parent is not None and ob not in done and ob.blenderkit.asset_base_id == '' and ob.instance_collection is None:
done[ob] = True
# print('step,',ob.name)
ob = ob.parent
# print('fin', ob.name)
if ob not in parents and ob not in done:
if ob.blenderkit.name != '' or ob.instance_collection is not None:
parents.append(ob)
done[ob] = True
# print(parents)
#if no blenderkit - like objects were found, use the original selection.
if len(parents) == 0:
parents = obs
return parents
def get_search_props():
scene = bpy.context.scene