BlenderKit: Rating refactorings
This mainly paves a way for removing the old and clumsy bgl UI and enable faster rating for users.
-Rating Ui is now more responsive -it can be dragged over the stars widget.
-fast rating operator (f shortcut over assetbar)
-wip on new ratings panel(disabled by now)
-if author didn't provide his webpage, the link now leads to his profile on the BlenderKit site.
-upload was partially broken thanks to a small bug
-perpendicular snap - This limits angled snapping in a reasonable way, should help when placing foliage or items on sloped ceilings e.t.c.
-removed the first_run property, it's replaced with a poput that informs the user about connecting to the internet.
(cherry picked from commit 8f6903bc92
)
This commit is contained in:
parent
66bd6dea71
commit
06181ee994
|
@ -250,6 +250,7 @@ def switch_search_results(self, context):
|
|||
s['search results orig'] = s.get('bkit brush search orig')
|
||||
search.load_previews()
|
||||
|
||||
|
||||
def asset_type_callback(self, context):
|
||||
'''
|
||||
Returns
|
||||
|
@ -650,29 +651,6 @@ class BlenderKitCommonUploadProps(object):
|
|||
)
|
||||
|
||||
|
||||
def stars_enum_callback(self, context):
|
||||
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 update_quality(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_quality_ui = '0'
|
||||
self.rating_quality = int(self.rating_quality_ui)
|
||||
|
||||
|
||||
class BlenderKitRatingProps(PropertyGroup):
|
||||
rating_quality: IntProperty(name="Quality",
|
||||
description="quality of the material",
|
||||
|
@ -680,19 +658,20 @@ class BlenderKitRatingProps(PropertyGroup):
|
|||
min=-1, max=10,
|
||||
update=ratings.update_ratings_quality)
|
||||
|
||||
#the following enum is only to ease interaction - enums support 'drag over' and enable to draw the stars easily.
|
||||
# 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,
|
||||
description='Rating stars 0 - 10',
|
||||
default=None,
|
||||
update=update_quality,
|
||||
)
|
||||
items=ratings.stars_enum_callback,
|
||||
description='Rating stars 0 - 10',
|
||||
default=None,
|
||||
update=ratings.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=1000, update=ratings.update_ratings_work_hours
|
||||
)
|
||||
|
||||
# rating_complexity: IntProperty(name="Complexity",
|
||||
# description="Complexity is a number estimating how much work was spent on the asset.aaa",
|
||||
# default=0, min=0, max=10)
|
||||
|
@ -1393,6 +1372,17 @@ class BlenderKitModelSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
|
|||
max=180,
|
||||
subtype='ANGLE')
|
||||
|
||||
perpendicular_snap: BoolProperty(name='Perpendicular snap',
|
||||
description="Limit snapping that is close to perpendicular angles to be perpendicular.",
|
||||
default=True)
|
||||
|
||||
perpendicular_snap_threshold: FloatProperty(name="Threshold",
|
||||
description="Limit perpendicular snap to be below these values.",
|
||||
default=.25,
|
||||
min=0,
|
||||
max=.5,
|
||||
)
|
||||
|
||||
|
||||
class BlenderKitSceneSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
|
||||
search_keywords: StringProperty(
|
||||
|
@ -1586,12 +1576,13 @@ class BlenderKitAddonPreferences(AddonPreferences):
|
|||
min=0,
|
||||
max=20000)
|
||||
|
||||
first_run: BoolProperty(
|
||||
name="First run",
|
||||
description="Detects if addon was already registered/run.",
|
||||
default=True,
|
||||
update=utils.save_prefs
|
||||
)
|
||||
# this is now made obsolete by the new popup upon registration -ensures the user knows about the first search.
|
||||
# first_run: BoolProperty(
|
||||
# name="First run",
|
||||
# description="Detects if addon was already registered/run.",
|
||||
# default=True,
|
||||
# update=utils.save_prefs
|
||||
# )
|
||||
|
||||
use_timers: BoolProperty(
|
||||
name="Use timers",
|
||||
|
@ -1729,7 +1720,8 @@ def register():
|
|||
for w in bpy.context.window_manager.windows:
|
||||
for a in w.screen.areas:
|
||||
if a.type == 'PREFERENCES':
|
||||
tasks_queue.add_task((bpy.ops.wm.blenderkit_welcome,( 'INVOKE_DEFAULT',)),fake_context = True, fake_context_area = 'PREFERENCES')
|
||||
tasks_queue.add_task((bpy.ops.wm.blenderkit_welcome, ('INVOKE_DEFAULT',)), fake_context=True,
|
||||
fake_context_area='PREFERENCES')
|
||||
|
||||
|
||||
def unregister():
|
||||
|
|
|
@ -75,6 +75,9 @@ def get_api_url():
|
|||
def get_oauth_landing_url():
|
||||
return get_bkit_url() + BLENDERKIT_OAUTH_LANDING_URL
|
||||
|
||||
def get_author_gallery_url(author_id):
|
||||
return f'{get_bkit_url()}/asset-gallery?query=author_id:{author_id}'
|
||||
|
||||
|
||||
def default_global_dict():
|
||||
from os.path import expanduser
|
||||
|
|
|
@ -94,7 +94,7 @@ def upload_review_thread(url, reviews, headers):
|
|||
|
||||
|
||||
def get_rating(asset_id):
|
||||
#this function isn't used anywhere,should probably get removed.
|
||||
# this function isn't used anywhere,should probably get removed.
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
api_key = user_preferences.api_key
|
||||
headers = utils.get_headers(api_key)
|
||||
|
@ -114,8 +114,13 @@ def update_ratings_quality(self, context):
|
|||
|
||||
headers = utils.get_headers(api_key)
|
||||
asset = self.id_data
|
||||
bkit_ratings = asset.bkit_ratings
|
||||
url = paths.get_api_url() + 'assets/' + asset['asset_data']['id'] + '/rating/'
|
||||
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)]
|
||||
|
@ -127,15 +132,19 @@ def update_ratings_work_hours(self, context):
|
|||
api_key = user_preferences.api_key
|
||||
headers = utils.get_headers(api_key)
|
||||
asset = self.id_data
|
||||
bkit_ratings = asset.bkit_ratings
|
||||
url = paths.get_api_url() + 'assets/' + asset['asset_data']['id'] + '/rating/'
|
||||
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.05:
|
||||
ratings = [('working_hours', round(bkit_ratings.rating_work_hours, 1))]
|
||||
tasks_queue.add_task((send_rating_to_thread_work_hours, (url, ratings, headers)), wait=1, only_last=True)
|
||||
|
||||
|
||||
|
||||
def upload_rating(asset):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
api_key = user_preferences.api_key
|
||||
|
@ -173,6 +182,7 @@ def upload_rating(asset):
|
|||
if bkit_ratings.rating_quality > 0.1 and bkit_ratings.rating_work_hours > 0.1:
|
||||
s['assets rated'][asset['asset_data']['assetBaseId']] = True
|
||||
|
||||
|
||||
def get_assets_for_rating():
|
||||
'''
|
||||
gets assets from scene that could/should be rated by the user.
|
||||
|
@ -191,26 +201,6 @@ def get_assets_for_rating():
|
|||
assets.append(b)
|
||||
return assets
|
||||
|
||||
# class StarRatingOperator(bpy.types.Operator):
|
||||
# """Tooltip"""
|
||||
# bl_idname = "object.blenderkit_rating"
|
||||
# bl_label = "Rate the Asset Quality"
|
||||
# bl_options = {'REGISTER', 'INTERNAL'}
|
||||
#
|
||||
# property_name: StringProperty(
|
||||
# name="Rating Property",
|
||||
# description="Property that is rated",
|
||||
# default="",
|
||||
# )
|
||||
#
|
||||
# rating: IntProperty(name="Rating", description="rating value", default=1, min=1, max=10)
|
||||
#
|
||||
# def execute(self, context):
|
||||
# asset = utils.get_active_asset()
|
||||
# props = asset.bkit_ratings
|
||||
# props.rating_quality = self.rating
|
||||
# return {'FINISHED'}
|
||||
|
||||
|
||||
asset_types = (
|
||||
('MODEL', 'Model', 'set of objects'),
|
||||
|
@ -254,43 +244,212 @@ 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_rating(layout, props, prop_name, name):
|
||||
# layout.label(name)
|
||||
|
||||
row = layout.row(align=True)
|
||||
# test method - 10 booleans.
|
||||
# propsx = bpy.context.active_object.bkit_ratings
|
||||
# for a in range(0, 10):
|
||||
# pn = f'rq{str(a+1).zfill(2)}'
|
||||
# if eval('propsx.' + pn) == False:
|
||||
# icon = 'SOLO_OFF'
|
||||
# else:
|
||||
# icon = 'SOLO_ON'
|
||||
# row.prop(propsx, pn, icon=icon, icon_only=True)
|
||||
# print(dir(props))
|
||||
# new best method - enum with an items callback. ('animates' the stars as item icons)
|
||||
row.prop(props, 'rating_quality_ui', expand=True, icon_only=True, emboss = False)
|
||||
# original (operator) method:
|
||||
# row = layout.row(align=True)
|
||||
# for a in range(0, 10):
|
||||
# if eval('props.' + prop_name) < a + 1:
|
||||
# icon = 'SOLO_OFF'
|
||||
# else:
|
||||
# icon = 'SOLO_ON'
|
||||
#
|
||||
# op = row.operator('object.blenderkit_rating', icon=icon, emboss=False, text='')
|
||||
# op.property_name = prop_name
|
||||
# op.rating = a + 1
|
||||
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.update_ratings_work_hours_ui_1_5 = '0'
|
||||
self.rating_work_hours = float(self.update_ratings_work_hours_ui_1_5)
|
||||
|
||||
|
||||
|
||||
class FastRateMenu(Operator):
|
||||
"""Fast rating of the assets directly in the asset bar - without need to download assets."""
|
||||
bl_idname = "wm.blenderkit_menu_rating_upload"
|
||||
bl_label = "Send Rating"
|
||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||
|
||||
message: StringProperty(
|
||||
name="message",
|
||||
description="message",
|
||||
default="Rating asset")
|
||||
|
||||
asset_id: StringProperty(
|
||||
name="Asset Base Id",
|
||||
description="Unique name of the asset (hidden)",
|
||||
default="")
|
||||
|
||||
asset_type: StringProperty(
|
||||
name="Asset type",
|
||||
description="asset type",
|
||||
default="")
|
||||
|
||||
rating_quality: IntProperty(name="Quality",
|
||||
description="quality of the material",
|
||||
default=0,
|
||||
min=-1, max=10,
|
||||
update=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=stars_enum_callback,
|
||||
description='Rating stars 0 - 10',
|
||||
default=None,
|
||||
update=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=1000, update=update_ratings_work_hours
|
||||
)
|
||||
|
||||
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', ''),
|
||||
('10', '10', ''),
|
||||
('15', '15', ''),
|
||||
('20', '20', ''),
|
||||
('50', '50', ''),
|
||||
('100', '100', ''),
|
||||
],
|
||||
default='0', update=update_ratings_work_hours_ui
|
||||
)
|
||||
|
||||
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=update_ratings_work_hours_ui_1_5
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = bpy.context.scene
|
||||
ui_props = scene.blenderkitUI
|
||||
return ui_props.active_index > -1
|
||||
|
||||
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)
|
||||
col.separator()
|
||||
col.prop(self, 'rating_work_hours')
|
||||
row = col.row()
|
||||
if self.asset_type == 'model':
|
||||
row.prop(self, 'rating_work_hours_ui', expand=True, icon_only=False, emboss=True)
|
||||
else:
|
||||
row.prop(self, 'rating_work_hours_ui_1_5', expand=True, icon_only=False, emboss=True)
|
||||
|
||||
def execute(self, context):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
api_key = user_preferences.api_key
|
||||
headers = utils.get_headers(api_key)
|
||||
|
||||
url = paths.get_api_url() + f'assets/{self.asset_id}/rating/'
|
||||
|
||||
rtgs = [
|
||||
|
||||
]
|
||||
|
||||
self.rating_quality = int(self.rating_quality_ui)
|
||||
|
||||
if self.rating_quality > 0.1:
|
||||
rtgs.append(('quality', self.rating_quality))
|
||||
if self.rating_work_hours > 0.1:
|
||||
rtgs.append(('working_hours', round(self.rating_work_hours, 1)))
|
||||
|
||||
thread = threading.Thread(target=upload_rating_thread, args=(url, rtgs, headers))
|
||||
thread.start()
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
scene = bpy.context.scene
|
||||
ui_props = scene.blenderkitUI
|
||||
if ui_props.active_index > -1:
|
||||
sr = bpy.context.scene['search results']
|
||||
asset_data = dict(sr[ui_props.active_index])
|
||||
self.asset_id = asset_data['id']
|
||||
self.asset_type = asset_data['assetType']
|
||||
self.message = f"Rate asset {asset_data['name']}"
|
||||
wm = context.window_manager
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
|
||||
def rating_menu_draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ui_props = context.scene.blenderkitUI
|
||||
sr = bpy.context.scene['search results orig']
|
||||
|
||||
asset_search_index = ui_props.active_index
|
||||
if asset_search_index > -1:
|
||||
asset_data = dict(sr['results'][asset_search_index])
|
||||
|
||||
col = layout.column()
|
||||
layout.label(text='Admin rating Tools:')
|
||||
col.operator_context = 'INVOKE_DEFAULT'
|
||||
|
||||
op = col.operator('wm.blenderkit_menu_rating_upload', text='Fast rate')
|
||||
op.asset_id = asset_data['id']
|
||||
op.asset_type = asset_data['assetType']
|
||||
|
||||
def register_ratings():
|
||||
pass;
|
||||
# bpy.utils.register_class(StarRatingOperator)
|
||||
bpy.utils.register_class(UploadRatingOperator)
|
||||
bpy.utils.register_class(FastRateMenu)
|
||||
# bpy.types.OBJECT_MT_blenderkit_asset_menu.append(rating_menu_draw)
|
||||
|
||||
|
||||
def unregister_ratings():
|
||||
pass;
|
||||
# bpy.utils.unregister_class(StarRatingOperator)
|
||||
bpy.utils.unregister_class(UploadRatingOperator)
|
||||
bpy.utils.unregister_class(FastRateMenu)
|
||||
|
|
|
@ -280,7 +280,7 @@ def timer_update():
|
|||
# TODO here it should check if there are some results, and only open assetbar if this is the case, not search.
|
||||
# if bpy.context.scene.get('search results') is None:
|
||||
search()
|
||||
preferences.first_run = False
|
||||
# preferences.first_run = False
|
||||
if preferences.tips_on_start:
|
||||
utils.get_largest_area()
|
||||
ui.update_ui_size(ui.active_area, ui.active_region)
|
||||
|
@ -1161,14 +1161,6 @@ def search(category='', get_next=False, author_id=''):
|
|||
scene = bpy.context.scene
|
||||
ui_props = scene.blenderkitUI
|
||||
|
||||
### updating of search categories was moved here, due to the reason that BlenderKit created the blenderkit_data
|
||||
# folder upon registration of BlenderKit, which wasn't a favourite option for some users (devs running tests).
|
||||
# user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
# if not user_preferences.first_run:
|
||||
# api_key = user_preferences.api_key
|
||||
# if bpy.context.window_manager.get('bkit_categories') is None:
|
||||
# categories.fetch_categories_thread(api_key)
|
||||
|
||||
if ui_props.asset_type == 'MODEL':
|
||||
if not hasattr(scene, 'blenderkit'):
|
||||
return;
|
||||
|
|
|
@ -876,7 +876,8 @@ def draw_callback_2d_search(self, context):
|
|||
else:
|
||||
iname = utils.previmg_name(ui_props.active_index)
|
||||
img = bpy.data.images.get(iname)
|
||||
img.colorspace_settings.name = 'sRGB'
|
||||
if img:
|
||||
img.colorspace_settings.name = 'sRGB'
|
||||
|
||||
gimg = None
|
||||
atip = ''
|
||||
|
@ -931,9 +932,21 @@ def mouse_raycast(context, mx, my):
|
|||
# rote = mathutils.Euler((0, 0, math.pi))
|
||||
randoffset = math.pi
|
||||
if has_hit:
|
||||
snapped_rotation = snapped_normal.to_track_quat('Z', 'Y').to_euler()
|
||||
up = Vector((0, 0, 1))
|
||||
props = bpy.context.scene.blenderkit_models
|
||||
up = Vector((0, 0, 1))
|
||||
|
||||
if props.perpendicular_snap:
|
||||
if snapped_normal.z > 1 - props.perpendicular_snap_threshold:
|
||||
snapped_normal = Vector((0, 0, 1))
|
||||
elif snapped_normal.z < -1 + props.perpendicular_snap_threshold:
|
||||
snapped_normal = Vector((0, 0, -1))
|
||||
elif abs(snapped_normal.z) < props.perpendicular_snap_threshold:
|
||||
snapped_normal.z = 0
|
||||
snapped_normal.normalize()
|
||||
|
||||
snapped_rotation = snapped_normal.to_track_quat('Z', 'Y').to_euler()
|
||||
|
||||
|
||||
if props.randomize_rotation and snapped_normal.angle(up) < math.radians(10.0):
|
||||
randoffset = props.offset_rotation_amount + math.pi + (
|
||||
random.random() - 0.5) * props.randomize_rotation_amount
|
||||
|
@ -1668,6 +1681,7 @@ class AssetBarOperator(bpy.types.Operator):
|
|||
utils.p('author:', a)
|
||||
search.search(author_id=a)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
if event.type == 'X' and ui_props.active_index > -1:
|
||||
# delete downloaded files for this asset
|
||||
sr = bpy.context.scene['search results']
|
||||
|
@ -1845,13 +1859,15 @@ def register_ui():
|
|||
if not wm.keyconfigs.addon:
|
||||
return
|
||||
km = wm.keyconfigs.addon.keymaps.new(name="Window", space_type='EMPTY')
|
||||
#asset bar shortcut
|
||||
kmi = km.keymap_items.new(AssetBarOperator.bl_idname, 'SEMI_COLON', 'PRESS', ctrl=False, shift=False)
|
||||
kmi.properties.keep_running = False
|
||||
kmi.properties.do_search = False
|
||||
addon_keymapitems.append(kmi)
|
||||
# auto open after searching:
|
||||
kmi = km.keymap_items.new(RunAssetBarWithContext.bl_idname, 'SEMI_COLON', 'PRESS', \
|
||||
ctrl=True, shift=True, alt=True)
|
||||
#fast rating shortcut
|
||||
wm = bpy.context.window_manager
|
||||
km = wm.keyconfigs.addon.keymaps['Window']
|
||||
kmi = km.keymap_items.new(ratings.FastRateMenu.bl_idname, 'F', 'PRESS', ctrl=False, shift=False)
|
||||
addon_keymapitems.append(kmi)
|
||||
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ import os
|
|||
import random
|
||||
|
||||
|
||||
|
||||
# this was moved to separate interface:
|
||||
|
||||
def draw_ratings(layout, context, asset):
|
||||
|
@ -63,9 +62,8 @@ def draw_ratings(layout, context, asset):
|
|||
# layout.template_icon_view(bkit_ratings, property, show_labels=False, scale=6.0, scale_popup=5.0)
|
||||
|
||||
row = col.row()
|
||||
row.prop(bkit_ratings , 'rating_quality_ui', expand=True, icon_only=True, emboss=False)
|
||||
#ratings.draw_rating(col, bkit_ratings, 'rating_quality', 'Quality')
|
||||
if bkit_ratings.rating_quality>0:
|
||||
row.prop(bkit_ratings, 'rating_quality_ui', expand=True, icon_only=True, emboss=False)
|
||||
if bkit_ratings.rating_quality > 0:
|
||||
col.separator()
|
||||
col.prop(bkit_ratings, 'rating_work_hours')
|
||||
# w = context.region.width
|
||||
|
@ -81,7 +79,7 @@ def draw_ratings(layout, context, asset):
|
|||
# re-enable layout if included in longer panel
|
||||
|
||||
|
||||
def draw_not_logged_in(source, message = 'Please Login/Signup to use this feature' ):
|
||||
def draw_not_logged_in(source, message='Please Login/Signup to use this feature'):
|
||||
title = "You aren't logged in"
|
||||
|
||||
def draw_message(source, context):
|
||||
|
@ -104,7 +102,7 @@ def draw_upload_common(layout, props, asset_type, context):
|
|||
|
||||
row = layout.row(align=True)
|
||||
if props.upload_state != '':
|
||||
utils.label_multiline(layout, text=props.upload_state, width=context.region.width)
|
||||
utils.label_multiline(layout, text=props.upload_state, width=context.region.width)
|
||||
if props.uploading:
|
||||
op = layout.operator('object.kill_bg_process', text="", icon='CANCEL')
|
||||
op.process_source = asset_type
|
||||
|
@ -193,7 +191,7 @@ def draw_panel_model_upload(self, context):
|
|||
op.process_source = 'MODEL'
|
||||
op.process_type = 'THUMBNAILER'
|
||||
elif props.thumbnail_generating_state != '':
|
||||
utils.label_multiline(layout, text=props.thumbnail_generating_state)
|
||||
utils.label_multiline(layout, text=props.thumbnail_generating_state)
|
||||
|
||||
layout.prop(props, 'description')
|
||||
layout.prop(props, 'tags')
|
||||
|
@ -359,7 +357,8 @@ class VIEW3D_PT_blenderkit_model_properties(Panel):
|
|||
o = utils.get_active_model()
|
||||
# o = bpy.context.active_object
|
||||
if o.get('asset_data') is None:
|
||||
utils.label_multiline(layout, text='To upload this asset to BlenderKit, go to the Find and Upload Assets panel.')
|
||||
utils.label_multiline(layout,
|
||||
text='To upload this asset to BlenderKit, go to the Find and Upload Assets panel.')
|
||||
layout.prop(o, 'name')
|
||||
|
||||
if o.get('asset_data') is not None:
|
||||
|
@ -383,12 +382,14 @@ class VIEW3D_PT_blenderkit_model_properties(Panel):
|
|||
# fun override project, not finished
|
||||
# layout.operator('object.blenderkit_color_corrector')
|
||||
|
||||
def draw_rating_asset(self,context,asset):
|
||||
|
||||
def draw_rating_asset(self, context, asset):
|
||||
layout = self.layout
|
||||
col = layout.box()
|
||||
# split = layout.split(factor=0.5)
|
||||
# col1 = split.column()
|
||||
# col2 = split.column()
|
||||
# print('%s_search' % asset['asset_data']['assetType'])
|
||||
directory = paths.get_temp_dir('%s_search' % asset['asset_data']['assetType'])
|
||||
tpath = os.path.join(directory, asset['asset_data']['thumbnail_small'])
|
||||
for image in bpy.data.images:
|
||||
|
@ -401,8 +402,6 @@ def draw_rating_asset(self,context,asset):
|
|||
draw_ratings(col, context, asset=asset)
|
||||
|
||||
|
||||
|
||||
|
||||
class VIEW3D_PT_blenderkit_ratings(Panel):
|
||||
bl_category = "BlenderKit"
|
||||
bl_idname = "VIEW3D_PT_blenderkit_ratings"
|
||||
|
@ -418,16 +417,17 @@ class VIEW3D_PT_blenderkit_ratings(Panel):
|
|||
return p
|
||||
|
||||
def draw(self, context):
|
||||
#TODO make a list of assets inside asset appending code, to happen only when assets are added to the scene.
|
||||
# TODO make a list of assets inside asset appending code, to happen only when assets are added to the scene.
|
||||
# draw asset properties here
|
||||
layout = self.layout
|
||||
assets = ratings.get_assets_for_rating()
|
||||
if len(assets)>0:
|
||||
layout.label(text = 'Help BlenderKit community')
|
||||
layout.label(text = 'by rating these assets:')
|
||||
if len(assets) > 0:
|
||||
layout.label(text='Help BlenderKit community')
|
||||
layout.label(text='by rating these assets:')
|
||||
|
||||
for a in assets:
|
||||
draw_rating_asset(self, context, asset = a)
|
||||
draw_rating_asset(self, context, asset=a)
|
||||
|
||||
|
||||
def draw_login_progress(layout):
|
||||
layout.label(text='Login through browser')
|
||||
|
@ -520,7 +520,7 @@ def draw_panel_model_rating(self, context):
|
|||
# o = bpy.context.active_object
|
||||
o = utils.get_active_model()
|
||||
# print('ratings active',o)
|
||||
draw_ratings(self.layout, context, asset = o) # , props)
|
||||
draw_ratings(self.layout, context, asset=o) # , props)
|
||||
# op.asset_type = 'MODEL'
|
||||
|
||||
|
||||
|
@ -564,7 +564,7 @@ def draw_panel_material_upload(self, context):
|
|||
op.process_source = 'MATERIAL'
|
||||
op.process_type = 'THUMBNAILER'
|
||||
elif props.thumbnail_generating_state != '':
|
||||
utils.label_multiline(layout, text=props.thumbnail_generating_state)
|
||||
utils.label_multiline(layout, text=props.thumbnail_generating_state)
|
||||
|
||||
if bpy.context.scene.render.engine in ('CYCLES', 'BLENDER_EEVEE'):
|
||||
layout.operator("object.blenderkit_material_thumbnail", text='Render thumbnail with Cycles', icon='EXPORT')
|
||||
|
@ -634,12 +634,12 @@ def draw_panel_brush_search(self, context):
|
|||
def draw_panel_brush_ratings(self, context):
|
||||
# props = utils.get_brush_props(context)
|
||||
brush = utils.get_active_brush()
|
||||
draw_ratings(self.layout, context, asset = brush) # , props)
|
||||
draw_ratings(self.layout, context, asset=brush) # , props)
|
||||
#
|
||||
# op.asset_type = 'BRUSH'
|
||||
|
||||
|
||||
def draw_login_buttons(layout, invoke = False):
|
||||
def draw_login_buttons(layout, invoke=False):
|
||||
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
|
||||
|
||||
if user_preferences.login_attempt:
|
||||
|
@ -782,7 +782,7 @@ class VIEW3D_PT_blenderkit_categories(Panel):
|
|||
s = context.scene
|
||||
ui_props = s.blenderkitUI
|
||||
mode = True
|
||||
if ui_props.asset_type == 'BRUSH' and not (context.sculpt_object or context.image_paint_object):
|
||||
if ui_props.asset_type == 'BRUSH' and not (context.sculpt_object or context.image_paint_object):
|
||||
mode = False
|
||||
return ui_props.down_up == 'SEARCH' and mode
|
||||
|
||||
|
@ -820,6 +820,10 @@ class VIEW3D_PT_blenderkit_import_settings(Panel):
|
|||
layout.prop(props, 'randomize_rotation')
|
||||
if props.randomize_rotation:
|
||||
layout.prop(props, 'randomize_rotation_amount')
|
||||
layout.prop(props, 'perpendicular_snap')
|
||||
if props.perpendicular_snap:
|
||||
layout.prop(props,'perpendicular_snap_threshold')
|
||||
|
||||
if ui_props.asset_type == 'MATERIAL':
|
||||
props = s.blenderkit_mat
|
||||
layout.prop(props, 'automap')
|
||||
|
@ -924,7 +928,7 @@ class VIEW3D_PT_blenderkit_unified(Panel):
|
|||
return;
|
||||
|
||||
if ui_props.asset_type == 'MODEL':
|
||||
#utils.label_multiline(layout, "Uploaded models won't be available in b2.79", icon='ERROR')
|
||||
# utils.label_multiline(layout, "Uploaded models won't be available in b2.79", icon='ERROR')
|
||||
if bpy.context.view_layer.objects.active is not None:
|
||||
draw_panel_model_upload(self, context)
|
||||
else:
|
||||
|
@ -933,12 +937,12 @@ class VIEW3D_PT_blenderkit_unified(Panel):
|
|||
draw_panel_scene_upload(self, context)
|
||||
|
||||
elif ui_props.asset_type == 'MATERIAL':
|
||||
#utils.label_multiline(layout, "Uploaded materials won't be available in b2.79", icon='ERROR')
|
||||
# utils.label_multiline(layout, "Uploaded materials won't be available in b2.79", icon='ERROR')
|
||||
|
||||
if bpy.context.view_layer.objects.active is not None and bpy.context.active_object.active_material is not None:
|
||||
draw_panel_material_upload(self, context)
|
||||
else:
|
||||
utils.label_multiline(layout, text='select object with material to upload materials', width=w)
|
||||
utils.label_multiline(layout, text='select object with material to upload materials', width=w)
|
||||
|
||||
elif ui_props.asset_type == 'BRUSH':
|
||||
if context.sculpt_object or context.image_paint_object:
|
||||
|
@ -972,6 +976,7 @@ class VIEW3D_PT_blenderkit_unified(Panel):
|
|||
if ui_props.asset_type == 'TEXTURE':
|
||||
layout.label(text='not yet implemented')
|
||||
|
||||
|
||||
class BlenderKitWelcomeOperator(bpy.types.Operator):
|
||||
"""Login online on BlenderKit webpage"""
|
||||
|
||||
|
@ -993,27 +998,36 @@ class BlenderKitWelcomeOperator(bpy.types.Operator):
|
|||
def draw(self, context):
|
||||
layout = self.layout
|
||||
if self.step == 0:
|
||||
message = "BlenderKit is an addon that connects to the internet to search and upload for models, materials, and brushes. \n\n Let's start by searching for some cool materials?"
|
||||
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."
|
||||
|
||||
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 = "This shouldn't be here at all"
|
||||
utils.label_multiline(layout, text= message, width = 300)
|
||||
message = "Operator Tutorial called with invalid step"
|
||||
|
||||
def execute(self, context):
|
||||
if self.step == 0:
|
||||
#move mouse:
|
||||
#bpy.context.window_manager.windows[0].cursor_warp(1000, 1000)
|
||||
#show n-key sidebar (spaces[index] has to be found for view3d too:
|
||||
# move mouse:
|
||||
# bpy.context.window_manager.windows[0].cursor_warp(1000, 1000)
|
||||
# show n-key sidebar (spaces[index] has to be found for view3d too:
|
||||
# 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'
|
||||
search.search()
|
||||
bpy.context.scene.blenderkit_mat.search_keywords = 'ice'
|
||||
# search.search()
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = bpy.context.window_manager
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
|
||||
def draw_asset_context_menu(self, context, asset_data):
|
||||
layout = self.layout
|
||||
ui_props = context.scene.blenderkitUI
|
||||
|
@ -1024,10 +1038,11 @@ def draw_asset_context_menu(self, context, asset_data):
|
|||
a = bpy.context.window_manager['bkit authors'].get(author_id)
|
||||
if a is not None:
|
||||
# utils.p('author:', a)
|
||||
op = layout.operator('wm.url_open', text="Open Author's Website")
|
||||
if a.get('aboutMeUrl') is not None:
|
||||
op = layout.operator('wm.url_open', text="Open Author's Website")
|
||||
op.url = a['aboutMeUrl']
|
||||
|
||||
else:
|
||||
op.url = paths.get_author_gallery_url(a['id'])
|
||||
op = layout.operator('view3d.blenderkit_search', text="Show Assets By Author")
|
||||
op.keywords = ''
|
||||
op.author_id = author_id
|
||||
|
@ -1080,6 +1095,8 @@ def draw_asset_context_menu(self, context, asset_data):
|
|||
op.asset_id = asset_data['id']
|
||||
op.state = 'rejected'
|
||||
|
||||
|
||||
|
||||
if author_id == str(profile['user']['id']):
|
||||
layout.label(text='Management tools:')
|
||||
row = layout.row()
|
||||
|
@ -1087,9 +1104,13 @@ def draw_asset_context_menu(self, context, asset_data):
|
|||
op = row.operator('object.blenderkit_change_status', text='Delete')
|
||||
op.asset_id = asset_data['id']
|
||||
op.state = 'deleted'
|
||||
# else:
|
||||
# #not an author - can rate
|
||||
# draw_ratings(layout, context)
|
||||
|
||||
if utils.profile_is_validator():
|
||||
layout.label(text='Admin rating Tools:')
|
||||
|
||||
op = layout.operator('wm.blenderkit_menu_rating_upload', text='Fast rate')
|
||||
op.asset_id = asset_data['id']
|
||||
op.asset_type = asset_data['assetType']
|
||||
|
||||
|
||||
class OBJECT_MT_blenderkit_asset_menu(bpy.types.Menu):
|
||||
|
@ -1104,6 +1125,7 @@ class OBJECT_MT_blenderkit_asset_menu(bpy.types.Menu):
|
|||
asset_data = sr[ui_props.active_index]
|
||||
draw_asset_context_menu(self, context, asset_data)
|
||||
|
||||
|
||||
class OBJECT_MT_blenderkit_login_menu(bpy.types.Menu):
|
||||
bl_label = "BlenderKit login/signup:"
|
||||
bl_idname = "OBJECT_MT_blenderkit_login_menu"
|
||||
|
@ -1188,6 +1210,7 @@ class UrlPopupDialog(bpy.types.Operator):
|
|||
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
|
||||
class LoginPopupDialog(bpy.types.Operator):
|
||||
"""Generate Cycles thumbnail for model assets"""
|
||||
bl_idname = "wm.blenderkit_url_dialog"
|
||||
|
|
|
@ -767,7 +767,7 @@ class UploadOperator(Operator):
|
|||
layout.label(text="For updates of thumbnail or model use reupload.")
|
||||
|
||||
if props.is_private == 'PUBLIC':
|
||||
ui_panels.label_multiline(layout, text='public assets are validated several hours'
|
||||
utils.label_multiline(layout, text='public assets are validated several hours'
|
||||
' or days after upload. Remember always to '
|
||||
'test download your asset to a clean file'
|
||||
' to see if it uploaded correctly.'
|
||||
|
|
Loading…
Reference in New Issue