diff options
-rw-r--r-- | blenderkit/__init__.py | 29 | ||||
-rw-r--r-- | blenderkit/bg_blender.py | 7 | ||||
-rw-r--r-- | blenderkit/categories.py | 1 | ||||
-rw-r--r-- | blenderkit/download.py | 43 | ||||
-rw-r--r-- | blenderkit/paths.py | 2 | ||||
-rw-r--r-- | blenderkit/rerequests.py | 14 | ||||
-rw-r--r-- | blenderkit/search.py | 64 | ||||
-rw-r--r-- | blenderkit/tasks_queue.py | 4 | ||||
-rw-r--r-- | blenderkit/thumbnails/intro.jpg | bin | 0 -> 66605 bytes | |||
-rw-r--r-- | blenderkit/ui.py | 16 | ||||
-rw-r--r-- | blenderkit/ui_panels.py | 68 | ||||
-rw-r--r-- | blenderkit/utils.py | 16 |
12 files changed, 204 insertions, 60 deletions
diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py index e8043626..c58e5d99 100644 --- a/blenderkit/__init__.py +++ b/blenderkit/__init__.py @@ -155,10 +155,10 @@ def scene_load(context): @bpy.app.handlers.persistent def check_timers_timer(): ''' checks if all timers are registered regularly. Prevents possible bugs from stopping the addon.''' - if not bpy.app.timers.is_registered(search.timer_update): - bpy.app.timers.register(search.timer_update) - if not bpy.app.timers.is_registered(download.timer_update): - bpy.app.timers.register(download.timer_update) + if not bpy.app.timers.is_registered(search.search_timer): + bpy.app.timers.register(search.search_timer) + if not bpy.app.timers.is_registered(download.download_timer): + bpy.app.timers.register(download.download_timer) if not (bpy.app.timers.is_registered(tasks_queue.queue_worker)): bpy.app.timers.register(tasks_queue.queue_worker) if not bpy.app.timers.is_registered(bg_blender.bg_update): @@ -1542,7 +1542,7 @@ class BlenderKitSceneSearchProps(PropertyGroup, BlenderKitCommonSearchProps): ) switch_after_append: BoolProperty( name='Switch to scene after download', - default=False + default=True ) @@ -1714,6 +1714,13 @@ class BlenderKitAddonPreferences(AddonPreferences): update=utils.save_prefs ) + # single_timer: BoolProperty( + # name="Use timers", + # description="Use timers for BlenderKit. Usefull for debugging since timers seem to be unstable", + # default=True, + # update=utils.save_prefs + # ) + experimental_features: BoolProperty( name="Enable experimental features", description="Enable all experimental features of BlenderKit. Use at your own risk.", @@ -1773,6 +1780,15 @@ class BlenderKitAddonPreferences(AddonPreferences): layout.prop(self, "categories_fix") +# # @bpy.app.handlers.persistent +# def blenderkit_timer(): +# +# +# if not user_preferences.use_timers: +# search.search_timer() +# download.download_timer() +# tasks_queue.queue_worker() +# bg_blender.bg_update() # registration classes = ( @@ -1800,6 +1816,7 @@ classes = ( ) + def register(): for cls in classes: bpy.utils.register_class(cls) @@ -1874,6 +1891,8 @@ def register(): if a.type == 'PREFERENCES': tasks_queue.add_task((bpy.ops.wm.blenderkit_welcome, ('INVOKE_DEFAULT',)), fake_context=True, fake_context_area='PREFERENCES') + #save preferences after manually enabling the addon + tasks_queue.add_task((bpy.ops.wm.save_userpref, ()), fake_context=False,) def unregister(): diff --git a/blenderkit/bg_blender.py b/blenderkit/bg_blender.py index 01c62538..c4294b30 100644 --- a/blenderkit/bg_blender.py +++ b/blenderkit/bg_blender.py @@ -108,11 +108,14 @@ def bg_update(): '''monitoring of background process''' text = '' #utils.p('timer search') + # utils.p('start bg_blender timer bg_update') s = bpy.context.scene global bg_processes if len(bg_processes) == 0: + # utils.p('end bg_blender timer bg_update') + return 2 #cleanup dead processes first remove_processes = [] @@ -156,7 +159,11 @@ def bg_update(): # if len(bg_processes) == 0: # bpy.app.timers.unregister(bg_update) if len(bg_processes) > 0: + # utils.p('end bg_blender timer bg_update') + return .3 + # utils.p('end bg_blender timer bg_update') + return 1. diff --git a/blenderkit/categories.py b/blenderkit/categories.py index 46d10f86..3a0d2624 100644 --- a/blenderkit/categories.py +++ b/blenderkit/categories.py @@ -84,6 +84,7 @@ def get_category_path(categories, category): category_path.insert(0, slug) return category_path check_categories.append(ch) + return category_path def get_category_name_path(categories, category): '''finds the category in all possible subcategories and returns the path to it''' diff --git a/blenderkit/download.py b/blenderkit/download.py index 7cffff44..f0c101a1 100644 --- a/blenderkit/download.py +++ b/blenderkit/download.py @@ -17,7 +17,7 @@ # ##### END GPL LICENSE BLOCK ##### -from blenderkit import paths, append_link, utils, ui, colors, tasks_queue, rerequests, resolutions +from blenderkit import paths, append_link, utils, ui, colors, tasks_queue, rerequests, resolutions, ui_panels import threading import time @@ -62,7 +62,7 @@ def check_missing(): for l in missing: asset_data = l['asset_data'] - downloaded = check_existing(asset_data, resolution=asset_data['resolution']) + downloaded = check_existing(asset_data, resolution=asset_data.get('resolution')) if downloaded: try: l.reload() @@ -315,11 +315,11 @@ def append_asset(asset_data, **kwargs): # downloaders=[], location=None, sprops = s.blenderkit_scene scene = append_link.append_scene(file_names[0], link=sprops.append_link == 'LINK', fake_user=False) - print('scene appended') + # print('scene appended') if scene is not None: props = scene.blenderkit asset_main = scene - print(sprops.switch_after_append) + # print(sprops.switch_after_append) if sprops.switch_after_append: bpy.context.window_manager.windows[0].scene = scene @@ -563,7 +563,7 @@ def replace_resolution_appended(file_paths, asset_data, resolution): # @bpy.app.handlers.persistent -def timer_update(): +def download_timer(): # TODO might get moved to handle all blenderkit stuff, not to slow down. ''' check for running and finished downloads. @@ -571,10 +571,14 @@ def timer_update(): Finished downloads are processed and linked/appended to scene. ''' global download_threads + # utils.p('start download timer') + # bk_logger.debug('timer download') if len(download_threads) == 0: - return 2.0 + # utils.p('end download timer') + + return 2 s = bpy.context.scene for threaddata in download_threads: t = threaddata[0] @@ -589,13 +593,14 @@ def timer_update(): if sr is not None: for r in sr: if asset_data['id'] == r['id']: - r['downloaded'] = tcom.progress - + r['downloaded'] = 0.5#tcom.progress if not t.is_alive(): if tcom.error: sprops = utils.get_search_props() sprops.report = tcom.report download_threads.remove(threaddata) + # utils.p('end download timer') + return file_paths = paths.get_download_filepaths(asset_data, tcom.passargs['resolution']) @@ -661,6 +666,8 @@ def timer_update(): sres['downloaded'] = 100 bk_logger.debug('finished download thread') + # utils.p('end download timer') + return .5 @@ -753,6 +760,7 @@ class Downloader(threading.Thread): # def main_download_thread(asset_data, tcom, scene_id, api_key): def run(self): '''try to download file from blenderkit''' + # utils.p('start downloader thread') asset_data = self.asset_data tcom = self.tcom scene_id = self.scene_id @@ -832,6 +840,8 @@ class Downloader(threading.Thread): tcom.report = f'Unpacking files' self.asset_data['resolution'] = self.resolution resolutions.send_to_bg(self.asset_data, file_name, command='unpack') + # utils.p('end downloader thread') + class ThreadCom: # object passed to threads to read background process stdout info @@ -1226,7 +1236,7 @@ def show_enum_values(obj, prop_name): class BlenderkitDownloadOperator(bpy.types.Operator): """Download and link asset to scene. Only link if asset already available locally""" bl_idname = "scene.blenderkit_download" - bl_label = "BlenderKit Asset Download" + bl_label = "Download" bl_options = {'REGISTER', 'UNDO', 'INTERNAL'} # asset_type: EnumProperty( @@ -1258,6 +1268,8 @@ class BlenderkitDownloadOperator(bpy.types.Operator): invoke_resolution: BoolProperty(name='Replace resolution popup', description='pop up to ask which resolution to download', default=False) + invoke_scene_settings: BoolProperty(name='Scene import settings popup', + description='pop up scene import settings', default=False) resolution: EnumProperty( items=available_resolutions_callback, @@ -1376,7 +1388,10 @@ class BlenderkitDownloadOperator(bpy.types.Operator): def draw(self, context): layout = self.layout - layout.prop(self, 'resolution', expand=True, icon_only=False) + if self.invoke_resolution: + layout.prop(self, 'resolution', expand=True, icon_only=False) + if self.invoke_scene_settings: + ui_panels.draw_scene_import_settings(self, context) def invoke(self, context, event): # if self.close_window: @@ -1399,6 +1414,8 @@ class BlenderkitDownloadOperator(bpy.types.Operator): self.resolution = 'ORIGINAL' return wm.invoke_props_dialog(self) + if self.invoke_scene_settings: + return wm.invoke_props_dialog(self) # if self.close_window: # time.sleep(0.1) # context.area.tag_redraw() @@ -1416,7 +1433,7 @@ def register_download(): bpy.app.handlers.save_pre.append(scene_save) user_preferences = bpy.context.preferences.addons['blenderkit'].preferences if user_preferences.use_timers: - bpy.app.timers.register(timer_update) + bpy.app.timers.register(download_timer) def unregister_download(): @@ -1424,5 +1441,5 @@ def unregister_download(): bpy.utils.unregister_class(BlenderkitKillDownloadOperator) bpy.app.handlers.load_post.remove(scene_load) bpy.app.handlers.save_pre.remove(scene_save) - if bpy.app.timers.is_registered(timer_update): - bpy.app.timers.unregister(timer_update) + if bpy.app.timers.is_registered(download_timer): + bpy.app.timers.unregister(download_timer) diff --git a/blenderkit/paths.py b/blenderkit/paths.py index 0ca55271..57511108 100644 --- a/blenderkit/paths.py +++ b/blenderkit/paths.py @@ -27,7 +27,7 @@ BLENDERKIT_API = "/api/v1/" BLENDERKIT_REPORT_URL = "usage_report/" BLENDERKIT_USER_ASSETS = "/my-assets" BLENDERKIT_PLANS = "/plans/pricing/" -BLENDERKIT_MANUAL = "https://youtu.be/1hVgcQhIAo8" +BLENDERKIT_MANUAL = "https://youtu.be/pSay3yaBWV0" BLENDERKIT_MODEL_UPLOAD_INSTRUCTIONS_URL = "https://www.blenderkit.com/docs/upload/" BLENDERKIT_MATERIAL_UPLOAD_INSTRUCTIONS_URL = "https://www.blenderkit.com/docs/uploading-material/" BLENDERKIT_BRUSH_UPLOAD_INSTRUCTIONS_URL = "https://www.blenderkit.com/docs/uploading-brush/" diff --git a/blenderkit/rerequests.py b/blenderkit/rerequests.py index 6a2659c2..f9c51559 100644 --- a/blenderkit/rerequests.py +++ b/blenderkit/rerequests.py @@ -22,10 +22,11 @@ from blenderkit import ui, utils, paths, tasks_queue, bkit_oauth import requests import bpy import logging + bk_logger = logging.getLogger('rerequests') -def rerequest(method, url, **kwargs): +def rerequest(method, url, recursion=0, **kwargs): # first get any additional args from kwargs immediate = False if kwargs.get('immediate'): @@ -34,10 +35,11 @@ def rerequest(method, url, **kwargs): # first normal attempt try: response = requests.request(method, url, **kwargs) - except: - return rerequest(method, url, **kwargs) + except Exception as e: + print(e) + return None - bk_logger.debug(url+ str( kwargs)) + bk_logger.debug(url + str(kwargs)) bk_logger.debug(response.status_code) if response.status_code == 401: @@ -53,7 +55,7 @@ def rerequest(method, url, **kwargs): if user_preferences.api_key != '': if user_preferences.enable_oauth and user_preferences.api_key_refresh != '': tasks_queue.add_task((ui.add_report, ( - 'refreshing token. If this fails, please login in BlenderKit Login panel.', 10))) + 'refreshing token. If this fails, please login in BlenderKit Login panel.', 10))) refresh_url = paths.get_bkit_url() auth_token, refresh_token, oauth_response = bkit_oauth.refresh_token( user_preferences.api_key_refresh, refresh_url) @@ -80,7 +82,7 @@ def rerequest(method, url, **kwargs): tasks_queue.add_task((ui.add_report, ( 'Refreshing token failed.Please login manually.', 10))) # tasks_queue.add_task((bkit_oauth.write_tokens, ('', '', ''))) - tasks_queue.add_task((bpy.ops.wm.blenderkit_login,( 'INVOKE_DEFAULT',)),fake_context = True) + tasks_queue.add_task((bpy.ops.wm.blenderkit_login, ('INVOKE_DEFAULT',)), fake_context=True) return response diff --git a/blenderkit/search.py b/blenderkit/search.py index d6e89a7b..23440b7c 100644 --- a/blenderkit/search.py +++ b/blenderkit/search.py @@ -48,6 +48,7 @@ import copy import json import math import unicodedata +import urllib import queue import logging @@ -80,7 +81,7 @@ reports_queue = queue.Queue() rtips = ['Click or drag model or material in scene to link/append ', "Please rate responsively and plentifully. This helps us distribute rewards to the authors.", "Click on brushes to link them into scene.", - "All materials and brushes are free.", + "All materials are free.", "Storage for public assets is unlimited.", "Locked models are available if you subscribe to Full plan.", "Login to upload your own models, materials or brushes.", @@ -246,7 +247,7 @@ def parse_result(r): durl, tname, small_tname = '', '', '' if r['assetType'] == 'hdr': - tname = paths.extract_filename_from_url(r['thumbnailMiddleUrlNonsquared']) + tname = paths.extract_filename_from_url(r['thumbnailLargeUrlNonsquared']) else: tname = paths.extract_filename_from_url(r['thumbnailMiddleUrl']) small_tname = paths.extract_filename_from_url(r['thumbnailSmallUrl']) @@ -349,10 +350,10 @@ def parse_result(r): # @bpy.app.handlers.persistent -def timer_update(): +def search_timer(): # this makes a first search after opening blender. showing latest assets. # utils.p('timer search') - + # utils.p('start search timer') global first_time preferences = bpy.context.preferences.addons['blenderkit'].preferences if first_time and not bpy.app.background: # first time @@ -367,6 +368,8 @@ def timer_update(): utils.get_largest_area() ui.update_ui_size(ui.active_area_pointer, ui.active_region_pointer) ui.add_report(text='BlenderKit Tip: ' + random.choice(rtips), timeout=12, color=colors.GREEN) + # utils.p('end search timer') + return 3.0 # if preferences.first_run: @@ -377,10 +380,14 @@ def timer_update(): global search_threads if len(search_threads) == 0: + # utils.p('end search timer') + return 1.0 # don't do anything while dragging - this could switch asset during drag, and make results list length different, # causing a lot of throuble. if bpy.context.scene.blenderkitUI.dragging: + # utils.p('end search timer') + return 0.5 for thread in search_threads: # TODO this doesn't check all processes when one gets removed, @@ -415,13 +422,21 @@ def timer_update(): while not reports_queue.empty(): props.report = str(reports_queue.get()) + # utils.p('end search timer') + return .2 rdata = thread[0].result result_field = [] ok, error = check_errors(rdata) if ok: - bpy.ops.object.run_assetbar_fix_context() + ui_props = bpy.context.scene.blenderkitUI + + if not ui_props.assetbar_on: + bpy.ops.object.run_assetbar_fix_context() + + + for r in rdata['results']: asset_data = parse_result(r) if asset_data != None: @@ -443,7 +458,6 @@ def timer_update(): wm['search results orig'] = wm[search_name + ' orig'] load_previews() - ui_props = bpy.context.scene.blenderkitUI if len(result_field) < ui_props.scrolloffset or not (thread[0].params.get('get_next')): # jump back ui_props.scrolloffset = 0 @@ -453,7 +467,7 @@ def timer_update(): 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') + # bpy.ops.wm.undo_push_context(message='Get BlenderKit search') else: bk_logger.error(error) @@ -462,6 +476,7 @@ def timer_update(): # print('finished search thread') mt('preview loading finished') + # utils.p('end search timer') return .3 @@ -638,6 +653,7 @@ class ThumbDownloader(threading.Thread): def run(self): # print('thumb downloader', self.url) + # utils.p('start thumbdownloader thread') r = None try: r = requests.get(self.url, stream=False) @@ -651,6 +667,8 @@ class ThumbDownloader(threading.Thread): # with open(path, 'wb') as f: # for chunk in r.iter_content(1048576*4): # f.write(chunk) + # utils.p('end thumbdownloader thread') + def write_gravatar(a_id, gravatar_path): @@ -796,7 +814,8 @@ def query_to_url(query={}, params={}): order.append('-score,_score') else: order.append('_score') - requeststring += '+order:' + ','.join(order) + if requeststring.find('+order:')==-1: + requeststring += '+order:' + ','.join(order) requeststring += '&addon_version=%s' % params['addon_version'] if params.get('scene_uuid') is not None: @@ -839,6 +858,8 @@ class Searcher(threading.Thread): params = self.params t = time.time() + # utils.p('start search thread') + mt('search thread started') # tempdir = paths.get_temp_dir('%s_search' % query['asset_type']) # json_filepath = os.path.join(tempdir, '%s_searchresult.json' % query['asset_type']) @@ -852,6 +873,8 @@ class Searcher(threading.Thread): except requests.exceptions.RequestException as e: bk_logger.error(e) reports_queue.put(str(e)) + # utils.p('end search thread') + return mt('search response is back ') @@ -871,10 +894,14 @@ class Searcher(threading.Thread): # it means it's a server error that has a clear message. # That's why it gets processed in the update timer, where it can be passed in messages to user. self.result = rdata + # utils.p('end search thread') + return # print('number of results: ', len(rdata.get('results', []))) if self.stopped(): utils.p('stopping search : ' + str(query)) + # utils.p('end search thread') + return mt('search finished') @@ -892,7 +919,7 @@ class Searcher(threading.Thread): thumb_small_filepaths.append(imgpath) if d["assetType"] == 'hdr': - larege_thumb_url = d['thumbnailMiddleUrlNonsquared'] + larege_thumb_url = d['thumbnailLargeUrlNonsquared'] else: larege_thumb_url = d['thumbnailMiddleUrl'] @@ -941,10 +968,12 @@ class Searcher(threading.Thread): for k in thumb_full_download_threads.keys(): if k not in thumb_full_filepaths: killthreads_full.append(k) # do actual killing here? - # TODO do the killing/ stopping here! remember threads might have finished inbetween! + # TODO do the killing/ stopping here. remember threads might have finished inbetween. if self.stopped(): utils.p('stopping search : ' + str(query)) + # utils.p('end search thread') + return # this loop handles downloading of small thumbnails @@ -969,6 +998,8 @@ class Searcher(threading.Thread): i += 1 if self.stopped(): utils.p('stopping search : ' + str(query)) + # utils.p('end search thread') + return idx = 0 while len(thumb_sml_download_threads) > 0: @@ -980,6 +1011,8 @@ class Searcher(threading.Thread): i += 1 if self.stopped(): + # utils.p('end search thread') + utils.p('stopping search : ' + str(query)) return @@ -991,6 +1024,7 @@ class Searcher(threading.Thread): # daemon=True) thread.start() thumb_full_download_threads[imgpath] = thread + # utils.p('end search thread') mt('thumbnails finished') @@ -998,7 +1032,9 @@ def build_query_common(query, props): '''add shared parameters to query''' query_common = {} if props.search_keywords != '': - query_common["query"] = props.search_keywords + # keywords = urllib.parse.urlencode(props.search_keywords) + keywords = props.search_keywords.replace('&','%26') + query_common["query"] = keywords if props.search_verification_status != 'ALL' and utils.profile_is_validator(): query_common['verification_status'] = props.search_verification_status.lower() @@ -1500,7 +1536,7 @@ def register_search(): user_preferences = bpy.context.preferences.addons['blenderkit'].preferences if user_preferences.use_timers: - bpy.app.timers.register(timer_update) + bpy.app.timers.register(search_timer) categories.load_categories() @@ -1511,5 +1547,5 @@ def unregister_search(): for c in classes: bpy.utils.unregister_class(c) - if bpy.app.timers.is_registered(timer_update): - bpy.app.timers.unregister(timer_update) + if bpy.app.timers.is_registered(search_timer): + bpy.app.timers.unregister(search_timer) diff --git a/blenderkit/tasks_queue.py b/blenderkit/tasks_queue.py index f52cfd63..0d991878 100644 --- a/blenderkit/tasks_queue.py +++ b/blenderkit/tasks_queue.py @@ -58,6 +58,8 @@ def add_task(task, wait = 0, only_last = False, fake_context = False, fake_conte def queue_worker(): + # utils.p('start queue worker timer') + #bk_logger.debug('timer queue worker') time_step = 2.0 q = get_queue() @@ -110,6 +112,8 @@ def queue_worker(): # print('queue while 2') for task in back_to_queue: q.put(task) + # utils.p('end queue worker timer') + return 2.0 diff --git a/blenderkit/thumbnails/intro.jpg b/blenderkit/thumbnails/intro.jpg Binary files differnew file mode 100644 index 00000000..52ce56e3 --- /dev/null +++ b/blenderkit/thumbnails/intro.jpg diff --git a/blenderkit/ui.py b/blenderkit/ui.py index 25d6fca5..7b51eb65 100644 --- a/blenderkit/ui.py +++ b/blenderkit/ui.py @@ -486,12 +486,14 @@ def draw_callback_2d_progress(self, context): loc = view3d_utils.location_3d_to_region_2d(bpy.context.region, bpy.context.space_data.region_3d, d['location']) + # print('drawing downloader') if loc is not None: if asset_data['assetType'] == 'model': # models now draw with star trek mode, no need to draw percent for the image. draw_downloader(loc[0], loc[1], percent=tcom.progress, img=img, text=tcom.report) else: draw_downloader(loc[0], loc[1], percent=tcom.progress, img=img, text=tcom.report) + # utils.p('end drawing downlaoders downloader') else: draw_progress(x, y - index * 30, text='downloading %s' % asset_data['name'], percent=tcom.progress) @@ -1189,8 +1191,8 @@ class AssetBarOperator(bpy.types.Operator): # timers testing - seems timers might be causing crashes. testing it this way now. if not user_preferences.use_timers: - search.timer_update() - download.timer_update() + search.search_timer() + download.download_timer() tasks_queue.queue_worker() bg_blender.bg_update() @@ -1448,7 +1450,7 @@ class AssetBarOperator(bpy.types.Operator): if not asset_data.get('canDownload'): message = "Let's support asset creators and Open source." link_text = 'Unlock the asset.' - url = paths.get_bkit_url() + '/get-blenderkit/' + asset_data['id'] + '/?from_addon' + url = paths.get_bkit_url() + '/get-blenderkit/' + asset_data['id'] + '/?from_addon=True' bpy.ops.wm.blenderkit_url_dialog('INVOKE_REGION_WIN', url=url, message=message, link_text=link_text) return {'RUNNING_MODAL'} @@ -1623,6 +1625,14 @@ class AssetBarOperator(bpy.types.Operator): invoke_resolution=True, max_resolution=asset_data.get('max_resolution', 0) ) + elif ui_props.asset_type == 'SCENE': + bpy.ops.scene.blenderkit_download('INVOKE_DEFAULT', + asset_index=asset_search_index, + # replace_resolution=True, + invoke_resolution=False, + invoke_scene_settings=True, + max_resolution=asset_data.get('max_resolution', 0) + ) else: bpy.ops.scene.blenderkit_download( # asset_type=ui_props.asset_type, asset_index=asset_search_index, diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py index 3c5f4dcf..fe91658c 100644 --- a/blenderkit/ui_panels.py +++ b/blenderkit/ui_panels.py @@ -36,6 +36,7 @@ from bpy.props import ( import bpy import os +import random import logging bk_logger = logging.getLogger('blenderkit') @@ -887,6 +888,15 @@ class VIEW3D_PT_blenderkit_categories(Panel): def draw(self, context): draw_panel_categories(self, context) +def draw_scene_import_settings(self, context): + s = context.scene + props = s.blenderkit_scene + layout = self.layout + layout.prop(props, 'switch_after_append') + # layout.label(text='Import method:') + row = layout.row() + row.prop(props, 'append_link', expand=True, icon_only=False) + class VIEW3D_PT_blenderkit_import_settings(Panel): bl_category = "BlenderKit" @@ -931,11 +941,8 @@ class VIEW3D_PT_blenderkit_import_settings(Panel): row.prop(props, 'append_method', expand=True, icon_only=False) if ui_props.asset_type == 'SCENE': - props = s.blenderkit_scene - layout.prop(props, 'switch_after_append') - layout.label(text='Import method:') - row = layout.row() - row.prop(props, 'append_link', expand=True, icon_only=False) + draw_scene_import_settings(self,context) + if ui_props.asset_type == 'HDR': props = s.blenderkit_HDR @@ -1113,13 +1120,19 @@ class BlenderKitWelcomeOperator(bpy.types.Operator): if self.step == 0: user_preferences = bpy.context.preferences.addons['blenderkit'].preferences - message = "BlenderKit connects from Blender to an online, " \ - "community built shared library of models, " \ - "materials, and brushes. " \ - "Use addon preferences to set up where files will be saved in the Global directory setting." + # message = "BlenderKit connects from Blender to an online, " \ + # "community built shared library of models, " \ + # "materials, and brushes. " \ + # "Use addon preferences to set up where files will be saved in the Global directory setting." + # + # utils.label_multiline(layout, text=message, width=300) + + layout.template_icon(icon_value=self.img.preview.icon_id, scale=18) + + # utils.label_multiline(layout, text="\n Let's start by searching for some cool materials?", width=300) + op = layout.operator("wm.url_open", text='Watch Video Tutorial', icon='QUESTION') + op.url = paths.BLENDERKIT_MANUAL - utils.label_multiline(layout, text=message, width=300) - utils.label_multiline(layout, text="\n Let's start by searching for some cool materials?", width=300) else: message = "Operator Tutorial called with invalid step" @@ -1131,14 +1144,36 @@ class BlenderKitWelcomeOperator(bpy.types.Operator): # bpy.context.window_manager.windows[0].screen.areas[5].spaces[0].show_region_ui = False print('running search no') ui_props = bpy.context.scene.blenderkitUI - ui_props.asset_type = 'MATERIAL' - bpy.context.scene.blenderkit_mat.search_keywords = 'ice' + random_searches = [ + ('MATERIAL','ice'), + ('MODEL','car'), + ('MODEL','vase'), + ('MODEL','grass'), + ('MODEL','plant'), + ('MODEL','man'), + ('MATERIAL','metal'), + ('MATERIAL','wood'), + ('MATERIAL','floor'), + ('MATERIAL','bricks'), + ] + random_search = random.choice(random_searches) + ui_props.asset_type = random_search[0] + + bpy.context.scene.blenderkit_mat.search_keywords = ''#random_search[1] + bpy.context.scene.blenderkit_mat.search_keywords = '+is_free:true+score_gte:1000+order:-created'#random_search[1] # search.search() return {'FINISHED'} def invoke(self, context, event): wm = bpy.context.window_manager - return wm.invoke_props_dialog(self) + img = utils.get_thumbnail('intro.jpg') + utils.img_to_preview(img, copy_original = True) + self.img = img + w, a, r = utils.get_largest_area(area_type='VIEW_3D') + if a is not None: + a.spaces.active.show_region_ui = True + + return wm.invoke_props_dialog(self, width = 500) def draw_asset_context_menu(layout, context, asset_data, from_panel=False): @@ -1779,8 +1814,9 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): # top draggabe bar with name of the asset top_row = layout.row() top_drag_bar = top_row.box() + bcats = bpy.context.window_manager['bkit_categories'] - cat_path = categories.get_category_path(bpy.context.window_manager['bkit_categories'], + cat_path = categories.get_category_path(bcats, self.asset_data['category'])[1:] for i,c in enumerate(cat_path): cat_path[i] = c.capitalize() @@ -1821,6 +1857,8 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): sr = bpy.context.window_manager['search results'] asset_data = sr[ui_props.active_index] self.img = ui.get_large_thumbnail_image(asset_data) + utils.img_to_preview(self.img, copy_original = True) + self.asset_type = asset_data['assetType'] self.asset_id = asset_data['id'] # self.tex = utils.get_hidden_texture(self.img) diff --git a/blenderkit/utils.py b/blenderkit/utils.py index bae1244d..3d1f3eae 100644 --- a/blenderkit/utils.py +++ b/blenderkit/utils.py @@ -337,9 +337,14 @@ def get_hidden_texture(name, force_reload=False): return t -def img_to_preview(img): - img.preview.image_size = (img.size[0], img.size[1]) - img.preview.image_pixels_float = img.pixels[:] +def img_to_preview(img, copy_original = False): + if bpy.app.version[0]>=3: + img.preview_ensure() + if not copy_original: + return; + if img.preview.image_size != img.size: + img.preview.image_size = (img.size[0], img.size[1]) + img.preview.image_pixels_float = img.pixels[:] # img.preview.icon_size = (img.size[0], img.size[1]) # img.preview.icon_pixels_float = img.pixels[:] @@ -852,11 +857,14 @@ def get_fake_context(context, area_type='VIEW_3D'): # print(w,a,r) return C_dict +# def is_url(text): + def label_multiline(layout, text='', icon='NONE', width=-1): ''' draw a ui label, but try to split it in multiple lines.''' if text.strip() == '': return + text = text.replace('\r\n','\n') lines = text.split('\n') if width > 0: threshold = int(width / 5.5) @@ -865,6 +873,8 @@ def label_multiline(layout, text='', icon='NONE', width=-1): maxlines = 8 li = 0 for l in lines: + # if is_url(l): + while len(l) > threshold: i = l.rfind(' ', 0, threshold) if i < 1: |