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-01-24 21:43:06 +0300
committerVilém Duha <vilda.novak@gmail.com>2020-01-28 15:45:44 +0300
commit7410d631ce4ac4f3e53c1d634eb6b70499398371 (patch)
tree482c12a3363f5b1eb560779d1e0ba0df0b197081 /blenderkit
parent7c3d8127daf1f32858076484d07fd8a6e96a3fb0 (diff)
BlenderKit:
-icons module -clipboard monitoring -fix link to website when people want to see asset online -advanced search parameters
Diffstat (limited to 'blenderkit')
-rw-r--r--blenderkit/__init__.py113
-rw-r--r--blenderkit/icons.py53
-rw-r--r--blenderkit/paths.py1
-rw-r--r--blenderkit/ratings.py2
-rw-r--r--blenderkit/search.py139
-rw-r--r--blenderkit/thumbnails/flp.pngbin0 -> 540 bytes
-rw-r--r--blenderkit/thumbnails/fp.pngbin0 -> 561 bytes
-rw-r--r--blenderkit/ui.py3
-rw-r--r--blenderkit/ui_panels.py122
9 files changed, 288 insertions, 145 deletions
diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py
index f8b31fec..fc2599a2 100644
--- a/blenderkit/__init__.py
+++ b/blenderkit/__init__.py
@@ -39,6 +39,7 @@ if "bpy" in locals():
ratings = reload(ratings)
autothumb = reload(autothumb)
ui = reload(ui)
+ icons = reload(icons)
bg_blender = reload(bg_blender)
paths = reload(paths)
utils = reload(utils)
@@ -48,7 +49,8 @@ if "bpy" in locals():
bkit_oauth = reload(bkit_oauth)
tasks_queue = reload(tasks_queue)
else:
- from blenderkit import asset_inspector, search, download, upload, ratings, autothumb, ui, bg_blender, paths, utils, \
+ from blenderkit import asset_inspector, search, download, upload, ratings, autothumb, ui, icons, bg_blender, paths, \
+ utils, \
overrides, ui_panels, categories, bkit_oauth, tasks_queue
import os
@@ -91,6 +93,7 @@ def scene_load(context):
preferences = bpy.context.preferences.addons['blenderkit'].preferences
preferences.login_attempt = False
+
def check_timers_timer():
''' checks if all timers are registered regularly. Prevents possible bugs from stopping the addon.'''
if not bpy.app.timers.is_registered(search.timer_update):
@@ -103,6 +106,7 @@ def check_timers_timer():
bpy.app.timers.register(bg_blender.bg_update)
return 5.0
+
licenses = (
('royalty_free', 'Royalty Free', 'royalty free commercial license'),
('cc_zero', 'Creative Commons Zero', 'Creative Commons Zero'),
@@ -191,6 +195,7 @@ thumbnail_resolutions = (
('2048', '2048', ''),
)
+
def get_upload_asset_type(self):
typemapper = {
BlenderKitModelUploadProps: 'model',
@@ -244,9 +249,10 @@ 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):
- #s = bpy.context.scene
- #ui_props = s.blenderkitUI
+ # s = bpy.context.scene
+ # ui_props = s.blenderkitUI
if self.down_up == 'SEARCH':
items = (
('MODEL', 'Find Models', 'Find models in the BlenderKit online database', 'OBJECT_DATAMODE', 0),
@@ -265,6 +271,7 @@ def asset_type_callback(self, context):
)
return items
+
class BlenderKitUIProps(PropertyGroup):
down_up: EnumProperty(
name="Download vs Upload",
@@ -387,13 +394,35 @@ class BlenderKitCommonSearchProps(object):
search_done: BoolProperty(name="Search Completed", description="at least one search did run (internal)",
default=False)
own_only: BoolProperty(name="My Assets", description="Search only for your assets",
- default=False)
+ default=False)
search_error: BoolProperty(name="Search Error", description="last search had an error", default=False)
report: StringProperty(
name="Report",
description="errors and messages",
default="")
+ # TEXTURE RESOLUTION
+ search_texture_resolution: BoolProperty(name="Texture Resolution",
+ description="Span of the texture resolutions",
+ default=False,
+ update=search.search_update,
+ )
+ search_texture_resolution_min: IntProperty(name="Min Texture Resolution",
+ description="Minimum texture resolution",
+ default=256,
+ min=0,
+ max=32768,
+ update=search.search_update,
+ )
+
+ search_texture_resolution_max: IntProperty(name="Max Texture Resolution",
+ description="Maximum texture resolution",
+ default=4096,
+ min=0,
+ max=32768,
+ update=search.search_update,
+ )
+
def name_update(self, context):
''' checks for name change, because it decides if whole asset has to be re-uploaded. Name is stored in the blend file
@@ -401,7 +430,6 @@ def name_update(self, context):
utils.name_update()
-
def update_tags(self, context):
props = utils.get_upload_props()
@@ -426,6 +454,7 @@ def update_tags(self, context):
if props.tags != ns:
props.tags = ns
+
def update_free(self, context):
if self.is_free == False:
self.is_free = True
@@ -440,6 +469,7 @@ def update_free(self, context):
bpy.context.window_manager.popup_menu(draw_message, title=title, icon='INFO')
+
class BlenderKitCommonUploadProps(object):
id: StringProperty(
name="Asset Version Id",
@@ -506,9 +536,9 @@ class BlenderKitCommonUploadProps(object):
)
is_procedural: BoolProperty(name="Procedural",
- description="Asset is procedural - has no texture.",
- default=True
- )
+ description="Asset is procedural - has no texture.",
+ default=True
+ )
node_count: IntProperty(name="Node count", description="Total nodes in the asset", default=0)
texture_count: IntProperty(name="Texture count", description="Total texture count in asset", default=0)
total_megapixels: IntProperty(name="Megapixels", description="Total megapixels of texture", default=0)
@@ -593,22 +623,26 @@ class BlenderKitMaterialSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
items=search_material_styles,
description="Style of material",
default="ANY",
+ update=search.search_update,
)
search_style_other: StringProperty(
name="Style Other",
description="Style not in the list",
default="",
+ update=search.search_update,
)
search_engine: EnumProperty(
name='Engine',
items=engines,
default='NONE',
description='Output engine',
+ update=search.search_update,
)
search_engine_other: StringProperty(
name="Engine",
description="engine not specified by addon",
default="",
+ update=search.search_update,
)
automap: BoolProperty(name="Auto-Map",
description="reset object texture space and also add automatically a cube mapped UV "
@@ -1147,10 +1181,10 @@ class BlenderKitModelSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
)
free_only: BoolProperty(name="Free only", description="Show only free models",
- default=False)
+ default=False,update=search.search_update)
search_advanced: BoolProperty(name="Advanced Search Options", description="use advanced search properties",
- default=False)
+ default=False,update=search.search_update)
# CONDITION
search_condition: EnumProperty(
@@ -1169,9 +1203,9 @@ class BlenderKitModelSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
search_procedural: EnumProperty(
items=(
- ('BOTH', 'Both',''),
- ('PROCEDURAL', 'Procedural',''),
- ('TEXTURE_BASED', 'Texture based',''),
+ ('BOTH', 'Both', ''),
+ ('PROCEDURAL', 'Procedural', ''),
+ ('TEXTURE_BASED', 'Texture based', ''),
),
default='BOTH',
@@ -1182,51 +1216,47 @@ class BlenderKitModelSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
# DESIGN YEAR
search_design_year: BoolProperty(name="Sesigned in Year",
description="when the object was approximately designed",
- default=False)
+ default=False,
+ update=search.search_update,
+ )
search_design_year_min: IntProperty(name="Min Age",
description="when the object was approximately designed",
- default=1950, min=-100000000, max=1000000000)
+ default=1950, min=-100000000, max=1000000000,
+ update=search.search_update,
+ )
search_design_year_max: IntProperty(name="Max Age",
description="when the object was approximately designed",
default=2017,
min=0,
- max=10000000)
+ max=10000000,
+ update=search.search_update,
+ )
- # TEXTURE RESOLUTION
- search_texture_resolution: BoolProperty(name="Texture Resolution",
- description="Span of the texture resolutions",
- default=False)
- search_texture_resolution_min: IntProperty(name="Min Texture Resolution",
- description="when the object was approximately designed",
- default=256,
- min=0,
- max=32768)
- search_texture_resolution_max: IntProperty(name="Max Texture Resolution",
- description="when the object was approximately designed",
- default=4096,
- min=0,
- max=32768)
# POLYCOUNT
search_polycount: BoolProperty(name="Use Polycount",
description="use polycount of object search tag",
- default=False)
+ default=False,
+ update=search.search_update,)
search_polycount_min: IntProperty(name="Min Polycount",
description="polycount of the asset minimum",
default=0,
min=0,
- max=100000000)
+ max=100000000,
+ update=search.search_update,)
search_polycount_max: IntProperty(name="Max Polycount",
description="polycount of the asset maximum",
default=100000000,
min=0,
- max=100000000)
+ max=100000000,
+ update=search.search_update,
+ )
append_method: EnumProperty(
name="Import Method",
@@ -1313,6 +1343,7 @@ class BlenderKitSceneSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
)
+
class BlenderKitAddonPreferences(AddonPreferences):
# this must match the addon name, use '__package__'
# when defining this in a submodule of a python package.
@@ -1338,9 +1369,9 @@ class BlenderKitAddonPreferences(AddonPreferences):
)
api_key_timeout: IntProperty(
- name = 'api key timeout',
- description = 'time where the api key will need to be refreshed',
- default = 0,
+ name='api key timeout',
+ description='time where the api key will need to be refreshed',
+ default=0,
)
api_key_life: IntProperty(
@@ -1370,7 +1401,7 @@ class BlenderKitAddonPreferences(AddonPreferences):
tips_on_start: BoolProperty(
name="Show tips when starting blender",
description="Show tips when starting blender",
- default=True
+ default=False
)
search_in_header: BoolProperty(
@@ -1439,10 +1470,8 @@ class BlenderKitAddonPreferences(AddonPreferences):
min=0,
max=20)
-
thumb_size: IntProperty(name="Assetbar thumbnail Size", default=96, min=-1, max=256)
-
asset_counter: IntProperty(name="Usage Counter",
description="Counts usages so it asks for registration only after reaching a limit",
default=0,
@@ -1473,7 +1502,7 @@ class BlenderKitAddonPreferences(AddonPreferences):
layout.operator("wm.blenderkit_logout", text="Logout",
icon='URL')
- #if not self.enable_oauth:
+ # if not self.enable_oauth:
layout.prop(self, "api_key", text='Your API Key')
# layout.label(text='After you paste API Key, categories are downloaded, so blender will freeze for a few seconds.')
layout.prop(self, "global_dir")
@@ -1489,7 +1518,6 @@ class BlenderKitAddonPreferences(AddonPreferences):
layout.prop(self, "search_in_header")
-
# registration
classes = (
@@ -1560,6 +1588,7 @@ def register():
ratings.register_ratings()
autothumb.register_thumbnailer()
ui.register_ui()
+ icons.register_icons()
ui_panels.register_ui_panels()
bg_blender.register()
utils.load_prefs()
@@ -1573,10 +1602,10 @@ def register():
def unregister():
-
bpy.app.timers.unregister(check_timers_timer)
ui.unregister_ui()
+ icons.unregister_icons()
search.unregister_search()
asset_inspector.unregister_asset_inspector()
download.unregister_download()
diff --git a/blenderkit/icons.py b/blenderkit/icons.py
new file mode 100644
index 00000000..3c6cea4b
--- /dev/null
+++ b/blenderkit/icons.py
@@ -0,0 +1,53 @@
+# ##### 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 #####
+
+
+import os
+import bpy
+
+# We can store multiple preview collections here,
+# however in this example we only store "main"
+icon_collections = {}
+
+icons_read = {
+ 'fp.png': 'free',
+ 'flp.png': 'full',
+}
+
+
+def register_icons():
+ # Note that preview collections returned by bpy.utils.previews
+ # are regular py objects - you can use them to store custom data.
+ import bpy.utils.previews
+ pcoll = bpy.utils.previews.new()
+
+ # path to the folder where the icon is
+ # the path is calculated relative to this py file inside the addon folder
+ icons_dir = os.path.join(os.path.dirname(__file__), "thumbnails")
+
+ # load a preview thumbnail of a file and store in the previews collection
+ for ir in icons_read.keys():
+ pcoll.load(icons_read[ir], os.path.join(icons_dir, ir), 'IMAGE')
+
+ icon_collections["main"] = pcoll
+
+
+def unregister_icons():
+ for pcoll in icon_collections.values():
+ bpy.utils.previews.remove(pcoll)
+ icon_collections.clear()
diff --git a/blenderkit/paths.py b/blenderkit/paths.py
index 3b0f22f9..112e2465 100644
--- a/blenderkit/paths.py
+++ b/blenderkit/paths.py
@@ -33,7 +33,6 @@ BLENDERKIT_BRUSH_UPLOAD_INSTRUCTIONS_URL = "https://www.blenderkit.com/docs/uplo
BLENDERKIT_LOGIN_URL = "https://www.blenderkit.com/accounts/login"
BLENDERKIT_OAUTH_LANDING_URL = "/oauth-landing/"
BLENDERKIT_SIGNUP_URL = "https://www.blenderkit.com/accounts/register"
-BLENDERKIT_ADDON_FILE_URL = "https://www.blenderkit.com/get-blenderkit/"
BLENDERKIT_SETTINGS_FILENAME = os.path.join(_presets, "bkit.json")
diff --git a/blenderkit/ratings.py b/blenderkit/ratings.py
index 7684d017..fd6bb2e8 100644
--- a/blenderkit/ratings.py
+++ b/blenderkit/ratings.py
@@ -154,7 +154,7 @@ asset_types = (
class UploadRatingOperator(bpy.types.Operator):
"""Upload rating to the web db"""
bl_idname = "object.blenderkit_rating_upload"
- bl_label = "Upload the Rating"
+ bl_label = "Send Rating"
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
# type of upload - model, material, textures, e.t.c.
diff --git a/blenderkit/search.py b/blenderkit/search.py
index 96c1e63e..fd92a87f 100644
--- a/blenderkit/search.py
+++ b/blenderkit/search.py
@@ -86,10 +86,11 @@ rtips = ['Click or drag model or material in scene to link/append ',
"Please rate responsively and plentifully. This helps us distribute rewards to the authors.",
"Click on brushes to link them into scene.",
"All materials and brushes are free.",
+ "Storage for public assets is unlimited.",
"Locked models are available if you subscribe to Full plan.",
"Login to upload your own models, materials or brushes.",
- "Use 'A' key to search assets by same author.",
- "Use 'W' key to open Authors webpage.", ]
+ "Use 'A' key over asset bar to search assets by same author.",
+ "Use 'W' key over asset bar to open Authors webpage.", ]
def refresh_token_timer():
''' this timer gets run every time the token needs refresh. It refreshes tokens and also categories.'''
@@ -127,7 +128,7 @@ def fetch_server_data():
first_time = True
-
+last_clipboard = ''
@bpy.app.handlers.persistent
def timer_update(): # TODO might get moved to handle all blenderkit stuff.
#this makes a first search after opening blender. showing latest assets.
@@ -142,6 +143,22 @@ def timer_update(): # TODO might get moved to handle all blenderkit stuff.
ui.update_ui_size(ui.active_area, ui.active_region)
ui.add_report(text='BlenderKit Tip:' + random.choice(rtips), timeout=12, color=colors.GREEN)
+ # clipboard monitoring to search assets from web
+ global last_clipboard
+ if bpy.context.window_manager.clipboard != last_clipboard:
+ last_clipboard = bpy.context.window_manager.clipboard
+ instr = 'asset_base_id:'
+ if last_clipboard[:len(instr)] == instr:
+ atstr = 'asset_type:'
+ ati = last_clipboard.find(atstr)
+ if ati>-1:
+ at = last_clipboard[ati:]
+
+ search_props = utils.get_search_props()
+ search_props.search_keywords = last_clipboard
+ search()
+
+
global search_threads
# don't do anything while dragging - this could switch asset type during drag, and make results list length different,
# causing a lot of throuble literally.
@@ -700,6 +717,9 @@ def profile_is_validator():
return True
return False
+
+
+
class Searcher(threading.Thread):
query = None
@@ -715,6 +735,43 @@ class Searcher(threading.Thread):
def stopped(self):
return self._stop_event.is_set()
+ def query_to_url(self):
+ query = self.query
+ params = self.params
+ # build a new request
+ url = paths.get_api_url() + 'search/'
+
+
+ # build request manually
+ # TODO use real queries
+ requeststring = '?query='
+ #
+ if query.get('query') not in ('', None):
+ requeststring += query['query'].lower()
+ for i, q in enumerate(query):
+ if q != 'query':
+ requeststring += '+'
+ requeststring += q + ':' + str(query[q]).lower()
+
+ # result ordering: _score - relevance, score - BlenderKit score
+ # first condition assumes no keywords and no category, thus an empty search that is triggered on start.
+ if query.get('query') is None and query.get('category_subtree') == None:
+ requeststring += '+order:-created'
+ elif query.get('author_id') is not None and profile_is_validator():
+ requeststring += '+order:-created'
+ else:
+ if query.get('category_subtree') is not None:
+ requeststring += '+order:-score,_score'
+ else:
+ requeststring += '+order:_score'
+
+ requeststring += '&addon_version=%s' % params['addon_version']
+ if params.get('scene_uuid') is not None:
+ requeststring += '&scene_uuid=%s' % params['scene_uuid']
+ print('params', params)
+ urlquery = url + requeststring
+ return urlquery
+
def run(self):
maxthreads = 50
query = self.query
@@ -736,45 +793,23 @@ class Searcher(threading.Thread):
try:
origdata = json.load(infile)
urlquery = origdata['next']
+ #rparameters = {}
if urlquery == None:
return;
except:
# in case no search results found on drive we don't do next page loading.
params['get_next'] = False
if not params['get_next']:
- # build a new request
url = paths.get_api_url() + 'search/'
- # build request manually
- # TODO use real queries
- requeststring = '?query=' + query['keywords'].lower() + '+'
- #
- for i, q in enumerate(query):
- if q != 'keywords':
- requeststring += q + ':' + str(query[q]).lower()
- if i < len(query) - 1:
- requeststring += '+'
-
- # result ordering: _score - relevance, score - BlenderKit score
- #first condition assumes no keywords and no category, thus an empty search that is triggered on start.
- if query['keywords'] == '' and query.get('category_subtree') == None:
- requeststring += '+order:-created'
- elif query.get('author_id') is not None and profile_is_validator():
- requeststring += '+order:-created'
- else:
- if query.get('category_subtree') is not None:
- requeststring += '+order:-score,_score'
- else:
- requeststring += '+order:_score'
+ urlquery = url
- requeststring += '&addon_version=%s' % params['addon_version']
- if params.get('scene_uuid') is not None:
- requeststring += '&scene_uuid=%s' % params['scene_uuid']
-
- urlquery = url + requeststring
+ #rparameters = query
+ urlquery = self.query_to_url()
try:
utils.p(urlquery)
- r = rerequests.get(urlquery, headers=headers)
+ r = rerequests.get(urlquery, headers=headers)#, params = rparameters)
+ print(r.url)
reports = ''
# utils.p(r.text)
except requests.exceptions.RequestException as e:
@@ -808,7 +843,7 @@ class Searcher(threading.Thread):
# print('number of results: ', len(rdata.get('results', [])))
if self.stopped():
- utils.p('stopping search : ' + query['keywords'])
+ utils.p('stopping search : ' + str(query))
return
mt('search finished')
@@ -867,7 +902,7 @@ class Searcher(threading.Thread):
# TODO do the killing/ stopping here! remember threads might have finished inbetween!
if self.stopped():
- utils.p('stopping search : ' + query['keywords'])
+ utils.p('stopping search : ' + str(query))
return
# this loop handles downloading of small thumbnails
@@ -891,7 +926,7 @@ class Searcher(threading.Thread):
# utils.p('fetched thumbnail ', i)
i += 1
if self.stopped():
- utils.p('stopping search : ' + query['keywords'])
+ utils.p('stopping search : ' + str(query))
return
idx = 0
while len(thumb_sml_download_threads) > 0:
@@ -903,7 +938,7 @@ class Searcher(threading.Thread):
i += 1
if self.stopped():
- utils.p('stopping search : ' + query['keywords'])
+ utils.p('stopping search : ' + str(query))
return
# start downloading full thumbs in the end
@@ -918,10 +953,11 @@ class Searcher(threading.Thread):
def build_query_common(query, props):
- query_common = {
- "keywords": props.search_keywords
- }
- query.update(query_common)
+ if props.search_keywords != '':
+ query_common = {
+ "query": props.search_keywords
+ }
+ query.update(query_common)
# def query_add_range(query, name, rmin, rmax):
@@ -948,19 +984,19 @@ def build_query_model():
if props.search_condition != 'UNSPECIFIED':
query["condition"] = props.search_condition
if props.search_design_year:
- query["designYearMin"] = props.search_design_year_min
- query["designYearMax"] = props.search_design_year_max
+ query["designYear_gte"] = props.search_design_year_min
+ query["designYear_lte"] = props.search_design_year_max
if props.search_polycount:
- query["polyCountMin"] = props.search_polycount_min
- query["polyCountMax"] = props.search_polycount_max
+ query["faceCount_gte"] = props.search_polycount_min
+ query["faceCount_lte"] = props.search_polycount_max
if props.search_texture_resolution:
- query["textureResolutionMin"] = props.search_texture_resolution_min
- query["textureResolutionMax"] = props.search_texture_resolution_max
+ query["textureResolutionMax_gte"] = props.search_texture_resolution_min
+ query["textureResolutionMax_lte"] = props.search_texture_resolution_max
- if props.search_procedural == "PROCEDURAL":
- query["procedural"] = True
- elif props.search_procedural == 'TEXTURE_BASED':
- query["procedural"] = False
+ if props.search_procedural == "PROCEDURAL":
+ query["procedural"] = True
+ elif props.search_procedural == 'TEXTURE_BASED':
+ query["procedural"] = False
build_query_common(query, props)
@@ -997,6 +1033,11 @@ def build_query_material():
query["style"] = props.search_style
else:
query["style"] = props.search_style_other
+
+ if props.search_texture_resolution:
+ query["textureResolutionMax_gte"] = props.search_texture_resolution_min
+ query["textureResolutionMax_lte"] = props.search_texture_resolution_max
+
build_query_common(query, props)
return query
diff --git a/blenderkit/thumbnails/flp.png b/blenderkit/thumbnails/flp.png
new file mode 100644
index 00000000..7ac3c3d7
--- /dev/null
+++ b/blenderkit/thumbnails/flp.png
Binary files differ
diff --git a/blenderkit/thumbnails/fp.png b/blenderkit/thumbnails/fp.png
new file mode 100644
index 00000000..4e356ab1
--- /dev/null
+++ b/blenderkit/thumbnails/fp.png
Binary files differ
diff --git a/blenderkit/ui.py b/blenderkit/ui.py
index be4bd451..f4b64a1f 100644
--- a/blenderkit/ui.py
+++ b/blenderkit/ui.py
@@ -1428,7 +1428,6 @@ class AssetBarOperator(bpy.types.Operator):
ui_props.draw_tooltip = True
ui_props.tooltip = asset_data['tooltip']
-
# bpy.ops.wm.call_menu(name='OBJECT_MT_blenderkit_asset_menu')
else:
@@ -1490,7 +1489,7 @@ class AssetBarOperator(bpy.types.Operator):
if not asset_data['can_download']:
message = 'Asset locked. Find out how to unlock Everything and ...'
link_text = 'support all BlenderKit artists.'
- url = paths.get_bkit_url() + '/get-blenderkit/' + asset_data['id']
+ url = paths.get_bkit_url() + '/get-blenderkit/' + asset_data['id'] + '/?from_addon'
bpy.ops.wm.blenderkit_url_dialog('INVOKE_REGION_WIN', url=url, message=message,
link_text=link_text)
return {'RUNNING_MODAL'}
diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py
index ede93587..50ea8e5d 100644
--- a/blenderkit/ui_panels.py
+++ b/blenderkit/ui_panels.py
@@ -24,8 +24,9 @@ if "bpy" in locals():
utils = importlib.reload(utils)
download = importlib.reload(download)
categories = importlib.reload(categories)
+ icons = importlib.reload(icons)
else:
- from blenderkit import paths, ratings, utils, download, categories
+ from blenderkit import paths, ratings, utils, download, categories, icons
from bpy.types import (
Panel
@@ -75,10 +76,10 @@ def draw_ratings(layout, context):
layout.prop(bkit_ratings, 'rating_work_hours')
w = context.region.width
- layout.label(text='problems')
- layout.prop(bkit_ratings, 'rating_problems', text='')
- layout.label(text='compliments')
- layout.prop(bkit_ratings, 'rating_compliments', text='')
+ # layout.label(text='problems')
+ # layout.prop(bkit_ratings, 'rating_problems', text='')
+ # layout.label(text='compliments')
+ # layout.prop(bkit_ratings, 'rating_compliments', text='')
row = layout.row()
op = row.operator("object.blenderkit_rating_upload", text="Send rating", icon='URL')
@@ -151,7 +152,7 @@ def prop_needed(layout, props, name, value, is_not_filled=''):
# row.label(text='', icon = 'ERROR')
icon = 'ERROR'
row.alert = True
- row.prop(props, name)#, icon=icon)
+ row.prop(props, name) # , icon=icon)
row.alert = False
else:
# row.label(text='', icon = 'FILE_TICK')
@@ -264,6 +265,7 @@ def draw_panel_scene_upload(self, context):
row.prop(props, 'work_hours')
layout.prop(props, 'adult')
+
def draw_assetbar_show_hide(layout, props):
s = bpy.context.scene
ui_props = s.blenderkitUI
@@ -301,7 +303,7 @@ def draw_panel_model_search(self, context):
layout.prop(props, "search_style")
layout.prop(props, "own_only")
layout.prop(props, "free_only")
- #layout.prop(props, "search_procedural", expand = True)
+ # layout.prop(props, "search_procedural", expand = True)
# if props.search_style == 'OTHER':
# layout.prop(props, "search_style_other")
# layout.prop(props, "search_engine")
@@ -309,7 +311,7 @@ def draw_panel_model_search(self, context):
# layout.prop(props, 'append_link', expand=True, icon_only=False)
# layout.prop(props, 'import_as', expand=True, icon_only=False)
- # layout.prop(props, "search_advanced")
+ layout.prop(props, "search_advanced")
if props.search_advanced:
layout.separator()
@@ -320,34 +322,31 @@ def draw_panel_model_search(self, context):
# layout.prop(props, "search_engine_keyword")
# AGE
- layout.prop(props, "search_condition") # , text ='condition of object new/old e.t.c.')
+ layout.prop(props, "search_condition", text = 'Condition') # , text ='condition of object new/old e.t.c.')
# DESIGN YEAR
layout.prop(props, "search_design_year", text='designed in ( min - max )')
- row = layout.row(align=True)
- if not props.search_design_year_min:
- row.active = False
- row.prop(props, "search_design_year_min", text='min')
- row.prop(props, "search_design_year_max", text='max')
+ if props.search_design_year:
+ row = layout.row(align=True)
+ row.prop(props, "search_design_year_min", text='min')
+ row.prop(props, "search_design_year_max", text='max')
# POLYCOUNT
- layout.prop(props, "search_polycount", text='polycount in ( min - max )')
- row = layout.row(align=True)
- if not props.search_polycount:
- row.active = False
- row.prop(props, "search_polycount_min", text='min')
- row.prop(props, "search_polycount_max", text='max')
+ layout.prop(props, "search_polycount", text='Poly count in ( min - max )')
+ if props.search_polycount:
+ row = layout.row(align=True)
+ row.prop(props, "search_polycount_min", text='min')
+ row.prop(props, "search_polycount_max", text='max')
# TEXTURE RESOLUTION
layout.prop(props, "search_texture_resolution", text='texture resolution ( min - max )')
- row = layout.row(align=True)
- if not props.search_texture_resolution:
- row.active = False
- row.prop(props, "search_texture_resolution_min", text='min')
- row.prop(props, "search_texture_resolution_max", text='max')
+ if props.search_texture_resolution:
+ row = layout.row(align=True)
+ row.prop(props, "search_texture_resolution_min", text='min')
+ row.prop(props, "search_texture_resolution_max", text='max')
# ADULT
- layout.prop(props, "search_adult") # , text ='condition of object new/old e.t.c.')
+ #layout.prop(props, "search_adult") # , text ='condition of object new/old e.t.c.')
draw_panel_categories(self, context)
@@ -403,6 +402,8 @@ class VIEW3D_PT_blenderkit_model_properties(Panel):
if o.instance_type == 'COLLECTION' and o.instance_collection is not None:
layout.operator('object.blenderkit_bring_to_scene', text='Bring to scene')
+ draw_panel_model_rating(self, context)
+
# if 'rig' in ad['tags']:
# # layout.label(text = 'can make proxy')
# layout.operator('object.blenderkit_make_proxy', text = 'Make Armature proxy')
@@ -442,19 +443,31 @@ class VIEW3D_PT_blenderkit_profile(Panel):
draw_login_progress(layout)
return
-
if user_preferences.api_key != '':
me = bpy.context.window_manager.get('bkit profile')
if me is not None:
me = me['user']
- layout.label(text='User: %s %s' % (me['firstName'], me['lastName']))
- layout.label(text='Email: %s' % (me['email']))
- if me.get('sumAssetFilesSize') is not None: # TODO remove this when production server has these too.
- layout.label(text='Public assets: %i MiB' % (me['sumAssetFilesSize']))
- if me.get('sumPrivateAssetFilesSize') is not None:
- layout.label(text='Private assets: %i MiB' % (me['sumPrivateAssetFilesSize']))
+ #user name
+ layout.label(text='Me: %s %s' % (me['firstName'], me['lastName']))
+ # layout.label(text='Email: %s' % (me['email']))
+
+ # plan information
+
+ # pcoll = icons.icon_collections["main"]
+ # my_icon = pcoll['free']
+ # row = layout.row()
+ # row.label(text='My plan:')
+ # row.label(text='Free plan', icon_value=my_icon.icon_id)
+ # layout.operator("wm.url_open", text="Change plan",
+ # icon='URL').url = paths.get_bkit_url() + paths.BLENDERKIT_PLANS
+
+ #storage statistics
+ # if me.get('sumAssetFilesSize') is not None: # TODO remove this when production server has these too.
+ # layout.label(text='My public assets: %i MiB' % (me['sumAssetFilesSize']))
+ # if me.get('sumPrivateAssetFilesSize') is not None:
+ # layout.label(text='My private assets: %i MiB' % (me['sumPrivateAssetFilesSize']))
if me.get('remainingPrivateQuota') is not None:
- layout.label(text='Remaining private storage: %i MiB' % (me['remainingPrivateQuota']))
+ layout.label(text='My free storage: %i MiB' % (me['remainingPrivateQuota']))
layout.operator("wm.url_open", text="See my uploads",
icon='URL').url = paths.get_bkit_url() + paths.BLENDERKIT_USER_ASSETS
@@ -482,6 +495,7 @@ class VIEW3D_PT_blenderkit_login(Panel):
if user_preferences.enable_oauth:
draw_login_buttons(layout)
+
def draw_panel_model_rating(self, context):
o = bpy.context.active_object
op = draw_ratings(self.layout, context) # , props)
@@ -558,10 +572,18 @@ def draw_panel_material_search(self, context):
# if props.search_engine == 'OTHER':
# layout.prop(props, 'search_engine_other')
- layout.prop(props, 'automap')
+ # TEXTURE RESOLUTION
+ layout.prop(props, "search_texture_resolution", text='texture resolution ( min - max )')
+ if props.search_texture_resolution:
+ row = layout.row(align=True)
+ row.prop(props, "search_texture_resolution_min", text='min')
+ row.prop(props, "search_texture_resolution_max", text='max')
draw_panel_categories(self, context)
+ layout.prop(props, 'automap')
+
+
def draw_panel_material_ratings(self, context):
op = draw_ratings(self.layout, context) # , props)
@@ -644,19 +666,19 @@ class VIEW3D_PT_blenderkit_unified(Panel):
# layout.prop_tabs_enum(ui_props, "asset_type", icon_only = True)
row = layout.row()
- #row.scale_x = 1.6
- #row.scale_y = 1.6
+ # row.scale_x = 1.6
+ # row.scale_y = 1.6
#
row.prop(ui_props, 'down_up', expand=True, icon_only=False)
# row.label(text='')
- #row = row.split().row()
- #layout.alert = True
- #layout.alignment = 'CENTER'
- #row = layout.row(align = True)
- #split = row.split(factor=.5)
- #row.prop(ui_props, 'asset_type', expand=True, icon_only=True)
- #row = layout.column(align = False)
- layout.prop(ui_props, 'asset_type', expand=False, text = '')
+ # row = row.split().row()
+ # layout.alert = True
+ # layout.alignment = 'CENTER'
+ # row = layout.row(align = True)
+ # split = row.split(factor=.5)
+ # row.prop(ui_props, 'asset_type', expand=True, icon_only=True)
+ # row = layout.column(align = False)
+ layout.prop(ui_props, 'asset_type', expand=False, text='')
w = context.region.width
if user_preferences.login_attempt:
@@ -766,7 +788,6 @@ class VIEW3D_PT_blenderkit_unified(Panel):
layout.label(text='not yet implemented')
-
class OBJECT_MT_blenderkit_asset_menu(bpy.types.Menu):
bl_label = "Asset options:"
bl_idname = "OBJECT_MT_blenderkit_asset_menu"
@@ -907,7 +928,7 @@ class UrlPopupDialog(bpy.types.Operator):
op.url = self.url
def execute(self, context):
- #start_thumbnailer(self, context)
+ # start_thumbnailer(self, context)
return {'FINISHED'}
def invoke(self, context, event):
@@ -1014,8 +1035,9 @@ def header_search_draw(self, context):
if ui_props.asset_type == 'BRUSH':
props = s.blenderkit_brush
- if context.space_data.show_region_tool_header == True:
- layout.separator_spacer()
+ # the center snap menu is in edit and object mode if tool settings are off.
+ if context.space_data.show_region_tool_header == True or context.mode[:4] not in ('EDIT', 'OBJE'):
+ layout.separator_spacer()
layout.prop(ui_props, "asset_type", text='', icon='URL')
layout.prop(props, "search_keywords", text="", icon='VIEWZOOM')
draw_assetbar_show_hide(layout, props)
@@ -1046,4 +1068,4 @@ def register_ui_panels():
def unregister_ui_panels():
for c in classess:
bpy.utils.unregister_class(c)
- bpy.types.VIEW3D_MT_editor_menus.remove(header_search_draw) \ No newline at end of file
+ bpy.types.VIEW3D_MT_editor_menus.remove(header_search_draw)