Merge branch 'blender-v2.92-release'
This commit is contained in:
commit
9d30d2bccb
|
@ -138,7 +138,10 @@ from bpy.types import (
|
|||
|
||||
@persistent
|
||||
def scene_load(context):
|
||||
print('loading in background')
|
||||
print(bpy.context.window_manager)
|
||||
if not bpy.app.background:
|
||||
|
||||
search.load_previews()
|
||||
ui_props = bpy.context.scene.blenderkitUI
|
||||
ui_props.assetbar_on = False
|
||||
|
@ -249,37 +252,39 @@ thumbnail_resolutions = (
|
|||
def udate_down_up(self, context):
|
||||
"""Perform a search if results are empty."""
|
||||
s = context.scene
|
||||
wm = bpy.context.window_manager
|
||||
props = s.blenderkitUI
|
||||
if s['search results'] == None and props.down_up == 'SEARCH':
|
||||
if wm['search results'] == None and props.down_up == 'SEARCH':
|
||||
search.search()
|
||||
|
||||
def switch_search_results(self, context):
|
||||
s = bpy.context.scene
|
||||
wm = bpy.context.window_manager
|
||||
props = s.blenderkitUI
|
||||
if props.asset_type == 'MODEL':
|
||||
s['search results'] = s.get('bkit model search')
|
||||
s['search results orig'] = s.get('bkit model search orig')
|
||||
wm['search results'] = wm.get('bkit model search')
|
||||
wm['search results orig'] = wm.get('bkit model search orig')
|
||||
elif props.asset_type == 'SCENE':
|
||||
s['search results'] = s.get('bkit scene search')
|
||||
s['search results orig'] = s.get('bkit scene search orig')
|
||||
wm['search results'] = wm.get('bkit scene search')
|
||||
wm['search results orig'] = wm.get('bkit scene search orig')
|
||||
elif props.asset_type == 'HDR':
|
||||
s['search results'] = s.get('bkit hdr search')
|
||||
s['search results orig'] = s.get('bkit hdr search orig')
|
||||
wm['search results'] = wm.get('bkit hdr search')
|
||||
wm['search results orig'] = wm.get('bkit hdr search orig')
|
||||
elif props.asset_type == 'MATERIAL':
|
||||
s['search results'] = s.get('bkit material search')
|
||||
s['search results orig'] = s.get('bkit material search orig')
|
||||
wm['search results'] = wm.get('bkit material search')
|
||||
wm['search results orig'] = wm.get('bkit material search orig')
|
||||
elif props.asset_type == 'TEXTURE':
|
||||
s['search results'] = s.get('bkit texture search')
|
||||
s['search results orig'] = s.get('bkit texture search orig')
|
||||
wm['search results'] = wm.get('bkit texture search')
|
||||
wm['search results orig'] = wm.get('bkit texture search orig')
|
||||
elif props.asset_type == 'BRUSH':
|
||||
s['search results'] = s.get('bkit brush search')
|
||||
s['search results orig'] = s.get('bkit brush search orig')
|
||||
wm['search results'] = wm.get('bkit brush search')
|
||||
wm['search results orig'] = wm.get('bkit brush search orig')
|
||||
if not(context.sculpt_object or context.image_paint_object):
|
||||
ui.add_report(
|
||||
'Switch to paint or sculpt mode to search in BlenderKit brushes.')
|
||||
|
||||
search.load_previews()
|
||||
if s['search results'] == None and props.down_up == 'SEARCH':
|
||||
if wm['search results'] == None and props.down_up == 'SEARCH':
|
||||
search.search()
|
||||
|
||||
|
||||
|
@ -577,16 +582,11 @@ def name_update(self, context):
|
|||
def update_free(self, context):
|
||||
if self.is_free == False:
|
||||
self.is_free = True
|
||||
title = "All BlenderKit materials are free"
|
||||
message = "Any material uploaded to BlenderKit is free." \
|
||||
ui_panels.ui_message(title = "All BlenderKit materials are free",
|
||||
message = "Any material uploaded to BlenderKit is free." \
|
||||
" However, it can still earn money for the author," \
|
||||
" based on our fair share system. " \
|
||||
"Part of subscription is sent to artists based on usage by paying users."
|
||||
|
||||
def draw_message(self, context):
|
||||
utils.label_multiline(self.layout, text=message, icon='NONE', width=-1)
|
||||
|
||||
bpy.context.window_manager.popup_menu(draw_message, title=title, icon='INFO')
|
||||
"Part of subscription is sent to artists based on usage by paying users.")
|
||||
|
||||
|
||||
class BlenderKitCommonUploadProps(object):
|
||||
|
@ -1512,15 +1512,11 @@ def fix_subdir(self, context):
|
|||
if self.project_subdir != pp:
|
||||
self.project_subdir = pp
|
||||
|
||||
title = "Fixed to relative path"
|
||||
message = "This path should be always realative.\n" \
|
||||
" It's a directory BlenderKit creates where your .blend is \n " \
|
||||
"and uses it for storing assets."
|
||||
ui_panels.ui_message(title = "Fixed to relative path",
|
||||
message = "This path should be always realative.\n" \
|
||||
" It's a directory BlenderKit creates where your .blend is \n " \
|
||||
"and uses it for storing assets.")
|
||||
|
||||
def draw_message(self, context):
|
||||
utils.label_multiline(self.layout, text=message, icon='NONE', width=400)
|
||||
|
||||
bpy.context.window_manager.popup_menu(draw_message, title=title, icon='INFO')
|
||||
|
||||
|
||||
class BlenderKitAddonPreferences(AddonPreferences):
|
||||
|
|
|
@ -25,8 +25,8 @@ from bpy.props import (
|
|||
|
||||
def draw_callback_tooltip(self, context):
|
||||
if self.draw_tooltip:
|
||||
s = bpy.context.scene
|
||||
sr = s.get('search results')
|
||||
wm = bpy.context.window_manager
|
||||
sr = wm.get('search results')
|
||||
r = sr[self.active_index]
|
||||
ui.draw_tooltip_with_author(r, 0, 500)
|
||||
|
||||
|
@ -269,7 +269,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
self.wcount = math.floor(
|
||||
(self.bar_width) / (self.button_size))
|
||||
|
||||
search_results = bpy.context.scene.get('search results')
|
||||
search_results = bpy.context.window_manager.get('search results')
|
||||
if search_results is not None and self.wcount > 0:
|
||||
self.hcount = min(user_preferences.max_assetbar_rows, math.ceil(len(search_results) / self.wcount))
|
||||
else:
|
||||
|
@ -311,8 +311,6 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
self.panel = BL_UI_Drag_Panel(0, 0, self.bar_width, self.bar_height)
|
||||
self.panel.bg_color = (0.0, 0.0, 0.0, 0.5)
|
||||
|
||||
sr = bpy.context.scene['search results']
|
||||
|
||||
for a in range(0, self.wcount):
|
||||
for b in range(0, self.hcount):
|
||||
asset_x = self.assetbar_margin + a * (self.button_size)
|
||||
|
@ -478,7 +476,8 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
|
||||
if self.active_index != widget.search_index:
|
||||
scene = bpy.context.scene
|
||||
sr = scene['search results']
|
||||
wm = bpy.context.window_manager
|
||||
sr = wm['search results']
|
||||
asset_data = sr[widget.search_index + self.scroll_offset]
|
||||
|
||||
self.active_index = widget.search_index
|
||||
|
@ -514,11 +513,12 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_asset_menu')
|
||||
|
||||
def search_more(self):
|
||||
sro = bpy.context.scene.get('search results orig')
|
||||
sro = bpy.context.window_manager.get('search results orig')
|
||||
if sro is not None and sro.get('next') is not None:
|
||||
blenderkit.search.search(get_next=True)
|
||||
|
||||
def update_images(self):
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
|
||||
for asset_button in self.asset_buttons:
|
||||
asset_button.asset_index = asset_button.button_index + self.scroll_offset
|
||||
|
@ -548,7 +548,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
asset_button.validation_icon.visible = False
|
||||
|
||||
def scroll_update(self):
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
self.scroll_offset = min(self.scroll_offset, len(sr) - (self.wcount * self.hcount))
|
||||
self.scroll_offset = max(self.scroll_offset, 0)
|
||||
self.update_images()
|
||||
|
@ -556,7 +556,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
self.search_more()
|
||||
|
||||
def search_by_author(self, asset_index):
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = sr[asset_index]
|
||||
a = asset_data['author']['id']
|
||||
if a is not None:
|
||||
|
@ -573,12 +573,10 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
return False
|
||||
|
||||
def scroll_up(self, widget):
|
||||
sr = bpy.context.scene['search results']
|
||||
self.scroll_offset += self.wcount * self.hcount
|
||||
self.scroll_update()
|
||||
|
||||
def scroll_down(self, widget):
|
||||
sr = bpy.context.scene['search results']
|
||||
self.scroll_offset -= self.wcount * self.hcount
|
||||
self.scroll_update()
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
|
||||
from blenderkit import paths, utils, bg_blender
|
||||
from blenderkit import paths, utils, bg_blender, ui_panels
|
||||
|
||||
import tempfile, os, subprocess, json, sys
|
||||
|
||||
|
@ -262,13 +262,10 @@ class GenerateThumbnailOperator(bpy.types.Operator):
|
|||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
if bpy.data.filepath == '':
|
||||
title = "Can't render thumbnail"
|
||||
message = "please save your file first"
|
||||
ui_panels.ui_message(
|
||||
title = "Can't render thumbnail",
|
||||
message = "please save your file first")
|
||||
|
||||
def draw_message(self, context):
|
||||
self.layout.label(text=message)
|
||||
|
||||
bpy.context.window_manager.popup_menu(draw_message, title=title, icon='INFO')
|
||||
return {'FINISHED'}
|
||||
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
|
|
@ -87,7 +87,7 @@ def write_tokens(auth_token, refresh_token, oauth_response):
|
|||
props.report = ''
|
||||
ui.add_report('BlenderKit Re-Login success')
|
||||
search.get_profile()
|
||||
categories.fetch_categories_thread(auth_token)
|
||||
categories.fetch_categories_thread(auth_token, force = False)
|
||||
|
||||
|
||||
class RegisterLoginOnline(bpy.types.Operator):
|
||||
|
|
|
@ -28,6 +28,7 @@ import time
|
|||
import shutil
|
||||
import threading
|
||||
import logging
|
||||
|
||||
bk_logger = logging.getLogger('blenderkit')
|
||||
|
||||
|
||||
|
@ -95,6 +96,7 @@ def get_category(categories, cat_path=()):
|
|||
return (c)
|
||||
break;
|
||||
|
||||
|
||||
# def get_upload_asset_type(self):
|
||||
# typemapper = {
|
||||
# bpy.types.Object.blenderkit: 'model',
|
||||
|
@ -106,15 +108,16 @@ def get_category(categories, cat_path=()):
|
|||
# asset_type = typemapper[type(self)]
|
||||
# return asset_type
|
||||
|
||||
def update_category_enums(self,context):
|
||||
def update_category_enums(self, context):
|
||||
'''Fixes if lower level is empty - sets it to None, because enum value can be higher.'''
|
||||
enums = get_subcategory_enums(self,context)
|
||||
enums = get_subcategory_enums(self, context)
|
||||
if enums[0][0] == 'NONE' and self.subcategory != 'NONE':
|
||||
self.subcategory = 'NONE'
|
||||
|
||||
def update_subcategory_enums(self,context):
|
||||
|
||||
def update_subcategory_enums(self, context):
|
||||
'''Fixes if lower level is empty - sets it to None, because enum value can be higher.'''
|
||||
enums = get_subcategory1_enums(self,context)
|
||||
enums = get_subcategory1_enums(self, context)
|
||||
if enums[0][0] == 'NONE' and self.subcategory1 != 'NONE':
|
||||
self.subcategory1 = 'NONE'
|
||||
|
||||
|
@ -132,10 +135,11 @@ def get_category_enums(self, context):
|
|||
items.append(('NONE', '', 'no categories on this level defined'))
|
||||
return items
|
||||
|
||||
|
||||
def get_subcategory_enums(self, context):
|
||||
wm = bpy.context.window_manager
|
||||
props = bpy.context.scene.blenderkitUI
|
||||
asset_type = props.asset_type.lower()
|
||||
asset_type = props.asset_type.lower()
|
||||
items = []
|
||||
if self.category != '':
|
||||
asset_categories = get_category(wm['bkit_categories'], cat_path=(asset_type, self.category,))
|
||||
|
@ -146,13 +150,14 @@ def get_subcategory_enums(self, context):
|
|||
# print('subcategory', items)
|
||||
return items
|
||||
|
||||
|
||||
def get_subcategory1_enums(self, context):
|
||||
wm = bpy.context.window_manager
|
||||
props = bpy.context.scene.blenderkitUI
|
||||
asset_type = props.asset_type.lower()
|
||||
asset_type = props.asset_type.lower()
|
||||
items = []
|
||||
if self.category != '' and self.subcategory != '':
|
||||
asset_categories = get_category(wm['bkit_categories'], cat_path=(asset_type, self.category, self.subcategory, ))
|
||||
asset_categories = get_category(wm['bkit_categories'], cat_path=(asset_type, self.category, self.subcategory,))
|
||||
if asset_categories:
|
||||
for c in asset_categories['children']:
|
||||
items.append((c['slug'], c['name'], c['description']))
|
||||
|
@ -160,6 +165,7 @@ def get_subcategory1_enums(self, context):
|
|||
items.append(('NONE', '', 'no categories on this level defined'))
|
||||
return items
|
||||
|
||||
|
||||
def copy_categories():
|
||||
# this creates the categories system on only
|
||||
tempdir = paths.get_temp_dir()
|
||||
|
@ -193,11 +199,12 @@ def load_categories():
|
|||
except:
|
||||
print('categories failed to read')
|
||||
|
||||
|
||||
#
|
||||
catfetch_counter = 0
|
||||
|
||||
|
||||
def fetch_categories(API_key, force = False):
|
||||
def fetch_categories(API_key, force=False):
|
||||
url = paths.get_api_url() + 'categories/'
|
||||
|
||||
headers = utils.get_headers(API_key)
|
||||
|
@ -216,14 +223,14 @@ def fetch_categories(API_key, force = False):
|
|||
try:
|
||||
# read categories only once per day maximum, or when forced to do so.
|
||||
if catfile_age > 86400 or force:
|
||||
bk_logger.debug('requesting categories')
|
||||
bk_logger.debug('requesting categories from server')
|
||||
r = rerequests.get(url, headers=headers)
|
||||
rdata = r.json()
|
||||
categories = rdata['results']
|
||||
fix_category_counts(categories)
|
||||
# filter_categories(categories) #TODO this should filter categories for search, but not for upload. by now off.
|
||||
with open(categories_filepath, 'w', encoding = 'utf-8') as s:
|
||||
json.dump(categories, s, ensure_ascii=False, indent=4)
|
||||
with open(categories_filepath, 'w', encoding='utf-8') as s:
|
||||
json.dump(categories, s, ensure_ascii=False, indent=4)
|
||||
tasks_queue.add_task((load_categories, ()))
|
||||
except Exception as e:
|
||||
bk_logger.debug('category fetching failed')
|
||||
|
@ -233,6 +240,6 @@ def fetch_categories(API_key, force = False):
|
|||
shutil.copy(source_path, categories_filepath)
|
||||
|
||||
|
||||
def fetch_categories_thread(API_key, force = False):
|
||||
def fetch_categories_thread(API_key, force=False):
|
||||
cat_thread = threading.Thread(target=fetch_categories, args=([API_key, force]), daemon=True)
|
||||
cat_thread.start()
|
||||
|
|
|
@ -280,7 +280,7 @@ def udpate_asset_data_in_dicts(asset_data):
|
|||
scene['assets rated'] = scene.get('assets rated', {})
|
||||
id = asset_data['assetBaseId']
|
||||
scene['assets rated'][id] = scene['assets rated'].get(id, False)
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
if not sr:
|
||||
return;
|
||||
for i, r in enumerate(sr):
|
||||
|
@ -577,7 +577,7 @@ def timer_update():
|
|||
downloaders = []
|
||||
|
||||
if t.is_alive(): # set downloader size
|
||||
sr = bpy.context.scene.get('search results')
|
||||
sr = bpy.context.window_manager.get('search results')
|
||||
if sr is not None:
|
||||
for r in sr:
|
||||
if asset_data['id'] == r['id']:
|
||||
|
@ -646,8 +646,8 @@ def timer_update():
|
|||
tcom.passargs['retry_counter'] = tcom.passargs.get('retry_counter', 0) + 1
|
||||
download(asset_data, **tcom.passargs)
|
||||
|
||||
if bpy.context.scene['search results'] is not None and done:
|
||||
for sres in bpy.context.scene['search results']:
|
||||
if bpy.context.window_manager['search results'] is not None and done:
|
||||
for sres in bpy.context.window_manager['search results']:
|
||||
if asset_data['id'] == sres['id']:
|
||||
sres['downloaded'] = 100
|
||||
|
||||
|
@ -1282,7 +1282,7 @@ class BlenderkitDownloadOperator(bpy.types.Operator):
|
|||
|
||||
if self.asset_index > -1:
|
||||
# either get the data from search results
|
||||
sr = s['search results']
|
||||
sr = bpy.context.window_manager['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']
|
||||
|
|
|
@ -429,7 +429,7 @@ class FastRateMenu(Operator):
|
|||
scene = bpy.context.scene
|
||||
ui_props = scene.blenderkitUI
|
||||
if ui_props.active_index > -1:
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = dict(sr[ui_props.active_index])
|
||||
self.asset_id = asset_data['id']
|
||||
self.asset_type = asset_data['assetType']
|
||||
|
@ -448,7 +448,7 @@ def rating_menu_draw(self, context):
|
|||
layout = self.layout
|
||||
|
||||
ui_props = context.scene.blenderkitUI
|
||||
sr = bpy.context.scene['search results orig']
|
||||
sr = bpy.context.window_manager['search results orig']
|
||||
|
||||
asset_search_index = ui_props.active_index
|
||||
if asset_search_index > -1:
|
||||
|
|
|
@ -601,7 +601,7 @@ def assets_db_path():
|
|||
|
||||
|
||||
def get_assets_search():
|
||||
bpy.app.debug_value = 2
|
||||
# bpy.app.debug_value = 2
|
||||
|
||||
results = []
|
||||
preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
|
|
|
@ -144,6 +144,24 @@ def update_assets_data(): # updates assets data on scene load.
|
|||
# bpy.context.scene['assets used'][ad] = ad
|
||||
|
||||
|
||||
def purge_search_results():
|
||||
''' clean up search results on save/load.'''
|
||||
|
||||
s = bpy.context.scene
|
||||
|
||||
sr_props = [
|
||||
'search results',
|
||||
'search results orig',
|
||||
]
|
||||
asset_types = ['model', 'material', 'scene', 'hdr', 'brush']
|
||||
for at in asset_types:
|
||||
sr_props.append('bkit {at} search')
|
||||
sr_props.append('bkit {at} search orig')
|
||||
for sr_prop in sr_props:
|
||||
if s.get(sr_prop):
|
||||
del (s[sr_prop])
|
||||
|
||||
|
||||
@persistent
|
||||
def scene_load(context):
|
||||
'''
|
||||
|
@ -151,6 +169,7 @@ def scene_load(context):
|
|||
Should (probably)also update asset data from server (after user consent)
|
||||
'''
|
||||
wm = bpy.context.window_manager
|
||||
purge_search_results()
|
||||
fetch_server_data()
|
||||
categories.load_categories()
|
||||
if not bpy.app.timers.is_registered(refresh_token_timer):
|
||||
|
@ -171,7 +190,7 @@ def fetch_server_data():
|
|||
if api_key != '' and bpy.context.window_manager.get('bkit profile') == None:
|
||||
get_profile()
|
||||
if bpy.context.window_manager.get('bkit_categories') is None:
|
||||
categories.fetch_categories_thread(api_key)
|
||||
categories.fetch_categories_thread(api_key, force = False)
|
||||
|
||||
|
||||
first_time = True
|
||||
|
@ -218,7 +237,7 @@ def parse_result(r):
|
|||
# except:
|
||||
# utils.p('asset with no files-size')
|
||||
asset_type = r['assetType']
|
||||
if len(r['files']) > 0:
|
||||
if len(r['files']) > 0:#TODO remove this condition so all assets are parsed.
|
||||
r['available_resolutions'] = []
|
||||
allthumbs = []
|
||||
durl, tname, small_tname = '', '', ''
|
||||
|
@ -323,7 +342,7 @@ def timer_update():
|
|||
first_time = False
|
||||
if preferences.show_on_start:
|
||||
# TODO here it should check if there are some results, and only open assetbar if this is the case, not search.
|
||||
# if bpy.context.scene.get('search results') is None:
|
||||
# if bpy.context.window_manager.get('search results') is None:
|
||||
search()
|
||||
# preferences.first_run = False
|
||||
if preferences.tips_on_start:
|
||||
|
@ -353,7 +372,7 @@ def timer_update():
|
|||
icons_dir = thread[1]
|
||||
scene = bpy.context.scene
|
||||
# these 2 lines should update the previews enum and set the first result as active.
|
||||
s = bpy.context.scene
|
||||
wm = bpy.context.window_manager
|
||||
asset_type = thread[2]
|
||||
if asset_type == 'model':
|
||||
props = scene.blenderkit_models
|
||||
|
@ -372,7 +391,7 @@ def timer_update():
|
|||
# json_filepath = os.path.join(icons_dir, 'brush_searchresult.json')
|
||||
search_name = f'bkit {asset_type} search'
|
||||
|
||||
s[search_name] = []
|
||||
wm[search_name] = []
|
||||
|
||||
global reports
|
||||
if reports != '':
|
||||
|
@ -391,10 +410,10 @@ def timer_update():
|
|||
result_field.append(asset_data)
|
||||
|
||||
# results = rdata['results']
|
||||
s[search_name] = result_field
|
||||
s['search results'] = result_field
|
||||
s[search_name + ' orig'] = copy.deepcopy(rdata)
|
||||
s['search results orig'] = s[search_name + ' orig']
|
||||
wm[search_name] = result_field
|
||||
wm['search results'] = result_field
|
||||
wm[search_name + ' orig'] = copy.deepcopy(rdata)
|
||||
wm['search results orig'] = wm[search_name + ' orig']
|
||||
|
||||
load_previews()
|
||||
ui_props = bpy.context.scene.blenderkitUI
|
||||
|
@ -402,8 +421,8 @@ def timer_update():
|
|||
ui_props.scrolloffset = 0
|
||||
props.is_searching = False
|
||||
props.search_error = False
|
||||
props.report = 'Found %i results. ' % (s['search results orig']['count'])
|
||||
if len(s['search results']) == 0:
|
||||
props.report = 'Found %i results. ' % (wm['search results orig']['count'])
|
||||
if len(wm['search results']) == 0:
|
||||
tasks_queue.add_task((ui.add_report, ('No matching results found.',)))
|
||||
# undo push
|
||||
bpy.ops.wm.undo_push_context(message='Get BlenderKit search')
|
||||
|
@ -425,7 +444,7 @@ def load_previews():
|
|||
props = scene.blenderkitUI
|
||||
directory = paths.get_temp_dir('%s_search' % props.asset_type.lower())
|
||||
s = bpy.context.scene
|
||||
results = s.get('search results')
|
||||
results = bpy.context.window_manager.get('search results')
|
||||
#
|
||||
if results is not None:
|
||||
inames = []
|
||||
|
@ -664,6 +683,8 @@ def generate_tooltip(mdata):
|
|||
t += f"Quality rating: {int(mdata['ratingsAverage']['quality']) * '*'}\n"
|
||||
t += f"Hours saved rating: {int(mdata['ratingsAverage']['workingHours'])}\n"
|
||||
if utils.profile_is_validator():
|
||||
t += f"Score: {int(mdata['score'])}\n"
|
||||
|
||||
t += f"Ratings count {rc['quality']}*/{rc['workingHours']}wh value " \
|
||||
f"{mdata['ratingsAverage']['quality']}*/{mdata['ratingsAverage']['workingHours']}wh\n"
|
||||
if len(t.split('\n')) < 11:
|
||||
|
@ -1256,7 +1277,6 @@ def add_search_process(query, params, orig_result):
|
|||
old_thread[0].stop()
|
||||
# TODO CARE HERE FOR ALSO KILLING THE Thumbnail THREADS.?
|
||||
# AT LEAST NOW SEARCH DONE FIRST WON'T REWRITE AN OLDER ONE
|
||||
|
||||
tempdir = paths.get_temp_dir('%s_search' % query['asset_type'])
|
||||
thread = Searcher(query, params, orig_result)
|
||||
thread.start()
|
||||
|
@ -1311,7 +1331,7 @@ def get_search_simple(parameters, filepath=None, page_size=100, max_results=1000
|
|||
if not filepath:
|
||||
return results
|
||||
|
||||
with open(filepath, 'w', encoding = 'utf-8') as s:
|
||||
with open(filepath, 'w', encoding='utf-8') as s:
|
||||
json.dump(results, s, ensure_ascii=False, indent=4)
|
||||
bk_logger.info(f'retrieved {len(results)} assets from elastic search')
|
||||
return results
|
||||
|
@ -1321,7 +1341,6 @@ def search(category='', get_next=False, author_id=''):
|
|||
''' initialize searching'''
|
||||
global search_start_time
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
|
||||
search_start_time = time.time()
|
||||
# mt('start')
|
||||
scene = bpy.context.scene
|
||||
|
@ -1364,6 +1383,7 @@ def search(category='', get_next=False, author_id=''):
|
|||
props = scene.blenderkit_brush
|
||||
query = build_query_brush()
|
||||
|
||||
# it's possible get_net was requested more than once.
|
||||
if props.is_searching and get_next == True:
|
||||
return;
|
||||
|
||||
|
@ -1395,7 +1415,7 @@ def search(category='', get_next=False, author_id=''):
|
|||
|
||||
# if free_only:
|
||||
# query['keywords'] += '+is_free:true'
|
||||
orig_results = scene.get(f'bkit {ui_props.asset_type.lower()} search orig', {})
|
||||
orig_results = bpy.context.window_manager.get(f'bkit {ui_props.asset_type.lower()} search orig', {})
|
||||
if orig_results != {}:
|
||||
# ensure it's a copy in dict for what we are passing to thread:
|
||||
orig_results = orig_results.to_dict()
|
||||
|
|
123
blenderkit/ui.py
123
blenderkit/ui.py
|
@ -138,10 +138,11 @@ class Report():
|
|||
|
||||
def get_asset_under_mouse(mousex, mousey):
|
||||
s = bpy.context.scene
|
||||
wm = bpy.context.window_manager
|
||||
ui_props = bpy.context.scene.blenderkitUI
|
||||
r = bpy.context.region
|
||||
|
||||
search_results = s.get('search results')
|
||||
search_results = wm.get('search results')
|
||||
if search_results is not None:
|
||||
|
||||
h_draw = min(ui_props.hcount, math.ceil(len(search_results) / ui_props.wcount))
|
||||
|
@ -741,8 +742,8 @@ def draw_asset_bar(self, context):
|
|||
# img,
|
||||
# 1)
|
||||
if not ui_props.dragging and ui_props.hcount > 0 and ui_props.wcount > 0:
|
||||
search_results = s.get('search results')
|
||||
search_results_orig = s.get('search results orig')
|
||||
search_results = bpy.context.window_manager.get('search results')
|
||||
search_results_orig = bpy.context.window_manager.get('search results orig')
|
||||
if search_results == None:
|
||||
return
|
||||
h_draw = min(ui_props.hcount, math.ceil(len(search_results) / ui_props.wcount))
|
||||
|
@ -882,6 +883,19 @@ def draw_callback_3d(self, context):
|
|||
if ui.draw_snapped_bounds:
|
||||
draw_bbox(ui.snapped_location, ui.snapped_rotation, ui.snapped_bbox_min, ui.snapped_bbox_max)
|
||||
|
||||
def object_in_particle_collection(o):
|
||||
'''checks if an object is in a particle system as instance, to not snap to it and not to try to attach material.'''
|
||||
for p in bpy.data.particles:
|
||||
if p.render_type =='COLLECTION':
|
||||
if p.instance_collection:
|
||||
for o1 in p.instance_collection.objects:
|
||||
if o1 == o:
|
||||
return True
|
||||
if p.render_type =='COLLECTION':
|
||||
if p.instance_object == o:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def deep_ray_cast(depsgraph, ray_origin, vec):
|
||||
# this allows to ignore some objects, like objects with bounding box draw style or particle objects
|
||||
|
@ -889,19 +903,22 @@ def deep_ray_cast(depsgraph, ray_origin, vec):
|
|||
# while object is None or object.draw
|
||||
has_hit, snapped_location, snapped_normal, face_index, object, matrix = bpy.context.scene.ray_cast(
|
||||
depsgraph, ray_origin, vec)
|
||||
empty_set = False, Vector((0, 0, 0)), Vector((0, 0, 1)), None, None, None
|
||||
if not object:
|
||||
return False, Vector((0, 0, 0)), Vector((0, 0, 1)), None, None, None
|
||||
return empty_set
|
||||
|
||||
try_object = object
|
||||
while try_object and try_object.display_type == 'BOUNDS':
|
||||
|
||||
while try_object and (try_object.display_type == 'BOUNDS' or object_in_particle_collection(try_object)):
|
||||
ray_origin = snapped_location + vec.normalized() * 0.0003
|
||||
try_has_hit, try_snapped_location, try_snapped_normal, try_face_index, try_object, try_matrix = bpy.context.scene.ray_cast(
|
||||
depsgraph, ray_origin, vec)
|
||||
if try_has_hit:
|
||||
#this way only good hits are returned, otherwise
|
||||
has_hit, snapped_location, snapped_normal, face_index, object, matrix = try_has_hit, try_snapped_location, try_snapped_normal, try_face_index, try_object, try_matrix
|
||||
|
||||
return has_hit, snapped_location, snapped_normal, face_index, object, matrix
|
||||
|
||||
if not (object.display_type == 'BOUNDS' or object_in_particle_collection(try_object)):# or not object.visible_get()):
|
||||
return has_hit, snapped_location, snapped_normal, face_index, object, matrix
|
||||
return empty_set
|
||||
|
||||
def mouse_raycast(context, mx, my):
|
||||
r = context.region
|
||||
|
@ -1078,10 +1095,9 @@ def mouse_in_area(mx, my, x, y, w, h):
|
|||
|
||||
|
||||
def mouse_in_asset_bar(mx, my):
|
||||
s = bpy.context.scene
|
||||
|
||||
ui_props = bpy.context.scene.blenderkitUI
|
||||
# search_results = s.get('search results')
|
||||
# search_results = bpy.context.window_manager.get('search results')
|
||||
# if search_results == None:
|
||||
# return False
|
||||
#
|
||||
|
@ -1127,7 +1143,7 @@ def update_ui_size(area, region):
|
|||
ui.wcount = math.floor(
|
||||
(ui.bar_width - 2 * ui.drawoffset) / (ui.thumb_size + ui.margin))
|
||||
|
||||
search_results = bpy.context.scene.get('search results')
|
||||
search_results = bpy.context.window_manager.get('search results')
|
||||
if search_results != None and ui.wcount > 0:
|
||||
ui.hcount = min(user_preferences.max_assetbar_rows, math.ceil(len(search_results) / ui.wcount))
|
||||
else:
|
||||
|
@ -1197,6 +1213,67 @@ class ParticlesDropDialog(bpy.types.Operator):
|
|||
wm = context.window_manager
|
||||
return wm.invoke_props_dialog(self, width=400)
|
||||
|
||||
# class MaterialDropDialog(bpy.types.Operator):
|
||||
# """Tooltip"""
|
||||
# bl_idname = "object.blenderkit_material_drop"
|
||||
# bl_label = "BlenderKit material drop on linked objects"
|
||||
# bl_options = {'REGISTER', 'INTERNAL'}
|
||||
#
|
||||
# asset_search_index: IntProperty(name="Asset index",
|
||||
# description="Index of the asset in asset bar",
|
||||
# default=0,
|
||||
# )
|
||||
#
|
||||
# model_location: FloatVectorProperty(name="Location",
|
||||
# default=(0, 0, 0))
|
||||
#
|
||||
# model_rotation: FloatVectorProperty(name="Rotation",
|
||||
# default=(0, 0, 0),
|
||||
# subtype='QUATERNION')
|
||||
#
|
||||
# target_object: StringProperty(
|
||||
# name="Target object",
|
||||
# description="The object to which the particles will get applied",
|
||||
# default="", options={'SKIP_SAVE'})
|
||||
#
|
||||
# target_material_slot: IntProperty(name="Target material slot",
|
||||
# description="Index of the material on the object to be changed",
|
||||
# default=0,
|
||||
# )
|
||||
#
|
||||
# @classmethod
|
||||
# def poll(cls, context):
|
||||
# return True
|
||||
#
|
||||
# def draw(self, context):
|
||||
# layout = self.layout
|
||||
# message = "This asset is linked to the scene from an external file and cannot have material appended." \
|
||||
# " Do you want to bring it into Blender Scene?"
|
||||
# utils.label_multiline(layout, text=message, width=400)
|
||||
#
|
||||
# def execute(self, context):
|
||||
# for c in bpy.data.collections:
|
||||
# for o in c.objects:
|
||||
# if o.name != self.target_object:
|
||||
# continue;
|
||||
# for empty in bpy.context.visible_objects:
|
||||
# if not(empty.instance_type == 'COLLECTION' and empty.instance_collection == c):
|
||||
# continue;
|
||||
# utils.activate(empty)
|
||||
# break;
|
||||
# bpy.ops.object.blenderkit_bring_to_scene()
|
||||
# bpy.ops.scene.blenderkit_download(True,
|
||||
# # asset_type=ui_props.asset_type,
|
||||
# asset_index=self.asset_search_index,
|
||||
# model_location=self.model_rotation,
|
||||
# model_rotation=self.model_rotation,
|
||||
# target_object=self.target_object,
|
||||
# material_target_slot = self.target_slot)
|
||||
# return {'FINISHED'}
|
||||
#
|
||||
# def invoke(self, context, event):
|
||||
# wm = context.window_manager
|
||||
# return wm.invoke_props_dialog(self, width=400)
|
||||
|
||||
class AssetBarOperator(bpy.types.Operator):
|
||||
'''runs search and displays the asset bar at the same time'''
|
||||
|
@ -1220,7 +1297,7 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
return properties.tooltip
|
||||
|
||||
def search_more(self):
|
||||
sro = bpy.context.scene.get('search results orig')
|
||||
sro = bpy.context.window_manager.get('search results orig')
|
||||
if sro is not None and sro.get('next') is not None:
|
||||
search.search(get_next=True)
|
||||
|
||||
|
@ -1336,8 +1413,8 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
# TODO add one more condition here to take less performance.
|
||||
r = self.region
|
||||
s = bpy.context.scene
|
||||
sr = s.get('search results')
|
||||
search_results_orig = s.get('search results orig')
|
||||
sr = bpy.context.window_manager.get('search results')
|
||||
search_results_orig = bpy.context.window_manager.get('search results orig')
|
||||
# If there aren't any results, we need no interaction(yet)
|
||||
if sr is None:
|
||||
return {'PASS_THROUGH'}
|
||||
|
@ -1424,7 +1501,7 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
bpy.context.window.cursor_set("DEFAULT")
|
||||
return {'PASS_THROUGH'}
|
||||
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
|
||||
if not ui_props.dragging:
|
||||
bpy.context.window.cursor_set("DEFAULT")
|
||||
|
@ -1672,7 +1749,7 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
return {'RUNNING_MODAL'}
|
||||
|
||||
if event.type == 'W' and ui_props.active_index > -1:
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = sr[ui_props.active_index]
|
||||
a = bpy.context.window_manager['bkit authors'].get(asset_data['author']['id'])
|
||||
if a is not None:
|
||||
|
@ -1681,7 +1758,7 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
bpy.ops.wm.url_open(url=a['aboutMeUrl'])
|
||||
return {'RUNNING_MODAL'}
|
||||
if event.type == 'A' and ui_props.active_index > -1:
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = sr[ui_props.active_index]
|
||||
a = asset_data['author']['id']
|
||||
if a is not None:
|
||||
|
@ -1694,7 +1771,7 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
|
||||
if event.type == 'X' and ui_props.active_index > -1:
|
||||
# delete downloaded files for this asset
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = sr[ui_props.active_index]
|
||||
bk_logger.info('delete asset from local drive:' + asset_data['name'])
|
||||
paths.delete_asset_debug(asset_data)
|
||||
|
@ -1705,6 +1782,7 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
def invoke(self, context, event):
|
||||
# FIRST START SEARCH
|
||||
ui_props = context.scene.blenderkitUI
|
||||
sr = bpy.context.window_manager.get('search results')
|
||||
|
||||
if self.do_search:
|
||||
# we erase search keywords for cateogry search now, since these combinations usually return nothing now.
|
||||
|
@ -1715,7 +1793,7 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
search.search(category=self.category)
|
||||
|
||||
if ui_props.assetbar_on:
|
||||
# we don't want to run the assetbar many times, that's why it has a switch on/off behaviour,
|
||||
# we don't want to run the assetbar more than once, that's why it has a switch on/off behaviour,
|
||||
# unless being called with 'keep_running' prop.
|
||||
if not self.keep_running:
|
||||
# this sends message to the originally running operator, so it quits, and then it ends this one too.
|
||||
|
@ -1734,9 +1812,8 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
ui_props.assetbar_on = True
|
||||
ui_props.turn_off = False
|
||||
|
||||
sr = bpy.context.scene.get('search results')
|
||||
if sr is None:
|
||||
bpy.context.scene['search results'] = []
|
||||
bpy.context.window_manager['search results'] = []
|
||||
|
||||
if context.area.type != 'VIEW_3D':
|
||||
self.report({'WARNING'}, "View3D not found, cannot run operator")
|
||||
|
@ -1873,6 +1950,8 @@ class AssetDragOperator(bpy.types.Operator):
|
|||
temp_mesh = object_eval.to_mesh()
|
||||
target_slot = temp_mesh.polygons[self.face_index].material_index
|
||||
object_eval.to_mesh_clear()
|
||||
# elif object.is_library_indirect:#case for bring to scene objects, will be solved through prefs and direct
|
||||
# action
|
||||
else:
|
||||
self.report({'WARNING'}, "Invalid or library object as input:")
|
||||
target_object = ''
|
||||
|
@ -2003,7 +2082,7 @@ class AssetDragOperator(bpy.types.Operator):
|
|||
object = None
|
||||
self.matrix = None
|
||||
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
self.asset_data = sr[self.asset_search_index]
|
||||
|
||||
context.window_manager.modal_handler_add(self)
|
||||
|
|
|
@ -546,7 +546,10 @@ class VIEW3D_PT_blenderkit_profile(Panel):
|
|||
if me is not None:
|
||||
me = me['user']
|
||||
# user name
|
||||
layout.label(text='Me: %s %s' % (me['firstName'], me['lastName']))
|
||||
if len(me['firstName'])>0 or len(me['lastName'])>0:
|
||||
layout.label(text=f"Me: {me['firstName']} {me['lastName']}")
|
||||
else:
|
||||
layout.label(text=f"Me: {me['email']}")
|
||||
# layout.label(text='Email: %s' % (me['email']))
|
||||
|
||||
# plan information
|
||||
|
@ -1244,7 +1247,7 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
|
|||
op.invoke_resolution = True
|
||||
o = utils.get_active_model()
|
||||
if o and o.get('asset_data'):
|
||||
if o['asset_data']['assetBaseId'] == bpy.context.scene['search results'][ui_props.active_index]:
|
||||
if o['asset_data']['assetBaseId'] == bpy.context.window_manager['search results'][ui_props.active_index]:
|
||||
op.model_location = o.location
|
||||
op.model_rotation = o.rotation_euler
|
||||
else:
|
||||
|
@ -1339,9 +1342,9 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
|
|||
# def draw(self, context):
|
||||
# ui_props = context.scene.blenderkitUI
|
||||
#
|
||||
# # sr = bpy.context.scene['search results']
|
||||
# # sr = bpy.context.window_manager['search results']
|
||||
#
|
||||
# # sr = bpy.context.scene['search results']
|
||||
# # sr = bpy.context.window_manager['search results']
|
||||
# # asset_data = sr[ui_props.active_index]
|
||||
#
|
||||
# for k in resolutions.resolution_props_to_server.keys():
|
||||
|
@ -1355,13 +1358,13 @@ class OBJECT_MT_blenderkit_asset_menu(bpy.types.Menu):
|
|||
def draw(self, context):
|
||||
ui_props = context.scene.blenderkitUI
|
||||
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = sr[ui_props.active_index]
|
||||
draw_asset_context_menu(self.layout, context, asset_data, from_panel=False)
|
||||
|
||||
# ui_props = context.scene.blenderkitUI
|
||||
#
|
||||
# sr = bpy.context.scene['search results']
|
||||
# sr = bpy.context.window_manager['search results']
|
||||
# asset_data = sr[ui_props.active_index]
|
||||
# layout = self.layout
|
||||
# row = layout.row()
|
||||
|
@ -1403,7 +1406,7 @@ class AssetPopupCard(bpy.types.Operator):
|
|||
def draw(self, context):
|
||||
ui_props = context.scene.blenderkitUI
|
||||
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = sr[ui_props.active_index]
|
||||
layout = self.layout
|
||||
row = layout.row()
|
||||
|
@ -1442,7 +1445,7 @@ class AssetPopupCard(bpy.types.Operator):
|
|||
wm = context.window_manager
|
||||
ui_props = context.scene.blenderkitUI
|
||||
ui_props.draw_tooltip = False
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = sr[ui_props.active_index]
|
||||
self.img = ui.get_large_thumbnail_image(asset_data)
|
||||
# self.tex = utils.get_hidden_texture(self.img)
|
||||
|
@ -1520,10 +1523,18 @@ class UrlPopupDialog(bpy.types.Operator):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
utils.label_multiline(layout, text=self.message)
|
||||
utils.label_multiline(layout, text=self.message, width = 300)
|
||||
|
||||
layout.active_default = True
|
||||
op = layout.operator("wm.url_open", text=self.link_text, icon='QUESTION')
|
||||
if not utils.user_logged_in():
|
||||
utils.label_multiline(layout,
|
||||
text='Already subscribed? You need to login to access your Full Plan.',
|
||||
width = 300)
|
||||
|
||||
layout.operator_context = 'EXEC_DEFAULT'
|
||||
layout.operator("wm.blenderkit_login", text="Login",
|
||||
icon='URL').signup = False
|
||||
op.url = self.url
|
||||
|
||||
def execute(self, context):
|
||||
|
@ -1533,7 +1544,7 @@ class UrlPopupDialog(bpy.types.Operator):
|
|||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
|
||||
return wm.invoke_props_dialog(self)
|
||||
return wm.invoke_props_dialog(self,width = 300)
|
||||
|
||||
|
||||
class LoginPopupDialog(bpy.types.Operator):
|
||||
|
@ -1688,7 +1699,12 @@ def header_search_draw(self, context):
|
|||
layout.prop(props, "search_keywords", text="", icon='VIEWZOOM')
|
||||
draw_assetbar_show_hide(layout, props)
|
||||
|
||||
def ui_message(title, message):
|
||||
def draw_message(self, context):
|
||||
layout = self.layout
|
||||
utils.label_multiline(layout, text=message)
|
||||
|
||||
bpy.context.window_manager.popup_menu(draw_message, title=title, icon='INFO')
|
||||
# We can store multiple preview collections here,
|
||||
# however in this example we only store "main"
|
||||
preview_collections = {}
|
||||
|
|
|
@ -524,8 +524,8 @@ def patch_individual_metadata(asset_id, metadata_dict, api_key):
|
|||
# layout = self.layout
|
||||
# ui_props = context.scene.blenderkitUI
|
||||
#
|
||||
# # sr = bpy.context.scene['search results']
|
||||
# sr = bpy.context.scene['search results']
|
||||
# # sr = bpy.context.window_manager['search results']
|
||||
# sr = bpy.context.window_manager['search results']
|
||||
# asset_data = sr[ui_props.active_index]
|
||||
# categories = bpy.context.window_manager['bkit_categories']
|
||||
# wm = bpy.context.win
|
||||
|
@ -654,10 +654,10 @@ class FastMetadata(bpy.types.Operator):
|
|||
scene = bpy.context.scene
|
||||
ui_props = scene.blenderkitUI
|
||||
if ui_props.active_index > -1:
|
||||
sr = bpy.context.scene['search results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = dict(sr[ui_props.active_index])
|
||||
else:
|
||||
for result in bpy.context.scene['search results']:
|
||||
for result in bpy.context.window_manager['search results']:
|
||||
if result['id'] == self.asset_id:
|
||||
asset_data = dict(result)
|
||||
|
||||
|
@ -673,7 +673,6 @@ class FastMetadata(bpy.types.Operator):
|
|||
except Exception as e:
|
||||
print(e)
|
||||
self.message = f"Fast edit metadata of {asset_data['name']}"
|
||||
self.message = str(cat_path)
|
||||
self.name = asset_data['displayName']
|
||||
self.description = asset_data['description']
|
||||
self.tags = ','.join(asset_data['tags'])
|
||||
|
@ -1196,12 +1195,12 @@ class AssetDebugPrint(Operator):
|
|||
def execute(self, context):
|
||||
preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
|
||||
if not bpy.context.scene['search results']:
|
||||
if not bpy.context.window_manager['search results']:
|
||||
print('no search results found')
|
||||
return {'CANCELLED'};
|
||||
# update status in search results for validator's clarity
|
||||
sr = bpy.context.scene['search results']
|
||||
sro = bpy.context.scene['search results orig']['results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
sro = bpy.context.window_manager['search results orig']['results']
|
||||
|
||||
result = None
|
||||
for r in sr:
|
||||
|
@ -1250,11 +1249,11 @@ class AssetVerificationStatusChange(Operator):
|
|||
def execute(self, context):
|
||||
preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
|
||||
if not bpy.context.scene['search results']:
|
||||
if not bpy.context.window_manager['search results']:
|
||||
return {'CANCELLED'};
|
||||
# update status in search results for validator's clarity
|
||||
sr = bpy.context.scene['search results']
|
||||
sro = bpy.context.scene['search results orig']['results']
|
||||
sr = bpy.context.window_manager['search results']
|
||||
sro = bpy.context.window_manager['search results orig']['results']
|
||||
|
||||
for r in sr:
|
||||
if r['id'] == self.asset_id:
|
||||
|
|
|
@ -780,13 +780,13 @@ def get_fake_context(context, area_type='VIEW_3D'):
|
|||
C_dict = {} # context.copy() #context.copy was a source of problems - incompatibility with addons that also define context
|
||||
C_dict.update(region='WINDOW')
|
||||
|
||||
try:
|
||||
context = context.copy()
|
||||
# print('bk context copied successfully')
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print('BlenderKit: context.copy() failed. Can be a colliding addon.')
|
||||
context = {}
|
||||
# try:
|
||||
# context = context.copy()
|
||||
# # print('bk context copied successfully')
|
||||
# except Exception as e:
|
||||
# print(e)
|
||||
# print('BlenderKit: context.copy() failed. Can be a colliding addon.')
|
||||
context = {}
|
||||
|
||||
if context.get('area') is None or context.get('area').type != area_type:
|
||||
w, a, r = get_largest_area(area_type=area_type)
|
||||
|
@ -825,3 +825,6 @@ def label_multiline(layout, text='', icon='NONE', width=-1):
|
|||
break;
|
||||
layout.label(text=l, icon=icon)
|
||||
icon = 'NONE'
|
||||
|
||||
def trace():
|
||||
traceback.print_stack()
|
|
@ -15,7 +15,7 @@
|
|||
bl_info = {
|
||||
'name': 'glTF 2.0 format',
|
||||
'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
|
||||
"version": (1, 6, 2),
|
||||
"version": (1, 6, 3),
|
||||
'blender': (2, 91, 0),
|
||||
'location': 'File > Import-Export',
|
||||
'description': 'Import-Export as glTF 2.0',
|
||||
|
|
|
@ -423,8 +423,17 @@ def __gather_trans_rot_scale(blender_object, export_settings):
|
|||
sca = __convert_swizzle_scale(sca, export_settings)
|
||||
|
||||
if blender_object.instance_type == 'COLLECTION' and blender_object.instance_collection:
|
||||
trans -= __convert_swizzle_location(
|
||||
offset = -__convert_swizzle_location(
|
||||
blender_object.instance_collection.instance_offset, export_settings)
|
||||
|
||||
s = Matrix.Diagonal(sca).to_4x4()
|
||||
r = rot.to_matrix().to_4x4()
|
||||
t = Matrix.Translation(trans).to_4x4()
|
||||
o = Matrix.Translation(offset).to_4x4()
|
||||
m = t @ r @ s @ o
|
||||
|
||||
trans = m.translation
|
||||
|
||||
translation, rotation, scale = (None, None, None)
|
||||
trans[0], trans[1], trans[2] = gltf2_blender_math.round_if_near(trans[0], 0.0), gltf2_blender_math.round_if_near(trans[1], 0.0), \
|
||||
gltf2_blender_math.round_if_near(trans[2], 0.0)
|
||||
|
|
Loading…
Reference in New Issue