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:
-rw-r--r--blenderkit/__init__.py29
-rw-r--r--blenderkit/bg_blender.py7
-rw-r--r--blenderkit/categories.py1
-rw-r--r--blenderkit/download.py43
-rw-r--r--blenderkit/paths.py2
-rw-r--r--blenderkit/rerequests.py14
-rw-r--r--blenderkit/search.py64
-rw-r--r--blenderkit/tasks_queue.py4
-rw-r--r--blenderkit/thumbnails/intro.jpgbin0 -> 66605 bytes
-rw-r--r--blenderkit/ui.py16
-rw-r--r--blenderkit/ui_panels.py68
-rw-r--r--blenderkit/utils.py16
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
new file mode 100644
index 00000000..52ce56e3
--- /dev/null
+++ b/blenderkit/thumbnails/intro.jpg
Binary files differ
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: