diff options
author | Vilem Duha <vilem.duha@gmail.com> | 2021-05-15 20:27:45 +0300 |
---|---|---|
committer | Vilem Duha <vilem.duha@gmail.com> | 2021-05-15 20:27:45 +0300 |
commit | 4fcdbfe7c20edfc1204c0aa46c98ea25354abcd9 (patch) | |
tree | 4de28d6b4ba313ee67e63fb8e9b0216eea34fb10 | |
parent | 8f1c831af6419c469f5da22e013e67163662b15d (diff) | |
parent | 4f961d71dc55b15e1ebe26c8302bcdd2800b60dd (diff) |
Merge remote-tracking branch 'origin/blender-v2.93-release'
-rw-r--r-- | blenderkit/__init__.py | 4 | ||||
-rw-r--r-- | blenderkit/autothumb.py | 2 | ||||
-rw-r--r-- | blenderkit/download.py | 15 | ||||
-rw-r--r-- | blenderkit/ratings.py | 52 | ||||
-rw-r--r-- | blenderkit/ratings_utils.py | 62 | ||||
-rw-r--r-- | blenderkit/search.py | 17 | ||||
-rw-r--r-- | blenderkit/ui.py | 5 | ||||
-rw-r--r-- | blenderkit/ui_panels.py | 58 |
8 files changed, 165 insertions, 50 deletions
diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py index b288cbb5..ca7cbeb2 100644 --- a/blenderkit/__init__.py +++ b/blenderkit/__init__.py @@ -19,8 +19,8 @@ bl_info = { "name": "BlenderKit Online Asset Library", "author": "Vilem Duha, Petr Dlouhy", - "version": (2, 92, 0), - "blender": (2, 92, 0), + "version": (2, 93, 0), + "blender": (2, 93, 0), "location": "View3D > Properties > BlenderKit", "description": "Online BlenderKit library (materials, models, brushes and more). Connects to the internet.", "warning": "", diff --git a/blenderkit/autothumb.py b/blenderkit/autothumb.py index 9be9039e..b7f2a8d0 100644 --- a/blenderkit/autothumb.py +++ b/blenderkit/autothumb.py @@ -426,8 +426,6 @@ class ReGenerateThumbnailOperator(bpy.types.Operator): json_args=args_dict, wait=False) return {'FINISHED'} - start_thumbnailer(self, context) - return {'FINISHED'} def invoke(self, context, event): wm = context.window_manager diff --git a/blenderkit/download.py b/blenderkit/download.py index eca35c41..7cffff44 100644 --- a/blenderkit/download.py +++ b/blenderkit/download.py @@ -1278,6 +1278,9 @@ class BlenderkitDownloadOperator(bpy.types.Operator): description="", default="") + # close_window: BoolProperty(name='Close window', + # description='Try to close the window below mouse before download', + # default=False) # @classmethod # def poll(cls, context): # return bpy.context.window_manager.BlenderKitModelThumbnails is not '' @@ -1376,6 +1379,9 @@ class BlenderkitDownloadOperator(bpy.types.Operator): layout.prop(self, 'resolution', expand=True, icon_only=False) def invoke(self, context, event): + # if self.close_window: + # context.window.cursor_warp(event.mouse_x-1000, event.mouse_y - 1000); + print(self.asset_base_id) wm = context.window_manager # only make a pop up in case of switching resolutions @@ -1393,6 +1399,15 @@ class BlenderkitDownloadOperator(bpy.types.Operator): self.resolution = 'ORIGINAL' return wm.invoke_props_dialog(self) + # if self.close_window: + # time.sleep(0.1) + # context.area.tag_redraw() + # time.sleep(0.1) + # + # context.window.cursor_warp(event.mouse_x, event.mouse_y); + + return self.execute(context) + def register_download(): bpy.utils.register_class(BlenderkitDownloadOperator) diff --git a/blenderkit/ratings.py b/blenderkit/ratings.py index 1d7b843d..dd4eeb3d 100644 --- a/blenderkit/ratings.py +++ b/blenderkit/ratings.py @@ -16,7 +16,7 @@ # # ##### END GPL LICENSE BLOCK ##### -from blenderkit import paths, utils, rerequests, tasks_queue, ratings_utils +from blenderkit import paths, utils, rerequests, tasks_queue, ratings_utils, icons import bpy import requests, threading @@ -176,44 +176,70 @@ class UploadRatingOperator(bpy.types.Operator): def draw_ratings_menu(self, context, layout): + pcoll = icons.icon_collections["main"] + + profile_name = '' + profile = bpy.context.window_manager.get('bkit profile') + if profile: + profile_name = ' ' + profile['user']['firstName'] + col = layout.column() # layout.template_icon_view(bkit_ratings, property, show_labels=False, scale=6.0, scale_popup=5.0) row = col.row() + row.label(text='Quality:', icon = 'SOLO_ON') + row = col.row() + row.label(text='Please help the community by rating quality:') + + row = col.row() row.prop(self, 'rating_quality_ui', expand=True, icon_only=True, emboss=False) + if self.rating_quality>0: + # row = col.row() + + row.label(text=f' Thanks{profile_name}!', icon = 'FUND') # row.label(text=str(self.rating_quality)) col.separator() + col.separator() - row = layout.row() + row = col.row() + row.label(text='Complexity:', icon_value=pcoll['dumbbell'].icon_id) + row = col.row() row.label(text=f"How many hours did this {self.asset_type} save you?") + if utils.profile_is_validator(): + row = col.row() + row.prop(self, 'rating_work_hours') + if self.asset_type in ('model', 'scene'): - row = layout.row() - if utils.profile_is_validator(): - col.prop(self, 'rating_work_hours') + row = col.row() + row.prop(self, 'rating_work_hours_ui', expand=True, icon_only=False, emboss=True) if float(self.rating_work_hours_ui) > 100: - utils.label_multiline(layout, + utils.label_multiline(col, text=f"\nThat's huge! please be sure to give such rating only to godly {self.asset_type}s.\n", width=500) elif float(self.rating_work_hours_ui) > 18: - layout.separator() + col.separator() - utils.label_multiline(layout, + utils.label_multiline(col, text=f"\nThat's a lot! please be sure to give such rating only to amazing {self.asset_type}s.\n", width=500) + elif self.asset_type == 'hdr': - row = layout.row() + row = col.row() row.prop(self, 'rating_work_hours_ui_1_10', expand=True, icon_only=False, emboss=True) else: - row = layout.row() + row = col.row() row.prop(self, 'rating_work_hours_ui_1_5', expand=True, icon_only=False, emboss=True) + if self.rating_work_hours>0: + row = col.row() + row.label(text=f'Thanks{profile_name}, you are amazing!', icon='FUND') class FastRateMenu(Operator, ratings_utils.RatingsProperties): """Rating of the assets , also directly from the asset bar - without need to download assets""" bl_idname = "wm.blenderkit_menu_rating_upload" - bl_label = "Rate asset" + bl_label = "" bl_options = {'REGISTER', 'UNDO', 'INTERNAL'} @@ -226,6 +252,7 @@ class FastRateMenu(Operator, ratings_utils.RatingsProperties): def draw(self, context): layout = self.layout layout.label(text=self.message) + layout.separator() draw_ratings_menu(self, context, layout) @@ -265,8 +292,9 @@ class FastRateMenu(Operator, ratings_utils.RatingsProperties): if self.asset_id == '': return {'CANCELLED'} - self.message = f"Rate asset {self.asset_name}" + self.message = f"{self.asset_name}" wm = context.window_manager + self.prefill_ratings() if self.asset_type in ('model', 'scene'): # spawn a wider one for validators for the enum buttons diff --git a/blenderkit/ratings_utils.py b/blenderkit/ratings_utils.py index 9ceea9d0..26acb84c 100644 --- a/blenderkit/ratings_utils.py +++ b/blenderkit/ratings_utils.py @@ -30,7 +30,6 @@ from bpy.props import ( PointerProperty, ) - import threading import requests import logging @@ -69,21 +68,43 @@ def send_rating_to_thread_work_hours(url, ratings, headers): thread.start() +def store_rating_local(asset_id, type='quality', value=0): + context = bpy.context + context.window_manager['asset ratings'] = context.window_manager.get('asset ratings', {}) + context.window_manager['asset ratings'][asset_id] = context.window_manager['asset ratings'].get(asset_id, {}) + context.window_manager['asset ratings'][asset_id][type] = value + + +def get_rating_local(asset_id): + context = bpy.context + context.window_manager['asset ratings'] = context.window_manager.get('asset ratings', {}) + rating = context.window_manager['asset ratings'].get(asset_id) + if rating: + return rating.to_dict() + return None + + def update_ratings_quality(self, context): user_preferences = bpy.context.preferences.addons['blenderkit'].preferences api_key = user_preferences.api_key headers = utils.get_headers(api_key) - asset = self.id_data - if asset: + + if not (hasattr(self, 'rating_quality')): + # first option is for rating of assets that are from scene + asset = self.id_data bkit_ratings = asset.bkit_ratings - url = paths.get_api_url() + 'assets/' + asset['asset_data']['id'] + '/rating/' + asset_id = asset['asset_data']['id'] else: # this part is for operator rating: bkit_ratings = self - url = paths.get_api_url() + f'assets/{self.asset_id}/rating/' + asset_id = self.asset_id if bkit_ratings.rating_quality > 0.1: + url = paths.get_api_url() + f'assets/{asset_id}/rating/' + + store_rating_local(asset_id, type='quality', value=bkit_ratings.rating_quality) + ratings = [('quality', bkit_ratings.rating_quality)] tasks_queue.add_task((send_rating_to_thread_quality, (url, ratings, headers)), wait=2.5, only_last=True) @@ -92,16 +113,21 @@ def update_ratings_work_hours(self, context): user_preferences = bpy.context.preferences.addons['blenderkit'].preferences api_key = user_preferences.api_key headers = utils.get_headers(api_key) - asset = self.id_data - if asset: + if not (hasattr(self, 'rating_work_hours')): + # first option is for rating of assets that are from scene + asset = self.id_data bkit_ratings = asset.bkit_ratings - url = paths.get_api_url() + 'assets/' + asset['asset_data']['id'] + '/rating/' + asset_id = asset['asset_data']['id'] else: # this part is for operator rating: bkit_ratings = self - url = paths.get_api_url() + f'assets/{self.asset_id}/rating/' + asset_id = self.asset_id if bkit_ratings.rating_work_hours > 0.45: + url = paths.get_api_url() + f'assets/{asset_id}/rating/' + + store_rating_local(asset_id, type='working_hours', value=bkit_ratings.rating_work_hours) + ratings = [('working_hours', round(bkit_ratings.rating_work_hours, 1))] tasks_queue.add_task((send_rating_to_thread_work_hours, (url, ratings, headers)), wait=2.5, only_last=True) @@ -140,8 +166,6 @@ def update_ratings_work_hours_ui_1_5(self, context): bpy.ops.wm.blenderkit_login('INVOKE_DEFAULT', message='Please login/signup to rate assets. Clicking OK takes you to web login.') # self.rating_work_hours_ui_1_5 = '0' - # print('updating 1-5') - # print(float(self.rating_work_hours_ui_1_5)) self.rating_work_hours = float(self.rating_work_hours_ui_1_5) @@ -171,6 +195,7 @@ def stars_enum_callback(self, context): items.append((f'{a + 1}', f'{a + 1}', '', icon, a + 1)) return items + class RatingsProperties(): message: StringProperty( name="message", @@ -279,4 +304,17 @@ class RatingsProperties(): default='0', update=update_ratings_work_hours_ui_1_10, options={'SKIP_SAVE'} - )
\ No newline at end of file + ) + + def prefill_ratings(self): + # pre-fill ratings + ratings = get_rating_local(self.asset_id) + if ratings and ratings.get('quality'): + self.rating_quality = ratings['quality'] + if ratings and ratings.get('working_hours'): + wh = int(ratings['working_hours']) + self.rating_work_hours_ui = str(wh) + if wh < 6: + self.rating_work_hours_ui_1_5 = str(int(ratings['working_hours'])) + if wh < 11: + self.rating_work_hours_ui_1_10 = str(int(ratings['working_hours'])) diff --git a/blenderkit/search.py b/blenderkit/search.py index 858f676b..cd89d3bd 100644 --- a/blenderkit/search.py +++ b/blenderkit/search.py @@ -628,13 +628,14 @@ class ThumbDownloader(threading.Thread): return self._stop_event.is_set() def run(self): - print('thumb downloader', self.url) + # print('thumb downloader', self.url) + r = None try: r = requests.get(self.url, stream=False) except Exception as e: bk_logger.error('Thumbnail download failed') bk_logger.error(str(e)) - if r.status_code == 200: + if r and r.status_code == 200: with open(self.path, 'wb') as f: f.write(r.content) # ORIGINALLY WE DOWNLOADED THUMBNAILS AS STREAM, BUT THIS WAS TOO SLOW. @@ -1405,6 +1406,11 @@ class SearchOperator(Operator): options={'SKIP_SAVE'} ) + # close_window: BoolProperty(name='Close window', + # description='Try to close the window below mouse before download', + # default=False) + + tooltip: bpy.props.StringProperty(default='Runs search and displays the asset bar at the same time') @classmethod @@ -1428,6 +1434,13 @@ class SearchOperator(Operator): return {'FINISHED'} + # def invoke(self, context, event): + # if self.close_window: + # context.window.cursor_warp(event.mouse_x, event.mouse_y - 100); + # context.area.tag_redraw() + # + # context.window.cursor_warp(event.mouse_x, event.mouse_y); + # return self. execute(context) class UrlOperator(Operator): """""" diff --git a/blenderkit/ui.py b/blenderkit/ui.py index 182ab99a..febf37b1 100644 --- a/blenderkit/ui.py +++ b/blenderkit/ui.py @@ -382,6 +382,7 @@ def draw_tooltip_with_author(asset_data, x, y): gimg = utils.get_hidden_image(a['gravatarImg'], a['gravatarHash']) aname = asset_data['displayName'] + aname = aname[0].upper() + aname[1:] if len(aname)>36: aname = f"{aname[:33]}..." @@ -1419,10 +1420,10 @@ class AssetBarOperator(bpy.types.Operator): my = event.mouse_y - r.y if event.value == 'PRESS' and mouse_in_asset_bar(mx, my): - context.window.cursor_warp(event.mouse_x - 400, event.mouse_y - 20); + # context.window.cursor_warp(event.mouse_x - 300, event.mouse_y - 10); bpy.ops.wm.blenderkit_asset_popup('INVOKE_DEFAULT') - context.window.cursor_warp(event.mouse_x, event.mouse_y); + # context.window.cursor_warp(event.mouse_x, event.mouse_y); # bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_asset_menu') return {'RUNNING_MODAL'} diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py index 220070b2..cb3b5a8b 100644 --- a/blenderkit/ui_panels.py +++ b/blenderkit/ui_panels.py @@ -421,8 +421,6 @@ class VIEW3D_PT_blenderkit_model_properties(Panel): layout.label(text=str(ad['name'])) if o.instance_type == 'COLLECTION' and o.instance_collection is not None: layout.operator('object.blenderkit_bring_to_scene', text='Bring to scene') - # layout.label(text='Ratings:') - # draw_panel_model_rating(self, context) layout.label(text='Asset tools:') draw_asset_context_menu(self.layout, context, ad, from_panel=True) @@ -465,8 +463,6 @@ class NODE_PT_blenderkit_material_properties(Panel): if m.get('asset_data') is not None: ad = m['asset_data'] layout.label(text=str(ad['name'])) - layout.label(text='Ratings:') - draw_panel_material_ratings(self, context) layout.label(text='Asset tools:') draw_asset_context_menu(self.layout, context, ad, from_panel=True) @@ -1390,6 +1386,7 @@ def label_or_url(layout, text='', tooltip='', url='', icon_value=None, icon=None else: op = layout.operator('wm.blenderkit_tooltip', text=text) op.tooltip = tooltip + # these are here to move the text to left, since operators can only center text by default layout.label(text='') layout.label(text='') return @@ -1439,6 +1436,10 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): parameter = utils.get_param(self.asset_data, key) if parameter == None: return + if type(parameter) == int: + parameter = f"{parameter:,d}" + elif type(parameter) == float: + parameter = f"{parameter:,.1f}" self.draw_property(layout, pretext, parameter) def draw_properties(self, layout, width=250): @@ -1458,10 +1459,11 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): pcoll = icons.icon_collections["main"] box = layout.box() + box.scale_y = 0.8 box.label(text='Properties') if self.asset_data.get('license') == 'cc_zero': - t = 'CC Zero' + t = 'CC Zero ' icon = pcoll['cc0'] else: @@ -1508,29 +1510,32 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): ) # resolution/s - # fs = self.asset_data['files'] - # - # if fs and len(fs) > 2: - # resolutions = '' - # list.sort(fs, key=lambda f: f['fileType']) - # for f in fs: - # if f['fileType'].find('resolution') > -1: - # resolutions += f['fileType'][11:] + ' ' - # resolutions = resolutions.replace('_', '.') - # self.draw_property(box, 'Resolutions:', resolutions) resolution = utils.get_param(self.asset_data, 'textureResolutionMax') + if resolution is not None: + fs = self.asset_data['files'] + ress = f"{int(round(resolution / 1024, 0))}K" self.draw_property(box, 'Resolution', ress, tooltip='Maximal resolution of textures in this asset.\n' \ 'Most texture asset have also lower resolutions generated.\n' \ 'Go to BlenderKit add-on import settings to set default resolution') + if fs and len(fs) > 2 and utils.profile_is_validator(): + resolutions = '' + list.sort(fs, key=lambda f: f['fileType']) + for f in fs: + if f['fileType'].find('resolution') > -1: + resolutions += f['fileType'][11:] + ' ' + resolutions = resolutions.replace('_', '.') + self.draw_property(box, 'Generated:', resolutions) + self.draw_asset_parameter(box, key='designer', pretext='Designer') self.draw_asset_parameter(box, key='manufacturer', pretext='Manufacturer') # TODO make them clickable! self.draw_asset_parameter(box, key='designCollection', pretext='Collection') self.draw_asset_parameter(box, key='designVariant', pretext='Variant') self.draw_asset_parameter(box, key='designYear', pretext='Design year') + self.draw_asset_parameter(box, key='faceCount', pretext='Face count') # self.draw_asset_parameter(box, key='thumbnailScale', pretext='Preview scale') # self.draw_asset_parameter(box, key='purePbr', pretext='Pure PBR') @@ -1544,6 +1549,14 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): utils.fmt_length(mparams['dimensionY']), utils.fmt_length(mparams['dimensionZ'])) self.draw_property(box, 'Size:', t) + if self.asset_data.get('filesSize'): + fs = self.asset_data['filesSize'] + fsmb = fs // (1024 * 1024) + fskb = fs % 1024 + if fsmb == 0: + self.draw_property(box, 'Original size:', f'{fskb}KB') + else: + self.draw_property(box, 'Original size:', f'{fsmb}MB') # Tags section # row = box.row() # letters_on_row = 0 @@ -1597,6 +1610,10 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): icon_value=icon.icon_id, tooltip=plans_tooltip, url=plans_link) + if utils.profile_is_validator(): + date = self.asset_data['created'][:10] + date = f"{date[8:10]}. {date[5:7]}. {date[:4]}" + self.draw_property(box, 'Created:', date) def draw_author_area(self, context, layout, width=330): self.draw_author(context, layout, width=width) @@ -1741,7 +1758,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() - top_drag_bar.label(text=asset_data['displayName']) + aname = asset_data['displayName'] + aname = aname[0].upper() + aname[1:] + top_drag_bar.label(text=aname) # left side row = layout.row(align=True) @@ -1755,8 +1774,7 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): self.draw_menu_desc_author(context, split_right, width=int(self.width * split_ratio)) ratings_box = layout.box() - ratings_box.scale_y = 0.7 - ratings_box.label(text='Rate asset quality:') + ratings.draw_ratings_menu(self, context, ratings_box) tip_box = layout.box() tip_box.label(text=self.tip) @@ -1781,6 +1799,10 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties): bl_label = asset_data['name'] self.tip = search.get_random_tip() self.tip = self.tip.replace('\n', '') + + # pre-fill ratings + self.prefill_ratings() + return wm.invoke_popup(self, width=self.width) |