Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVilém Duha <vilda.novak@gmail.com>2020-07-27 13:59:38 +0300
committerVilém Duha <vilda.novak@gmail.com>2020-07-29 23:17:27 +0300
commit06181ee9947d558d5323471c9b5d9792267fdb66 (patch)
tree56fd77163c173a7cecfb9d5da1910ca5b8c391c6
parent66bd6dea71862d8f55ede79879117d9e7de882a4 (diff)
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 8f6903bc92531aa8e5d4c64a0a108c2904506a83)
-rw-r--r--blenderkit/__init__.py64
-rw-r--r--blenderkit/paths.py3
-rw-r--r--blenderkit/ratings.py269
-rw-r--r--blenderkit/search.py10
-rw-r--r--blenderkit/ui.py28
-rw-r--r--blenderkit/ui_panels.py95
-rw-r--r--blenderkit/upload.py2
7 files changed, 328 insertions, 143 deletions
diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py
index 23ee89c5..fba80a7e 100644
--- a/blenderkit/__init__.py
+++ b/blenderkit/__init__.py
@@ -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():
diff --git a/blenderkit/paths.py b/blenderkit/paths.py
index b4210a85..399e7555 100644
--- a/blenderkit/paths.py
+++ b/blenderkit/paths.py
@@ -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
diff --git a/blenderkit/ratings.py b/blenderkit/ratings.py
index 48c34a61..800749c8 100644
--- a/blenderkit/ratings.py
+++ b/blenderkit/ratings.py
@@ -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)
diff --git a/blenderkit/search.py b/blenderkit/search.py
index cee0b14b..6c8d16e2 100644
--- a/blenderkit/search.py
+++ b/blenderkit/search.py
@@ -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;
diff --git a/blenderkit/ui.py b/blenderkit/ui.py
index 30195168..7935363d 100644
--- a/blenderkit/ui.py
+++ b/blenderkit/ui.py
@@ -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)
diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py
index d067afa0..89646862 100644
--- a/blenderkit/ui_panels.py
+++ b/blenderkit/ui_panels.py
@@ -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"
diff --git a/blenderkit/upload.py b/blenderkit/upload.py
index 18e43b8a..14fbe6db 100644
--- a/blenderkit/upload.py
+++ b/blenderkit/upload.py
@@ -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.'