BlenderKit: improve right click menu
-basically a complete revamp of the code, enables to display asset information in a much cleaner way with more tooltips e.t.c. -simplified floating asset preview - name needs to be fixed still, and tooltip generation cleaned -added several new icons, deleted one unused -improve a lot of tooltips -fix rerender of thumbnails in unsaved files (would save assets into addon directory) -reorganize some rating functions into ratings_utils.py -new 'wrap' operator for web links, allows to have custom tooltips for each link
This commit is contained in:
parent
452996ae95
commit
e670cee075
|
@ -49,6 +49,7 @@ if "bpy" in locals():
|
|||
overrides = reload(overrides)
|
||||
paths = reload(paths)
|
||||
ratings = reload(ratings)
|
||||
ratings_utils = reload(ratings_utils)
|
||||
resolutions = reload(resolutions)
|
||||
search = reload(search)
|
||||
tasks_queue = reload(tasks_queue)
|
||||
|
@ -84,6 +85,7 @@ else:
|
|||
from blenderkit import overrides
|
||||
from blenderkit import paths
|
||||
from blenderkit import ratings
|
||||
from blenderkit import ratings_utils
|
||||
from blenderkit import resolutions
|
||||
from blenderkit import search
|
||||
from blenderkit import tasks_queue
|
||||
|
@ -731,20 +733,20 @@ class BlenderKitRatingProps(PropertyGroup):
|
|||
description="quality of the material",
|
||||
default=0,
|
||||
min=-1, max=10,
|
||||
update=ratings.update_ratings_quality)
|
||||
update=ratings_utils.update_ratings_quality)
|
||||
|
||||
# the following enum is only to ease interaction - enums support 'drag over' and enable to draw the stars easily.
|
||||
rating_quality_ui: EnumProperty(name='rating_quality_ui',
|
||||
items=ratings.stars_enum_callback,
|
||||
items=ratings_utils.stars_enum_callback,
|
||||
description='Rating stars 0 - 10',
|
||||
default=None,
|
||||
update=ratings.update_quality_ui,
|
||||
update=ratings_utils.update_quality_ui,
|
||||
)
|
||||
|
||||
rating_work_hours: FloatProperty(name="Work Hours",
|
||||
description="How many hours did this work take?",
|
||||
default=0.00,
|
||||
min=0.0, max=150, update=ratings.update_ratings_work_hours
|
||||
min=0.0, max=150, update=ratings_utils.update_ratings_work_hours
|
||||
)
|
||||
|
||||
# rating_complexity: IntProperty(name="Complexity",
|
||||
|
|
|
@ -225,9 +225,9 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
self.asset_name = name_label
|
||||
self.tooltip_widgets.append(name_label)
|
||||
offset_y = 16 + self.margin
|
||||
label = self.new_text('Left click or drag to append/link. Right click for more options.', self.assetbar_margin*2, labels_start + offset_y,
|
||||
text_size=14)
|
||||
self.tooltip_widgets.append(label)
|
||||
# label = self.new_text('Left click or drag to append/link. Right click for more options.', self.assetbar_margin*2, labels_start + offset_y,
|
||||
# text_size=14)
|
||||
# self.tooltip_widgets.append(label)
|
||||
|
||||
|
||||
self.hide_tooltip()
|
||||
|
@ -505,6 +505,9 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
# handlers
|
||||
|
||||
def enter_button(self, widget):
|
||||
# context.window.cursor_warp(event.mouse_x, event.mouse_y - 20);
|
||||
|
||||
|
||||
self.show_tooltip()
|
||||
|
||||
if self.active_index != widget.search_index:
|
||||
|
@ -532,6 +535,8 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
|
|||
|
||||
self.tooltip_panel.update(tooltip_x, widget.y_screen + widget.height)
|
||||
self.tooltip_panel.layout_widgets()
|
||||
# bpy.ops.wm.blenderkit_asset_popup('INVOKE_DEFAULT')
|
||||
|
||||
|
||||
def exit_button(self, widget):
|
||||
# this condition checks if there wasn't another button already entered, which can happen with small button gaps
|
||||
|
|
|
@ -156,7 +156,7 @@ def start_thumbnailer(self=None, json_args=None, props=None, wait=False, add_bg_
|
|||
eval_path_state = "bpy.data.objects['%s'].blenderkit.thumbnail_generating_state" % json_args['asset_name']
|
||||
eval_path = "bpy.data.objects['%s']" % json_args['asset_name']
|
||||
|
||||
bg_blender.add_bg_process(eval_path_computing=eval_path_computing, eval_path_state=eval_path_state,
|
||||
bg_blender.add_bg_process(name = f"{json_args['asset_name']} thumbnailer" ,eval_path_computing=eval_path_computing, eval_path_state=eval_path_state,
|
||||
eval_path=eval_path, process_type='THUMBNAILER', process=proc)
|
||||
|
||||
|
||||
|
@ -206,7 +206,7 @@ def start_material_thumbnailer(self=None, json_args=None, props=None, wait=False
|
|||
eval_path_state = "bpy.data.materials['%s'].blenderkit.thumbnail_generating_state" % json_args['asset_name']
|
||||
eval_path = "bpy.data.materials['%s']" % json_args['asset_name']
|
||||
|
||||
bg_blender.add_bg_process(name=json_args['asset_name'], eval_path_computing=eval_path_computing,
|
||||
bg_blender.add_bg_process(name=f"{json_args['asset_name']} thumbnailer", eval_path_computing=eval_path_computing,
|
||||
eval_path_state=eval_path_state,
|
||||
eval_path=eval_path, process_type='THUMBNAILER', process=proc)
|
||||
if props:
|
||||
|
@ -328,7 +328,10 @@ class GenerateThumbnailOperator(bpy.types.Operator):
|
|||
|
||||
|
||||
class ReGenerateThumbnailOperator(bpy.types.Operator):
|
||||
"""Generate Cycles thumbnail for model assets"""
|
||||
"""
|
||||
Generate default thumbnail with Cycles renderer and upload it.
|
||||
Works also for assets from search results, without being downloaded before.
|
||||
"""
|
||||
bl_idname = "object.blenderkit_regenerate_thumbnail"
|
||||
bl_label = "BlenderKit Thumbnail Re-generate"
|
||||
bl_options = {'REGISTER', 'INTERNAL'}
|
||||
|
@ -371,11 +374,9 @@ class ReGenerateThumbnailOperator(bpy.types.Operator):
|
|||
return True # bpy.context.view_layer.objects.active is not None
|
||||
|
||||
def draw(self, context):
|
||||
ob = bpy.context.active_object
|
||||
while ob.parent is not None:
|
||||
ob = ob.parent
|
||||
props = self
|
||||
layout = self.layout
|
||||
# layout.label('This will re-generate thumbnail and directly upload it to server. You should see your updated thumbnail online depending ')
|
||||
layout.label(text='thumbnailer settings')
|
||||
layout.prop(props, 'thumbnail_background_lightness')
|
||||
layout.prop(props, 'thumbnail_angle')
|
||||
|
@ -521,7 +522,7 @@ class GenerateMaterialThumbnailOperator(bpy.types.Operator):
|
|||
|
||||
class ReGenerateMaterialThumbnailOperator(bpy.types.Operator):
|
||||
"""
|
||||
Generate default thumbnail with Cycles renderer.
|
||||
Generate default thumbnail with Cycles renderer and upload it.
|
||||
Works also for assets from search results, without being downloaded before.
|
||||
"""
|
||||
bl_idname = "object.blenderkit_regenerate_material_thumbnail"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
from blenderkit import utils, append_link, bg_blender, upload_bg, download
|
||||
|
||||
import sys, json, math
|
||||
import sys, json, math, os
|
||||
import bpy
|
||||
from pathlib import Path
|
||||
|
||||
|
@ -48,6 +48,10 @@ if __name__ == "__main__":
|
|||
data = json.load(s)
|
||||
# append_material(file_name, matname = None, link = False, fake_user = True)
|
||||
if data.get('do_download'):
|
||||
#need to save the file, so that asset doesn't get downloaded into addon directory
|
||||
temp_blend_path = os.path.join(data['tempdir'], 'temp.blend')
|
||||
bpy.ops.wm.save_as_mainfile(filepath=temp_blend_path)
|
||||
|
||||
asset_data = data['asset_data']
|
||||
has_url = download.get_download_url(asset_data, download.get_scene_id(), user_preferences.api_key, tcom=None,
|
||||
resolution='blend')
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
|
||||
from blenderkit import utils, append_link, bg_blender, download, upload_bg
|
||||
|
||||
import sys, json, math
|
||||
from pathlib import Path
|
||||
import sys, json, math, os
|
||||
import bpy
|
||||
import mathutils
|
||||
|
||||
|
@ -86,8 +85,11 @@ if __name__ == "__main__":
|
|||
|
||||
|
||||
if data.get('do_download'):
|
||||
bg_blender.progress('Downloading asset')
|
||||
#need to save the file, so that asset doesn't get downloaded into addon directory
|
||||
temp_blend_path = os.path.join(data['tempdir'], 'temp.blend')
|
||||
bpy.ops.wm.save_as_mainfile(filepath = temp_blend_path)
|
||||
|
||||
bg_blender.progress('Downloading asset')
|
||||
asset_data = data['asset_data']
|
||||
has_url = download.get_download_url(asset_data, download.get_scene_id(), user_preferences.api_key, tcom=None,
|
||||
resolution='blend')
|
||||
|
|
|
@ -27,9 +27,23 @@ icon_collections = {}
|
|||
icons_read = {
|
||||
'fp.png': 'free',
|
||||
'flp.png': 'full',
|
||||
'test.jpg': 'test',
|
||||
'trophy.png': 'trophy',
|
||||
'cc0.png': 'cc0',
|
||||
'royalty_free.png': 'royalty_free',
|
||||
}
|
||||
|
||||
verification_icons = {
|
||||
'vs_ready.png':'ready',
|
||||
'vs_deleted.png':'deleted' ,
|
||||
'vs_uploaded.png': 'uploaded',
|
||||
'vs_uploading.png': 'uploading',
|
||||
'vs_on_hold.png': 'on_hold',
|
||||
'vs_validated.png': 'validated',
|
||||
'vs_rejected.png': 'rejected'
|
||||
|
||||
}
|
||||
|
||||
icons_read.update(verification_icons)
|
||||
|
||||
def register_icons():
|
||||
# Note that preview collections returned by bpy.utils.previews
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
from blenderkit import paths, utils, rerequests, tasks_queue
|
||||
from blenderkit import paths, utils, rerequests, tasks_queue, ratings_utils
|
||||
|
||||
import bpy
|
||||
import requests, threading
|
||||
|
@ -103,42 +103,6 @@ def get_rating(asset_id):
|
|||
print(r.text)
|
||||
|
||||
|
||||
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:
|
||||
bkit_ratings = asset.bkit_ratings
|
||||
url = paths.get_api_url() + 'assets/' + asset['asset_data']['id'] + '/rating/'
|
||||
else:
|
||||
# this part is for operator rating:
|
||||
bkit_ratings = self
|
||||
url = paths.get_api_url() + f'assets/{self.asset_id}/rating/'
|
||||
|
||||
if bkit_ratings.rating_quality > 0.1:
|
||||
ratings = [('quality', bkit_ratings.rating_quality)]
|
||||
tasks_queue.add_task((send_rating_to_thread_quality, (url, ratings, headers)), wait=2.5, only_last=True)
|
||||
|
||||
|
||||
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:
|
||||
bkit_ratings = asset.bkit_ratings
|
||||
url = paths.get_api_url() + 'assets/' + asset['asset_data']['id'] + '/rating/'
|
||||
else:
|
||||
# this part is for operator rating:
|
||||
bkit_ratings = self
|
||||
url = paths.get_api_url() + f'assets/{self.asset_id}/rating/'
|
||||
|
||||
if bkit_ratings.rating_work_hours > 0.45:
|
||||
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)
|
||||
|
||||
|
||||
def upload_rating(asset):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
|
@ -242,69 +206,40 @@ class UploadRatingOperator(bpy.types.Operator):
|
|||
return wm.invoke_props_dialog(self)
|
||||
|
||||
|
||||
def stars_enum_callback(self, context):
|
||||
'''regenerates the enum property used to display rating stars, so that there are filled/empty stars correctly.'''
|
||||
items = []
|
||||
for a in range(0, 10):
|
||||
if self.rating_quality < a + 1:
|
||||
icon = 'SOLO_OFF'
|
||||
else:
|
||||
icon = 'SOLO_ON'
|
||||
# has to have something before the number in the value, otherwise fails on registration.
|
||||
items.append((f'{a + 1}', f'{a + 1}', '', icon, a + 1))
|
||||
return items
|
||||
|
||||
def draw_ratings_menu(self, context, layout):
|
||||
col = layout.column()
|
||||
# layout.template_icon_view(bkit_ratings, property, show_labels=False, scale=6.0, scale_popup=5.0)
|
||||
row = col.row()
|
||||
row.prop(self, 'rating_quality_ui', expand=True, icon_only=True, emboss=False)
|
||||
# row.label(text=str(self.rating_quality))
|
||||
col.separator()
|
||||
|
||||
def update_quality_ui(self, context):
|
||||
'''Converts the _ui the enum into actual quality number.'''
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
if user_preferences.api_key == '':
|
||||
# ui_panels.draw_not_logged_in(self, message='Please login/signup to rate assets.')
|
||||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_login_menu')
|
||||
# return
|
||||
bpy.ops.wm.blenderkit_login('INVOKE_DEFAULT',
|
||||
message='Please login/signup to rate assets. Clicking OK takes you to web login.')
|
||||
# self.rating_quality_ui = '0'
|
||||
self.rating_quality = int(self.rating_quality_ui)
|
||||
row = layout.row()
|
||||
row.label(text=f"How many hours did this {self.asset_type} save you?")
|
||||
|
||||
if self.asset_type in ('model', 'scene'):
|
||||
row = layout.row()
|
||||
if utils.profile_is_validator():
|
||||
col.prop(self, 'rating_work_hours')
|
||||
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,
|
||||
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()
|
||||
|
||||
def update_ratings_work_hours_ui(self, context):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
if user_preferences.api_key == '':
|
||||
# ui_panels.draw_not_logged_in(self, message='Please login/signup to rate assets.')
|
||||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_login_menu')
|
||||
# return
|
||||
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 = '0'
|
||||
self.rating_work_hours = float(self.rating_work_hours_ui)
|
||||
utils.label_multiline(layout,
|
||||
text=f"\nThat's a lot! please be sure to give such rating only to amazing {self.asset_type}s.\n",
|
||||
width=500)
|
||||
|
||||
|
||||
def update_ratings_work_hours_ui_1_5(self, context):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
if user_preferences.api_key == '':
|
||||
# ui_panels.draw_not_logged_in(self, message='Please login/signup to rate assets.')
|
||||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_login_menu')
|
||||
# return
|
||||
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)
|
||||
|
||||
def update_ratings_work_hours_ui_1_10(self, context):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
if user_preferences.api_key == '':
|
||||
# ui_panels.draw_not_logged_in(self, message='Please login/signup to rate assets.')
|
||||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_login_menu')
|
||||
# return
|
||||
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_10)
|
||||
elif self.asset_type == 'hdr':
|
||||
row = layout.row()
|
||||
row.prop(self, 'rating_work_hours_ui_1_10', expand=True, icon_only=False, emboss=True)
|
||||
else:
|
||||
row = layout.row()
|
||||
row.prop(self, 'rating_work_hours_ui_1_5', expand=True, icon_only=False, emboss=True)
|
||||
|
||||
|
||||
class FastRateMenu(Operator):
|
||||
|
@ -341,22 +276,22 @@ class FastRateMenu(Operator):
|
|||
description="quality of the material",
|
||||
default=0,
|
||||
min=-1, max=10,
|
||||
# update=update_ratings_quality,
|
||||
# update=ratings_utils.update_ratings_quality,
|
||||
options={'SKIP_SAVE'})
|
||||
|
||||
# the following enum is only to ease interaction - enums support 'drag over' and enable to draw the stars easily.
|
||||
rating_quality_ui: EnumProperty(name='rating_quality_ui',
|
||||
items=stars_enum_callback,
|
||||
items=ratings_utils.stars_enum_callback,
|
||||
description='Rating stars 0 - 10',
|
||||
default=0,
|
||||
update=update_quality_ui,
|
||||
update=ratings_utils.update_quality_ui,
|
||||
options={'SKIP_SAVE'})
|
||||
|
||||
rating_work_hours: FloatProperty(name="Work Hours",
|
||||
description="How many hours did this work take?",
|
||||
default=0.00,
|
||||
min=0.0, max=300,
|
||||
# update=update_ratings_work_hours,
|
||||
# update=ratings_utils.update_ratings_work_hours,
|
||||
options={'SKIP_SAVE'}
|
||||
)
|
||||
|
||||
|
@ -383,8 +318,8 @@ class FastRateMenu(Operator):
|
|||
('200', '200', high_rating_warning),
|
||||
('250', '250', high_rating_warning),
|
||||
],
|
||||
default='0', update=update_ratings_work_hours_ui,
|
||||
options = {'SKIP_SAVE'}
|
||||
default='0', update=ratings_utils.update_ratings_work_hours_ui,
|
||||
options={'SKIP_SAVE'}
|
||||
)
|
||||
|
||||
rating_work_hours_ui_1_5: EnumProperty(name="Work Hours",
|
||||
|
@ -399,28 +334,28 @@ class FastRateMenu(Operator):
|
|||
('5', '5', '')
|
||||
],
|
||||
default='0',
|
||||
update=update_ratings_work_hours_ui_1_5,
|
||||
options = {'SKIP_SAVE'}
|
||||
update=ratings_utils.update_ratings_work_hours_ui_1_5,
|
||||
options={'SKIP_SAVE'}
|
||||
)
|
||||
|
||||
rating_work_hours_ui_1_10: EnumProperty(name="Work Hours",
|
||||
description="How many hours did this work take?",
|
||||
items=[('0', '0', ''),
|
||||
('1', '1', ''),
|
||||
('2', '2', ''),
|
||||
('3', '3', ''),
|
||||
('4', '4', ''),
|
||||
('5', '5', ''),
|
||||
('6', '6', ''),
|
||||
('7', '7', ''),
|
||||
('8', '8', ''),
|
||||
('9', '9', ''),
|
||||
('10', '10', '')
|
||||
],
|
||||
default='0',
|
||||
update=update_ratings_work_hours_ui_1_10,
|
||||
options={'SKIP_SAVE'}
|
||||
)
|
||||
description="How many hours did this work take?",
|
||||
items=[('0', '0', ''),
|
||||
('1', '1', ''),
|
||||
('2', '2', ''),
|
||||
('3', '3', ''),
|
||||
('4', '4', ''),
|
||||
('5', '5', ''),
|
||||
('6', '6', ''),
|
||||
('7', '7', ''),
|
||||
('8', '8', ''),
|
||||
('9', '9', ''),
|
||||
('10', '10', '')
|
||||
],
|
||||
default='0',
|
||||
update=ratings_utils.update_ratings_work_hours_ui_1_10,
|
||||
options={'SKIP_SAVE'}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@ -430,41 +365,9 @@ class FastRateMenu(Operator):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
col = layout.column()
|
||||
|
||||
# layout.template_icon_view(bkit_ratings, property, show_labels=False, scale=6.0, scale_popup=5.0)
|
||||
col.label(text=self.message)
|
||||
row = col.row()
|
||||
row.prop(self, 'rating_quality_ui', expand=True, icon_only=True, emboss=False)
|
||||
# row.label(text=str(self.rating_quality))
|
||||
col.separator()
|
||||
|
||||
row = layout.row()
|
||||
row.label(text=f"How many hours did this {self.asset_type} save you?")
|
||||
|
||||
if self.asset_type in ('model', 'scene'):
|
||||
row = layout.row()
|
||||
if utils.profile_is_validator():
|
||||
col.prop(self, 'rating_work_hours')
|
||||
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,
|
||||
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()
|
||||
|
||||
utils.label_multiline(layout,
|
||||
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.prop(self, 'rating_work_hours_ui_1_10', expand=True, icon_only=False, emboss=True)
|
||||
else:
|
||||
row = layout.row()
|
||||
row.prop(self, 'rating_work_hours_ui_1_5', expand=True, icon_only=False, emboss=True)
|
||||
layout.label(text=self.message)
|
||||
|
||||
draw_ratings_menu(self, context, layout)
|
||||
|
||||
def execute(self, context):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
|
@ -505,7 +408,7 @@ class FastRateMenu(Operator):
|
|||
self.message = f"Rate asset {self.asset_name}"
|
||||
wm = context.window_manager
|
||||
|
||||
if self.asset_type in ('model','scene'):
|
||||
if self.asset_type in ('model', 'scene'):
|
||||
# spawn a wider one for validators for the enum buttons
|
||||
return wm.invoke_props_dialog(self, width=500)
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
#mainly update functions and callbacks for ratings properties, here to avoid circular imports.
|
||||
import bpy
|
||||
|
||||
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:
|
||||
bkit_ratings = asset.bkit_ratings
|
||||
url = paths.get_api_url() + 'assets/' + asset['asset_data']['id'] + '/rating/'
|
||||
else:
|
||||
# this part is for operator rating:
|
||||
bkit_ratings = self
|
||||
url = paths.get_api_url() + f'assets/{self.asset_id}/rating/'
|
||||
|
||||
if bkit_ratings.rating_quality > 0.1:
|
||||
ratings = [('quality', bkit_ratings.rating_quality)]
|
||||
tasks_queue.add_task((send_rating_to_thread_quality, (url, ratings, headers)), wait=2.5, only_last=True)
|
||||
|
||||
|
||||
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:
|
||||
bkit_ratings = asset.bkit_ratings
|
||||
url = paths.get_api_url() + 'assets/' + asset['asset_data']['id'] + '/rating/'
|
||||
else:
|
||||
# this part is for operator rating:
|
||||
bkit_ratings = self
|
||||
url = paths.get_api_url() + f'assets/{self.asset_id}/rating/'
|
||||
|
||||
if bkit_ratings.rating_work_hours > 0.45:
|
||||
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)
|
||||
|
||||
def update_quality_ui(self, context):
|
||||
'''Converts the _ui the enum into actual quality number.'''
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
if user_preferences.api_key == '':
|
||||
# ui_panels.draw_not_logged_in(self, message='Please login/signup to rate assets.')
|
||||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_login_menu')
|
||||
# return
|
||||
bpy.ops.wm.blenderkit_login('INVOKE_DEFAULT',
|
||||
message='Please login/signup to rate assets. Clicking OK takes you to web login.')
|
||||
# self.rating_quality_ui = '0'
|
||||
self.rating_quality = int(self.rating_quality_ui)
|
||||
|
||||
|
||||
def update_ratings_work_hours_ui(self, context):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
if user_preferences.api_key == '':
|
||||
# ui_panels.draw_not_logged_in(self, message='Please login/signup to rate assets.')
|
||||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_login_menu')
|
||||
# return
|
||||
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 = '0'
|
||||
self.rating_work_hours = float(self.rating_work_hours_ui)
|
||||
|
||||
|
||||
def update_ratings_work_hours_ui_1_5(self, context):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
if user_preferences.api_key == '':
|
||||
# ui_panels.draw_not_logged_in(self, message='Please login/signup to rate assets.')
|
||||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_login_menu')
|
||||
# return
|
||||
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)
|
||||
|
||||
|
||||
def update_ratings_work_hours_ui_1_10(self, context):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
if user_preferences.api_key == '':
|
||||
# ui_panels.draw_not_logged_in(self, message='Please login/signup to rate assets.')
|
||||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_login_menu')
|
||||
# return
|
||||
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_10)
|
||||
|
||||
|
||||
def stars_enum_callback(self, context):
|
||||
'''regenerates the enum property used to display rating stars, so that there are filled/empty stars correctly.'''
|
||||
items = []
|
||||
for a in range(0, 10):
|
||||
if self.rating_quality < a + 1:
|
||||
icon = 'SOLO_OFF'
|
||||
else:
|
||||
icon = 'SOLO_ON'
|
||||
# has to have something before the number in the value, otherwise fails on registration.
|
||||
items.append((f'{a + 1}', f'{a + 1}', '', icon, a + 1))
|
||||
return items
|
|
@ -572,10 +572,6 @@ def writeblockm(tooltip, mdata, key='', pretext=None, width=40): # for longer t
|
|||
return tooltip
|
||||
|
||||
|
||||
def fmt_length(prop):
|
||||
prop = str(round(prop, 2))
|
||||
return prop
|
||||
|
||||
|
||||
def has(mdata, prop):
|
||||
if mdata.get(prop) is not None and mdata[prop] is not None and mdata[prop] is not False:
|
||||
|
@ -583,8 +579,152 @@ def has(mdata, prop):
|
|||
else:
|
||||
return False
|
||||
|
||||
|
||||
def generate_tooltip(mdata):
|
||||
col_w = 40
|
||||
if type(mdata['parameters']) == list:
|
||||
mparams = utils.params_to_dict(mdata['parameters'])
|
||||
else:
|
||||
mparams = mdata['parameters']
|
||||
t = ''
|
||||
# t = writeblock(t, mdata['displayName'], width=col_w)
|
||||
# t += '\n'
|
||||
|
||||
t = writeblockm(t, mdata, key='description', pretext='', width=col_w)
|
||||
if mdata['description'] != '':
|
||||
t += '\n'
|
||||
|
||||
bools = (('rig', None), ('animated', None), ('manifold', 'non-manifold'), ('scene', None), ('simulation', None),
|
||||
('uv', None))
|
||||
for b in bools:
|
||||
if mparams.get(b[0]):
|
||||
mdata['tags'].append(b[0])
|
||||
elif b[1] != None:
|
||||
mdata['tags'].append(b[1])
|
||||
|
||||
bools_data = ('adult',)
|
||||
for b in bools_data:
|
||||
if mdata.get(b) and mdata[b]:
|
||||
mdata['tags'].append(b)
|
||||
t = writeblockm(t, mparams, key='designer', pretext='Designer', width=col_w)
|
||||
t = writeblockm(t, mparams, key='manufacturer', pretext='Manufacturer', width=col_w)
|
||||
t = writeblockm(t, mparams, key='designCollection', pretext='Design collection', width=col_w)
|
||||
|
||||
# t = writeblockm(t, mparams, key='engines', pretext='engine', width = col_w)
|
||||
# t = writeblockm(t, mparams, key='model_style', pretext='style', width = col_w)
|
||||
# t = writeblockm(t, mparams, key='material_style', pretext='style', width = col_w)
|
||||
# t = writeblockm(t, mdata, key='tags', width = col_w)
|
||||
# t = writeblockm(t, mparams, key='condition', pretext='condition', width = col_w)
|
||||
# t = writeblockm(t, mparams, key='productionLevel', pretext='production level', width = col_w)
|
||||
if has(mdata, 'purePbr'):
|
||||
t = writeblockm(t, mparams, key='pbrType', pretext='Pbr', width=col_w)
|
||||
|
||||
t = writeblockm(t, mparams, key='designYear', pretext='Design year', width=col_w)
|
||||
|
||||
if has(mparams, 'dimensionX'):
|
||||
t += 'Size: %s × %s × %s m\n' % (utils.fmt_length(mparams['dimensionX']),
|
||||
utils.fmt_length(mparams['dimensionY']),
|
||||
utils.fmt_length(mparams['dimensionZ']))
|
||||
if has(mparams, 'faceCount') and mdata['assetType'] == 'model':
|
||||
t += 'Face count: %s\n' % (mparams['faceCount'])
|
||||
# t += 'face count: %s, render: %s\n' % (mparams['faceCount'], mparams['faceCountRender'])
|
||||
|
||||
# write files size - this doesn't reflect true file size, since files size is computed from all asset files, including resolutions.
|
||||
# if mdata.get('filesSize'):
|
||||
# fs = utils.files_size_to_text(mdata['filesSize'])
|
||||
# t += f'files size: {fs}\n'
|
||||
|
||||
# t = writeblockm(t, mparams, key='meshPolyType', pretext='mesh type', width = col_w)
|
||||
# t = writeblockm(t, mparams, key='objectCount', pretext='nubmber of objects', width = col_w)
|
||||
|
||||
# t = writeblockm(t, mparams, key='materials', width = col_w)
|
||||
# t = writeblockm(t, mparams, key='modifiers', width = col_w)
|
||||
# t = writeblockm(t, mparams, key='shaders', width = col_w)
|
||||
|
||||
# if has(mparams, 'textureSizeMeters'):
|
||||
# t += 'Texture size: %s m\n' % utils.fmt_length(mparams['textureSizeMeters'])
|
||||
|
||||
if has(mparams, 'textureResolutionMax') and mparams['textureResolutionMax'] > 0:
|
||||
if not mparams.get('textureResolutionMin'): # for HDR's
|
||||
t = writeblockm(t, mparams, key='textureResolutionMax', pretext='Resolution', width=col_w)
|
||||
elif mparams.get('textureResolutionMin') == mparams['textureResolutionMax']:
|
||||
t = writeblockm(t, mparams, key='textureResolutionMin', pretext='Texture resolution', width=col_w)
|
||||
else:
|
||||
t += 'Tex resolution: %i - %i\n' % (mparams.get('textureResolutionMin'), mparams['textureResolutionMax'])
|
||||
|
||||
if has(mparams, 'thumbnailScale'):
|
||||
t = writeblockm(t, mparams, key='thumbnailScale', pretext='Preview scale', width=col_w)
|
||||
|
||||
# t += 'uv: %s\n' % mdata['uv']
|
||||
# t += '\n'
|
||||
if mdata.get('license') == 'cc_zero':
|
||||
t+= 'license: CC Zero\n'
|
||||
else:
|
||||
t+= 'license: Royalty free\n'
|
||||
# t = writeblockm(t, mdata, key='license', width=col_w)
|
||||
|
||||
fs = mdata.get('files')
|
||||
|
||||
if utils.profile_is_validator():
|
||||
if fs and len(fs) > 2:
|
||||
resolutions = 'Resolutions:'
|
||||
list.sort(fs, key=lambda f: f['fileType'])
|
||||
for f in fs:
|
||||
if f['fileType'].find('resolution') > -1:
|
||||
resolutions += f['fileType'][11:] + ' '
|
||||
resolutions += '\n'
|
||||
t += resolutions.replace('_', '.')
|
||||
|
||||
# if mdata['isFree']:
|
||||
# t += 'Free plan\n'
|
||||
# else:
|
||||
# t += 'Full plan\n'
|
||||
else:
|
||||
if fs:
|
||||
for f in fs:
|
||||
if f['fileType'].find('resolution') > -1:
|
||||
t += 'Asset has lower resolutions available\n'
|
||||
break;
|
||||
|
||||
# generator is for both upload preview and search, this is only after search
|
||||
# if mdata.get('versionNumber'):
|
||||
# # t = writeblockm(t, mdata, key='versionNumber', pretext='version', width = col_w)
|
||||
# a_id = mdata['author'].get('id')
|
||||
# if a_id != None:
|
||||
# adata = bpy.context.window_manager['bkit authors'].get(str(a_id))
|
||||
# if adata != None:
|
||||
# t += generate_author_textblock(adata)
|
||||
|
||||
|
||||
# t += '\n'
|
||||
# rc = mdata.get('ratingsCount')
|
||||
# if rc:
|
||||
# t+='\n'
|
||||
# if rc:
|
||||
# rcount = min(rc['quality'], rc['workingHours'])
|
||||
# else:
|
||||
# rcount = 0
|
||||
#
|
||||
# show_rating_threshold = 5
|
||||
#
|
||||
# if rcount < show_rating_threshold and mdata['assetType'] != 'hdr':
|
||||
# t += f"Only assets with enough ratings \nshow the rating value. Please rate.\n"
|
||||
# if rc['quality'] >= show_rating_threshold:
|
||||
# # t += f"{int(mdata['ratingsAverage']['quality']) * '*'}\n"
|
||||
# t += f"* {round(mdata['ratingsAverage']['quality'],1)}\n"
|
||||
# if rc['workingHours'] >= show_rating_threshold:
|
||||
# t += f"Hours saved: {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'],1)}*/{(mdata['ratingsAverage']['workingHours'],1)}wh\n"
|
||||
# if len(t.split('\n')) < 11:
|
||||
# t += '\n'
|
||||
# t += get_random_tip(mdata)
|
||||
# t += '\n'
|
||||
return t
|
||||
|
||||
def generate_tooltip_old(mdata):
|
||||
col_w = 40
|
||||
if type(mdata['parameters']) == list:
|
||||
mparams = utils.params_to_dict(mdata['parameters'])
|
||||
|
@ -626,9 +766,9 @@ def generate_tooltip(mdata):
|
|||
t = writeblockm(t, mparams, key='designYear', pretext='Design year', width=col_w)
|
||||
|
||||
if has(mparams, 'dimensionX'):
|
||||
t += 'Size: %s x %s x %sm\n' % (fmt_length(mparams['dimensionX']),
|
||||
fmt_length(mparams['dimensionY']),
|
||||
fmt_length(mparams['dimensionZ']))
|
||||
t += 'Size: %s x %s x %sm\n' % (utils.fmt_length(mparams['dimensionX']),
|
||||
utils.fmt_length(mparams['dimensionY']),
|
||||
utils.fmt_length(mparams['dimensionZ']))
|
||||
if has(mparams, 'faceCount') and mdata['assetType'] == 'model':
|
||||
t += 'Face count: %s\n' % (mparams['faceCount'])
|
||||
# t += 'face count: %s, render: %s\n' % (mparams['faceCount'], mparams['faceCountRender'])
|
||||
|
@ -646,7 +786,7 @@ def generate_tooltip(mdata):
|
|||
# t = writeblockm(t, mparams, key='shaders', width = col_w)
|
||||
|
||||
# if has(mparams, 'textureSizeMeters'):
|
||||
# t += 'Texture size: %s m\n' % fmt_length(mparams['textureSizeMeters'])
|
||||
# t += 'Texture size: %s m\n' % utils.fmt_length(mparams['textureSizeMeters'])
|
||||
|
||||
if has(mparams, 'textureResolutionMax') and mparams['textureResolutionMax'] > 0:
|
||||
if not mparams.get('textureResolutionMin'): # for HDR's
|
||||
|
@ -729,37 +869,24 @@ def generate_tooltip(mdata):
|
|||
return t
|
||||
|
||||
|
||||
def get_random_tip(mdata):
|
||||
def get_random_tip():
|
||||
t = ''
|
||||
|
||||
tip = 'Tip: ' + random.choice(rtips)
|
||||
t = writeblock(t, tip)
|
||||
return t
|
||||
# at = mdata['assetType']
|
||||
# if at == 'brush' or at == 'texture':
|
||||
# t += 'click to link %s' % mdata['assetType']
|
||||
# if at == 'model' or at == 'material':
|
||||
# tips = ['Click or drag in scene to link/append %s' % mdata['assetType'],
|
||||
# "'A' key to search assets by same author",
|
||||
# "'W' key to open Authors webpage",
|
||||
# ]
|
||||
# tip = 'Tip: ' + random.choice(tips)
|
||||
# t = writeblock(t, tip)
|
||||
return t
|
||||
|
||||
|
||||
def generate_author_textblock(adata):
|
||||
t = '\n\n\n'
|
||||
t = ''
|
||||
|
||||
if adata not in (None, ''):
|
||||
col_w = 40
|
||||
col_w = 2000
|
||||
if len(adata['firstName'] + adata['lastName']) > 0:
|
||||
t = 'Author:\n'
|
||||
t += '%s %s\n' % (adata['firstName'], adata['lastName'])
|
||||
t = 'Author: %s %s\n' % (adata['firstName'], adata['lastName'])
|
||||
t += '\n'
|
||||
if adata.get('aboutMeUrl') is not None:
|
||||
t = writeblockm(t, adata, key='aboutMeUrl', pretext='', width=col_w)
|
||||
t += '\n'
|
||||
# if adata.get('aboutMeUrl') is not None:
|
||||
# t = writeblockm(t, adata, key='aboutMeUrl', pretext='', width=col_w)
|
||||
# t += '\n'
|
||||
if adata.get('aboutMe') is not None:
|
||||
t = writeblockm(t, adata, key='aboutMe', pretext='', width=col_w)
|
||||
t += '\n'
|
||||
|
@ -1528,6 +1655,7 @@ class SearchOperator(Operator):
|
|||
bl_label = "BlenderKit asset search"
|
||||
bl_description = "Search online for assets"
|
||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||
|
||||
own: BoolProperty(name="own assets only",
|
||||
description="Find all own assets",
|
||||
default=False)
|
||||
|
@ -1559,6 +1687,12 @@ class SearchOperator(Operator):
|
|||
options={'SKIP_SAVE'}
|
||||
)
|
||||
|
||||
tooltip: bpy.props.StringProperty(default='Runs search and displays the asset bar at the same time')
|
||||
|
||||
@classmethod
|
||||
def description(cls, context, properties):
|
||||
return properties.tooltip
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
@ -1577,9 +1711,27 @@ class SearchOperator(Operator):
|
|||
|
||||
return {'FINISHED'}
|
||||
|
||||
class UrlOperator(Operator):
|
||||
""""""
|
||||
bl_idname = "wm.blenderkit_url"
|
||||
bl_label = ""
|
||||
bl_description = "Search online for assets"
|
||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||
|
||||
tooltip: bpy.props.StringProperty(default='Open a web page')
|
||||
url: bpy.props.StringProperty(default='Runs search and displays the asset bar at the same time')
|
||||
|
||||
@classmethod
|
||||
def description(cls, context, properties):
|
||||
return properties.tooltip
|
||||
|
||||
def execute(self,context):
|
||||
bpy.ops.wm.url_open(url=self.url)
|
||||
|
||||
|
||||
classes = [
|
||||
SearchOperator
|
||||
SearchOperator,
|
||||
UrlOperator
|
||||
]
|
||||
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 540 B |
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
|
@ -360,8 +360,10 @@ def draw_tooltip(x, y, text='', author='', img=None, gravatar=None):
|
|||
if gravatar is not None:
|
||||
# ui_bgl.draw_image(x + isizex - gsize - textmargin, y - isizey + texth - gsize - nameline_height - textmargin,
|
||||
# gsize, gsize, gravatar, 1)
|
||||
ui_bgl.draw_image(x + isizex / 2 + textmargin, y - isizey + texth - gsize - nameline_height - textmargin,
|
||||
gsize, gsize, gravatar, 1)
|
||||
# ui_bgl.draw_image(x + isizex / 2 + textmargin, y - isizey + texth - gsize - nameline_height - textmargin,
|
||||
# gsize, gsize, gravatar, 1)
|
||||
ui_bgl.draw_image(x + isizex / 2 + textmargin, y - isizey + texth - gsize - textmargin,
|
||||
gsize, gsize, gravatar, 1)
|
||||
|
||||
i = 0
|
||||
column_lines = -1 # start minus one for the name
|
||||
|
@ -399,13 +401,14 @@ def draw_tooltip(x, y, text='', author='', img=None, gravatar=None):
|
|||
xtext -= gsize + textmargin
|
||||
|
||||
ytext = y - column_lines * line_height - nameline_height - ttipmargin - textmargin - isizey + texth
|
||||
if False: # i == 0:
|
||||
if i == 0:
|
||||
fsize = name_height-4
|
||||
ytext = y - name_height + 5 - isizey + texth - textmargin
|
||||
elif i == len(lines) - 1:
|
||||
ytext = y - (nlines - 1) * line_height - nameline_height - ttipmargin * 2 - isizey + texth
|
||||
tcol = textcol
|
||||
tsize = font_height
|
||||
if (i > 0 and alines[i - 1][:7] == 'Author:'):
|
||||
elif (i > 0 and alines[i - 1][:7] == 'Author:'):
|
||||
tcol = textcol_strong
|
||||
fsize = font_height + 2
|
||||
else:
|
||||
|
@ -455,9 +458,16 @@ def draw_tooltip_with_author(asset_data, x, y):
|
|||
gimg = utils.get_hidden_image(a['gravatarImg'], a['gravatarHash'])
|
||||
atip = a['tooltip']
|
||||
|
||||
|
||||
tooltip = f"{asset_data['displayName']}\n\n" \
|
||||
f"Left click to drag to append/link.\nRight click for more."
|
||||
|
||||
# scene = bpy.context.scene
|
||||
# ui_props = scene.blenderkitUI
|
||||
draw_tooltip(x, y, text=asset_data['tooltip'], author=atip, img=img,
|
||||
author_s = ''
|
||||
if not gimg:
|
||||
author_s = 'Author: '
|
||||
draw_tooltip(x, y, text=asset_data['displayName']+'\n\n', author=f"{author_s}{a['firstName']} {a['lastName']}", img=img,
|
||||
gravatar=gimg)
|
||||
|
||||
|
||||
|
@ -851,6 +861,8 @@ def draw_asset_bar(self, context):
|
|||
img = utils.get_thumbnail('locked.png')
|
||||
ui_bgl.draw_image(x + 2, y + 2, 24, 24, img, 1)
|
||||
|
||||
# pcoll = icons.icon_collections["main"]
|
||||
# v_icon = pcoll['rejected']
|
||||
v_icon = verification_icons[result.get('verificationStatus', 'validated')]
|
||||
if v_icon is not None:
|
||||
img = utils.get_thumbnail(v_icon)
|
||||
|
@ -1575,8 +1587,12 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
my = event.mouse_y - r.y
|
||||
|
||||
if event.value == 'PRESS' and mouse_in_asset_bar(mx, my):
|
||||
# bpy.ops.wm.blenderkit_asset_popup('INVOKE_DEFAULT')
|
||||
bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_asset_menu')
|
||||
context.window.cursor_warp(event.mouse_x-500, event.mouse_y-45);
|
||||
|
||||
bpy.ops.wm.blenderkit_asset_popup('INVOKE_DEFAULT')
|
||||
context.window.cursor_warp(event.mouse_x, event.mouse_y);
|
||||
|
||||
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_asset_menu')
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
if event.type == 'LEFTMOUSE':
|
||||
|
@ -1960,7 +1976,7 @@ def find_and_activate_instancers(object):
|
|||
|
||||
|
||||
class AssetDragOperator(bpy.types.Operator):
|
||||
"""Draw a line with the mouse"""
|
||||
"""Drag & drop assets into scene."""
|
||||
bl_idname = "view3d.asset_drag_drop"
|
||||
bl_label = "BlenderKit asset drag drop"
|
||||
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
|
||||
from blenderkit import paths, ratings, utils, download, categories, icons, search, resolutions, ui, tasks_queue, \
|
||||
autothumb
|
||||
from blenderkit import paths, ratings, ratings_utils, utils, download, categories, icons, search, resolutions, ui, \
|
||||
tasks_queue, \
|
||||
autothumb, upload
|
||||
|
||||
from bpy.types import (
|
||||
Panel
|
||||
|
@ -35,9 +36,7 @@ from bpy.props import (
|
|||
|
||||
import bpy
|
||||
import os
|
||||
import random
|
||||
import logging
|
||||
import blenderkit
|
||||
|
||||
bk_logger = logging.getLogger('blenderkit')
|
||||
|
||||
|
@ -207,7 +206,6 @@ def draw_panel_hdr_search(self, context):
|
|||
utils.label_multiline(layout, text=props.report)
|
||||
|
||||
|
||||
|
||||
def draw_thumbnail_upload_panel(layout, props):
|
||||
update = False
|
||||
tex = autothumb.get_texture_ui(props.thumbnail, '.upload_preview')
|
||||
|
@ -216,6 +214,7 @@ def draw_thumbnail_upload_panel(layout, props):
|
|||
box = layout.box()
|
||||
box.template_icon(icon_value=tex.image.preview.icon_id, scale=6.0)
|
||||
|
||||
|
||||
def draw_panel_model_upload(self, context):
|
||||
ob = bpy.context.active_object
|
||||
while ob.parent is not None:
|
||||
|
@ -646,7 +645,8 @@ def draw_panel_material_upload(self, context):
|
|||
prop_needed(row, props, 'thumbnail', props.has_thumbnail, False)
|
||||
|
||||
if bpy.context.scene.render.engine in ('CYCLES', 'BLENDER_EEVEE'):
|
||||
layout.operator("object.blenderkit_generate_material_thumbnail", text='Render thumbnail with Cycles', icon='EXPORT')
|
||||
layout.operator("object.blenderkit_generate_material_thumbnail", text='Render thumbnail with Cycles',
|
||||
icon='EXPORT')
|
||||
if props.is_generating_thumbnail:
|
||||
row = layout.row(align=True)
|
||||
row.label(text=props.thumbnail_generating_state, icon='RENDER_STILL')
|
||||
|
@ -1153,12 +1153,13 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
|
|||
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
|
||||
op = layout.operator('wm.blenderkit_menu_rating_upload', text='Rate')
|
||||
op.asset_name = asset_data['name']
|
||||
op.asset_id = asset_data['id']
|
||||
op.asset_type = asset_data['assetType']
|
||||
if from_panel:
|
||||
op = layout.operator('wm.blenderkit_menu_rating_upload', text='Rate')
|
||||
op.asset_name = asset_data['name']
|
||||
op.asset_id = asset_data['id']
|
||||
op.asset_type = asset_data['assetType']
|
||||
|
||||
if wm.get('bkit authors') is not None and author_id is not None:
|
||||
if from_panel and wm.get('bkit authors') is not None and author_id is not None:
|
||||
a = bpy.context.window_manager['bkit authors'].get(author_id)
|
||||
if a is not None:
|
||||
# utils.p('author:', a)
|
||||
|
@ -1172,6 +1173,7 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
|
|||
op.author_id = author_id
|
||||
|
||||
op = layout.operator('view3d.blenderkit_search', text='Search Similar')
|
||||
op.tooltip = 'Search for similar assets in the library'
|
||||
# build search string from description and tags:
|
||||
op.keywords = asset_data['name']
|
||||
if asset_data.get('description'):
|
||||
|
@ -1263,7 +1265,6 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
|
|||
op.model_rotation = (0, 0, 0)
|
||||
op.max_resolution = asset_data.get('max_resolution',
|
||||
0) # str(utils.get_param(asset_data, 'textureResolutionMax'))
|
||||
print('should be drawn!')
|
||||
# print('operator res ', resolution)
|
||||
# op.resolution = resolution
|
||||
|
||||
|
@ -1297,7 +1298,7 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
|
|||
|
||||
row = layout.row()
|
||||
row.operator_context = 'INVOKE_DEFAULT'
|
||||
op = layout.operator('wm.blenderkit_fast_metadata', text='Fast Edit Metadata')
|
||||
op = layout.operator('wm.blenderkit_fast_metadata', text='Edit Metadata')
|
||||
op.asset_id = asset_data['id']
|
||||
op.asset_type = asset_data['assetType']
|
||||
|
||||
|
@ -1377,97 +1378,429 @@ class OBJECT_MT_blenderkit_asset_menu(bpy.types.Menu):
|
|||
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.window_manager['search results']
|
||||
# asset_data = sr[ui_props.active_index]
|
||||
# layout = self.layout
|
||||
# row = layout.row()
|
||||
# split = row.split(factor=0.2)
|
||||
# col = split.column()
|
||||
# op = col.operator('view3d.asset_drag_drop')
|
||||
# op.asset_search_index=ui_props.active_index
|
||||
#
|
||||
# draw_asset_context_menu(col, context, asset_data, from_panel=False)
|
||||
# split = split.split(factor=0.3)
|
||||
# col1 = split.column()
|
||||
# box = col1.box()
|
||||
# utils.label_multiline(box, asset_data['tooltip'])
|
||||
# col2 = split.column()
|
||||
#
|
||||
# pcoll = icons.icon_collections["main"]
|
||||
# my_icon = pcoll['test']
|
||||
# row = col2.row()
|
||||
# row.scale_y = 4
|
||||
# row.template_icon(icon_value=my_icon.icon_id, scale=2.0)
|
||||
# # col2.template_icon(icon_value=self.img.preview.icon_id, scale=10.0)
|
||||
# box2 = col2.box()
|
||||
#
|
||||
# box2.label(text='and heere goes the rating')
|
||||
# box2.label(text='************')
|
||||
# box2.label(text='dadydadadada')
|
||||
|
||||
|
||||
class AssetPopupCard(bpy.types.Operator):
|
||||
"""Generate Cycles thumbnail for model assets"""
|
||||
bl_idname = "wm.blenderkit_asset_popup"
|
||||
bl_label = "BlenderKit asset popup"
|
||||
# bl_options = {'REGISTER', 'INTERNAL'}
|
||||
bl_options = {'REGISTER', }
|
||||
|
||||
width = 700
|
||||
|
||||
message: StringProperty(
|
||||
name="message",
|
||||
description="message",
|
||||
default="Rating asset",
|
||||
options={'SKIP_SAVE'})
|
||||
|
||||
asset_id: StringProperty(
|
||||
name="Asset Base Id",
|
||||
description="Unique id of the asset (hidden)",
|
||||
default="",
|
||||
options={'SKIP_SAVE'})
|
||||
|
||||
asset_name: StringProperty(
|
||||
name="Asset Name",
|
||||
description="Name of the asset (hidden)",
|
||||
default="",
|
||||
options={'SKIP_SAVE'})
|
||||
|
||||
asset_type: StringProperty(
|
||||
name="Asset type",
|
||||
description="asset type",
|
||||
default="",
|
||||
options={'SKIP_SAVE'})
|
||||
|
||||
rating_quality: IntProperty(name="Quality",
|
||||
description="quality of the material",
|
||||
default=0,
|
||||
min=-1, max=10,
|
||||
# update=update_ratings_quality,
|
||||
options={'SKIP_SAVE'})
|
||||
|
||||
# the following enum is only to ease interaction - enums support 'drag over' and enable to draw the stars easily.
|
||||
rating_quality_ui: EnumProperty(name='rating_quality_ui',
|
||||
items=ratings_utils.stars_enum_callback,
|
||||
description='Rating stars 0 - 10',
|
||||
default=0,
|
||||
update=ratings_utils.update_quality_ui,
|
||||
options={'SKIP_SAVE'})
|
||||
|
||||
rating_work_hours: FloatProperty(name="Work Hours",
|
||||
description="How many hours did this work take?",
|
||||
default=0.00,
|
||||
min=0.0, max=300,
|
||||
# update=update_ratings_work_hours,
|
||||
options={'SKIP_SAVE'}
|
||||
)
|
||||
|
||||
high_rating_warning = "This is a high rating, please be sure to give such rating only to amazing assets"
|
||||
|
||||
rating_work_hours_ui: EnumProperty(name="Work Hours",
|
||||
description="How many hours did this work take?",
|
||||
items=[('0', '0', ''),
|
||||
('.5', '0.5', ''),
|
||||
('1', '1', ''),
|
||||
('2', '2', ''),
|
||||
('3', '3', ''),
|
||||
('4', '4', ''),
|
||||
('5', '5', ''),
|
||||
('6', '6', ''),
|
||||
('8', '8', ''),
|
||||
('10', '10', ''),
|
||||
('15', '15', ''),
|
||||
('20', '20', ''),
|
||||
('30', '30', high_rating_warning),
|
||||
('50', '50', high_rating_warning),
|
||||
('100', '100', high_rating_warning),
|
||||
('150', '150', high_rating_warning),
|
||||
('200', '200', high_rating_warning),
|
||||
('250', '250', high_rating_warning),
|
||||
],
|
||||
default='0', update=ratings_utils.update_ratings_work_hours_ui,
|
||||
options={'SKIP_SAVE'}
|
||||
)
|
||||
|
||||
rating_work_hours_ui_1_5: EnumProperty(name="Work Hours",
|
||||
description="How many hours did this work take?",
|
||||
items=[('0', '0', ''),
|
||||
('.2', '0.2', ''),
|
||||
('.5', '0.5', ''),
|
||||
('1', '1', ''),
|
||||
('2', '2', ''),
|
||||
('3', '3', ''),
|
||||
('4', '4', ''),
|
||||
('5', '5', '')
|
||||
],
|
||||
default='0',
|
||||
update=ratings_utils.update_ratings_work_hours_ui_1_5,
|
||||
options={'SKIP_SAVE'}
|
||||
)
|
||||
|
||||
rating_work_hours_ui_1_10: EnumProperty(name="Work Hours",
|
||||
description="How many hours did this work take?",
|
||||
items=[('0', '0', ''),
|
||||
('1', '1', ''),
|
||||
('2', '2', ''),
|
||||
('3', '3', ''),
|
||||
('4', '4', ''),
|
||||
('5', '5', ''),
|
||||
('6', '6', ''),
|
||||
('7', '7', ''),
|
||||
('8', '8', ''),
|
||||
('9', '9', ''),
|
||||
('10', '10', '')
|
||||
],
|
||||
default='0',
|
||||
update=ratings_utils.update_ratings_work_hours_ui_1_10,
|
||||
options={'SKIP_SAVE'}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
def draw_menu(self, context, layout):
|
||||
ui_props = context.scene.blenderkitUI
|
||||
|
||||
col_left = layout.column()
|
||||
# row_button = col_left.row()
|
||||
# row_button.scale_y = 3
|
||||
# op = row_button.operator('view3d.asset_drag_drop', text='Drag & Drop')
|
||||
# op.asset_search_index = ui_props.active_index
|
||||
draw_asset_context_menu(col_left, context, self.asset_data, from_panel=False)
|
||||
# layout = col_left
|
||||
# op = layout.operator('view3d.blenderkit_search', text='Search Similar')
|
||||
# # build search string from description and tags:
|
||||
# op.keywords = self.asset_data['name']
|
||||
# if self.asset_data.get('description'):
|
||||
# op.keywords += ' ' + self.asset_data.get('description') + ' '
|
||||
# op.keywords += ' '.join(self.asset_data.get('tags'))
|
||||
|
||||
def draw_property(self, layout, left, right, icon=None, icon_value=None, url=None, tooltip=''):
|
||||
right = str(right)
|
||||
row = layout.row()
|
||||
split = row.split(factor=0.4)
|
||||
split.alignment = 'RIGHT'
|
||||
split.label(text=left)
|
||||
split = split.split()
|
||||
# if url:
|
||||
# if icon_value:
|
||||
# op = split.operator('wm.url_open', text=right, icon_value=icon_value)
|
||||
# elif icon:
|
||||
# op = split.operator('wm.url_open', text=right, icon=icon)
|
||||
# else:
|
||||
# op = split.operator('wm.url_open', text=right)
|
||||
# op.url = url
|
||||
# return
|
||||
if url:
|
||||
split = split.split(factor=0.9)
|
||||
if icon_value:
|
||||
split.label(text=right, icon_value=icon_value)
|
||||
elif icon:
|
||||
split.label(text=right, icon=icon)
|
||||
|
||||
else:
|
||||
split.label(text=right)
|
||||
if url:
|
||||
split = split.split()
|
||||
op = split.operator('wm.blenderkit_url', text='', icon='QUESTION')
|
||||
op.url = url
|
||||
op.tooltip = tooltip
|
||||
|
||||
def draw_asset_parameter(self, layout, key='', pretext=''):
|
||||
parameter = utils.get_param(self.asset_data, key)
|
||||
if parameter == None:
|
||||
return
|
||||
self.draw_property(layout, pretext, parameter)
|
||||
|
||||
def draw_tooltip(self, layout):
|
||||
if type(self.asset_data['parameters']) == list:
|
||||
mparams = utils.params_to_dict(self.asset_data['parameters'])
|
||||
else:
|
||||
mparams = self.asset_data['parameters']
|
||||
|
||||
layout = layout.column()
|
||||
if len(self.asset_data['description']) > 0:
|
||||
box = layout.box()
|
||||
box.scale_y = 0.8
|
||||
box.label(text='Description:')
|
||||
utils.label_multiline(box, self.asset_data['description'], width=200)
|
||||
|
||||
pcoll = icons.icon_collections["main"]
|
||||
|
||||
box = layout.box()
|
||||
box.scale_y = 0.8
|
||||
|
||||
if self.asset_data.get('license') == 'cc_zero':
|
||||
t = 'CC Zero'
|
||||
icon = pcoll['cc0']
|
||||
|
||||
else:
|
||||
t = 'Royalty free'
|
||||
icon = pcoll['royalty_free']
|
||||
|
||||
self.draw_property(box,
|
||||
'license:', t,
|
||||
icon_value=icon.icon_id,
|
||||
url="https://www.blenderkit.com/docs/licenses/",
|
||||
tooltip='All BlenderKit assets are available for commercial use. '
|
||||
'Click to read more about BlenderKit licenses online'
|
||||
)
|
||||
|
||||
if upload.can_edit_asset(asset_data=self.asset_data):
|
||||
icon = pcoll[self.asset_data['verificationStatus']]
|
||||
verification_status_tooltips = {
|
||||
'uploading': "Your asset got stuck during upload. Probably, your file was too large "
|
||||
"or your connection too slow or interrupting. If you have repeated issues, "
|
||||
"please contact us and let us know, it might be a bug",
|
||||
'uploaded': "Your asset uploaded successfully. Yay! If it's public, "
|
||||
"it's awaiting validation. If it's private, use it",
|
||||
'on_hold': "Your asset needs some (usually smaller) fixes, "
|
||||
"so we can make it public for everybody."
|
||||
" Please check your email to see the feedback "
|
||||
"that we send to every creator personally",
|
||||
'rejected': "The asset has serious quality issues, " \
|
||||
"and it's probable that it might be good to start " \
|
||||
"all over again or try with something simpler. " \
|
||||
"You also get personal feedback into your e-mail, " \
|
||||
"since we believe that together, we can all learn " \
|
||||
"to become awesome 3D artists",
|
||||
'deleted': "You deleted this asset",
|
||||
'validated': "Your asset passed our validation process, "
|
||||
"and is now available to BlenderKit users"
|
||||
|
||||
}
|
||||
self.draw_property(box,
|
||||
'Verification:',
|
||||
self.asset_data['verificationStatus'],
|
||||
icon_value=icon.icon_id,
|
||||
url="https://www.blenderkit.com/docs/validation-status/",
|
||||
tooltip=verification_status_tooltips[self.asset_data['verificationStatus']]
|
||||
|
||||
)
|
||||
|
||||
self.draw_asset_parameter(box, key='textureResolutionMax', pretext='Resolution:')
|
||||
|
||||
self.draw_asset_parameter(box, key='designer', pretext='Designer:')
|
||||
self.draw_asset_parameter(box, key='manufacturer', pretext='Manufacturer:')
|
||||
self.draw_asset_parameter(box, key='collection', pretext='Collection:')
|
||||
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:')
|
||||
|
||||
if utils.get_param(self.asset_data, 'dimensionX'):
|
||||
t = '%s × %s × %s m' % (utils.fmt_length(mparams['dimensionX']),
|
||||
utils.fmt_length(mparams['dimensionY']),
|
||||
utils.fmt_length(mparams['dimensionZ']))
|
||||
self.draw_property(box, 'Size:', t)
|
||||
|
||||
#Free/Full plan or private Access
|
||||
if self.asset_data['isPrivate']:
|
||||
t = 'Private'
|
||||
self.draw_property(box, 'Access:', t, icon='LOCKED')
|
||||
elif self.asset_data['isFree']:
|
||||
t = 'Free plan'
|
||||
icon = pcoll['free']
|
||||
self.draw_property(box, 'Access:', t, icon_value=icon.icon_id)
|
||||
else:
|
||||
t = 'Full plan'
|
||||
icon = pcoll['full']
|
||||
self.draw_property(box, 'Access:', t, icon_value=icon.icon_id)
|
||||
|
||||
def draw_author(self, layout, width=330):
|
||||
image_split = 0.25
|
||||
text_width = width
|
||||
authors = bpy.context.window_manager['bkit authors']
|
||||
a = authors.get(self.asset_data['author']['id'])
|
||||
if a is not None: # or a is '' or (a.get('gravatarHash') is not None and a.get('gravatarImg') is None):
|
||||
row = layout.row()
|
||||
author_box = row.box()
|
||||
author_box.scale_y = 0.6 # get text lines closer to each other
|
||||
if hasattr(self, 'gimg'):
|
||||
|
||||
author_left = author_box.split(factor=0.25)
|
||||
author_left.template_icon(icon_value=self.gimg.preview.icon_id, scale=6.0)
|
||||
text_area = author_left.split()
|
||||
text_width = int(text_width * (1 - image_split))
|
||||
else:
|
||||
text_area = author_box
|
||||
|
||||
author_right = text_area.column()
|
||||
row = author_right.row()
|
||||
col = row.column()
|
||||
|
||||
utils.label_multiline(col, text=a['tooltip'], width=text_width)
|
||||
if upload.can_edit_asset(asset_data=self.asset_data) and a.get('aboutMe') is not None and len(
|
||||
a.get('aboutMe', '')) == 0:
|
||||
col.label(text='Please write something about yourself!')
|
||||
op = col.operator('wm.blenderkit_url', text='Edit your profile')
|
||||
op.url = 'https://www.blenderkit.com/profile'
|
||||
op.tooltip = 'Edit your profile on BlenderKit webpage'
|
||||
|
||||
button_row = author_box.row()
|
||||
button_row.scale_y = 2.0
|
||||
|
||||
if a.get('aboutMeUrl') is not None:
|
||||
url = a['aboutMeUrl']
|
||||
text = url
|
||||
if len(url) > 25:
|
||||
text = url[:25] + '...'
|
||||
else:
|
||||
url = paths.get_author_gallery_url(a['id'])
|
||||
text = "Open Author's Profile"
|
||||
|
||||
op = button_row.operator('wm.url_open', text=text)
|
||||
op.url = url
|
||||
|
||||
op = button_row.operator('view3d.blenderkit_search', text="Show Assets By Author")
|
||||
op.keywords = ''
|
||||
op.author_id = self.asset_data['author']['id']
|
||||
|
||||
def draw_thumbnail_box(self, layout):
|
||||
layout.emboss = 'NORMAL'
|
||||
|
||||
box_thumbnail = layout.box()
|
||||
# row = split_right.row()
|
||||
# column_right = row.column()
|
||||
|
||||
box_thumbnail.scale_y = 0.5
|
||||
# row = box_thumbnail.row()
|
||||
# row.scale_y = 20
|
||||
|
||||
box_thumbnail.template_icon(icon_value=self.img.preview.icon_id, scale=34.0)
|
||||
# row = box_thumbnail.row()
|
||||
# row.scale_y = 4
|
||||
# op = row.operator('view3d.asset_drag_drop', text='Drag & Drop from here', depress=True)
|
||||
|
||||
row = box_thumbnail.row()
|
||||
row.alignment = 'EXPAND'
|
||||
rc = self.asset_data.get('ratingsCount')
|
||||
show_rating_threshold = 3
|
||||
|
||||
if rc:
|
||||
rcount = min(rc['quality'], rc['workingHours'])
|
||||
else:
|
||||
rcount = 0
|
||||
if rcount >= show_rating_threshold or upload.can_edit_asset(asset_data=self.asset_data):
|
||||
pcoll = icons.icon_collections["main"]
|
||||
my_icon = pcoll['trophy']
|
||||
s = self.asset_data['score']
|
||||
if s:
|
||||
row.label(text=str(round(s)), icon_value=my_icon.icon_id)
|
||||
q = self.asset_data['ratingsAverage'].get('quality')
|
||||
if q:
|
||||
row.label(text=str(round(q)), icon='SOLO_ON')
|
||||
c = self.asset_data['ratingsAverage'].get('workingHours')
|
||||
if c:
|
||||
row.label(text=str(round(c)), icon='SORTTIME')
|
||||
else:
|
||||
box_thumbnail.label(text=f"This asset needs more ratings ( {rcount} of {show_rating_threshold} ).")
|
||||
# box_thumbnail.label(text=f"Please rate this asset.")
|
||||
|
||||
def draw_menu_desc_author(self, context, layout):
|
||||
box = layout.column()
|
||||
|
||||
box.emboss = 'NORMAL'
|
||||
# left - tooltip & params
|
||||
row = box.row()
|
||||
split_left_left = row.split(factor=0.7)
|
||||
self.draw_tooltip(split_left_left)
|
||||
|
||||
# right - menu
|
||||
col1 = split_left_left.split()
|
||||
self.draw_menu(context, col1)
|
||||
|
||||
# author
|
||||
self.draw_author(box)
|
||||
|
||||
def draw(self, context):
|
||||
ui_props = context.scene.blenderkitUI
|
||||
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = sr[ui_props.active_index]
|
||||
self.asset_data = asset_data
|
||||
layout = self.layout
|
||||
row = layout.row()
|
||||
split = row.split(factor=0.2)
|
||||
col = split.column()
|
||||
op = col.operator('view3d.asset_drag_drop')
|
||||
op.asset_search_index = ui_props.active_index
|
||||
draw_asset_context_menu(col, context, asset_data, from_panel=False)
|
||||
split = split.split(factor=0.5)
|
||||
col1 = split.column()
|
||||
box = col1.box()
|
||||
utils.label_multiline(box, asset_data['tooltip'], width=300)
|
||||
# top draggabe bar with name of the asset
|
||||
top_row = layout.row()
|
||||
top_drag_bar = top_row.box()
|
||||
top_drag_bar.alignment = 'CENTER'
|
||||
|
||||
col2 = split.column()
|
||||
top_drag_bar.label(text=asset_data['displayName'])
|
||||
# left side
|
||||
row = layout.row(align=True)
|
||||
split_left = row.split(factor=0.5)
|
||||
self.draw_thumbnail_box(split_left)
|
||||
|
||||
pcoll = icons.icon_collections["main"]
|
||||
my_icon = pcoll['test']
|
||||
col2.template_icon(icon_value=my_icon.icon_id, scale=20.0)
|
||||
# col2.template_icon(icon_value=self.img.preview.icon_id, scale=10.0)
|
||||
box2 = col2.box()
|
||||
# right split
|
||||
split_right = split_left.split()
|
||||
self.draw_menu_desc_author(context, split_right)
|
||||
|
||||
# draw_ratings(box2, context, asset_data)
|
||||
box2.label(text='Ratings')
|
||||
# print(tp, dir(tp))
|
||||
# if not hasattr(self, 'first_draw'):# try to redraw because of template preview which needs update
|
||||
# for region in context.area.regions:
|
||||
# region.tag_redraw()
|
||||
# self.first_draw = True
|
||||
ratings_box = layout.box()
|
||||
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)
|
||||
|
||||
def execute(self, context):
|
||||
print('execute')
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.window_manager
|
||||
ui_props = context.scene.blenderkitUI
|
||||
ui_props.draw_tooltip = False
|
||||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = sr[ui_props.active_index]
|
||||
self.img = ui.get_large_thumbnail_image(asset_data)
|
||||
self.asset_type = asset_data['assetType']
|
||||
# self.tex = utils.get_hidden_texture(self.img)
|
||||
# self.tex.update_tag()
|
||||
|
||||
authors = bpy.context.window_manager['bkit authors']
|
||||
a = authors.get(asset_data['author']['id'])
|
||||
if a.get('gravatarImg') is not None:
|
||||
self.gimg = utils.get_hidden_image(a['gravatarImg'], a['gravatarHash'])
|
||||
|
||||
bl_label = asset_data['name']
|
||||
return wm.invoke_props_dialog(self, width=700)
|
||||
self.tip = search.get_random_tip()
|
||||
self.tip = self.tip.replace('\n', '')
|
||||
return wm.invoke_popup(self, width=self.width)
|
||||
|
||||
|
||||
class OBJECT_MT_blenderkit_login_menu(bpy.types.Menu):
|
||||
|
|
|
@ -580,13 +580,13 @@ def can_edit_asset(active_index=-1, asset_data=None):
|
|||
sr = bpy.context.window_manager['search results']
|
||||
asset_data = dict(sr[active_index])
|
||||
# print(profile, asset_data)
|
||||
if asset_data['author']['id'] == profile['user']['id']:
|
||||
if int(asset_data['author']['id']) == int(profile['user']['id']):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class FastMetadata(bpy.types.Operator):
|
||||
"""Fast change of the category of object directly in asset bar."""
|
||||
"""Edit metadata of the asset"""
|
||||
bl_idname = "wm.blenderkit_fast_metadata"
|
||||
bl_label = "Update metadata"
|
||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||
|
@ -731,6 +731,7 @@ class FastMetadata(bpy.types.Operator):
|
|||
active_asset = utils.get_active_asset_by_type(asset_type = self.asset_type)
|
||||
asset_data = active_asset.get('asset_data')
|
||||
|
||||
print('can edit asset?', can_edit_asset(asset_data=asset_data))
|
||||
if not can_edit_asset(asset_data=asset_data):
|
||||
return {'CANCELLED'}
|
||||
self.asset_id = asset_data['id']
|
||||
|
@ -1298,7 +1299,7 @@ class AssetDebugPrint(Operator):
|
|||
class AssetVerificationStatusChange(Operator):
|
||||
"""Change verification status"""
|
||||
bl_idname = "object.blenderkit_change_status"
|
||||
bl_description = "Change asset ststus"
|
||||
bl_description = "Change asset status"
|
||||
bl_label = "Change verification status"
|
||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||
|
||||
|
|
|
@ -337,6 +337,12 @@ 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[:]
|
||||
# img.preview.icon_size = (img.size[0], img.size[1])
|
||||
# img.preview.icon_pixels_float = img.pixels[:]
|
||||
|
||||
def get_hidden_image(tpath, bdata_name, force_reload=False, colorspace='sRGB'):
|
||||
if bdata_name[0] == '.':
|
||||
hidden_name = bdata_name
|
||||
|
@ -355,6 +361,7 @@ def get_hidden_image(tpath, bdata_name, force_reload=False, colorspace='sRGB'):
|
|||
|
||||
if img is None:
|
||||
img = bpy.data.images.load(tpath)
|
||||
img_to_preview(img)
|
||||
img.name = hidden_name
|
||||
else:
|
||||
if img.filepath != tpath:
|
||||
|
@ -363,13 +370,16 @@ def get_hidden_image(tpath, bdata_name, force_reload=False, colorspace='sRGB'):
|
|||
|
||||
img.filepath = tpath
|
||||
img.reload()
|
||||
img_to_preview(img)
|
||||
image_utils.set_colorspace(img, colorspace)
|
||||
|
||||
elif force_reload:
|
||||
if img.packed_file is not None:
|
||||
img.unpack(method='USE_ORIGINAL')
|
||||
img.reload()
|
||||
img_to_preview(img)
|
||||
image_utils.set_colorspace(img, colorspace)
|
||||
|
||||
return img
|
||||
|
||||
|
||||
|
@ -690,6 +700,9 @@ def name_update(props):
|
|||
# Here we actually rename assets datablocks, but don't do that with HDR's and possibly with others
|
||||
asset.name = fname
|
||||
|
||||
def fmt_length(prop):
|
||||
prop = str(round(prop, 2))
|
||||
return prop
|
||||
|
||||
def get_param(asset_data, parameter_name, default = None):
|
||||
if not asset_data.get('parameters'):
|
||||
|
|
Loading…
Reference in New Issue