# ##### 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 ##### bl_info = { "name": "BlenderKit Online Asset Library", "author": "Vilem Duha, Petr Dlouhy", "version": (2, 93, 0), "blender": (2, 93, 0), "location": "View3D > Properties > BlenderKit", "description": "Online BlenderKit library (materials, models, brushes and more). Connects to the internet.", "warning": "", "doc_url": "{BLENDER_MANUAL_URL}/addons/3d_view/blenderkit.html", "category": "3D View", } if "bpy" in locals(): from importlib import reload # alphabetically sorted all add-on modules since reload only happens from __init__. # modules with _bg are used for background computations in separate blender instance and that's why they don't need reload. append_link = reload(append_link) asset_bar_op = reload(asset_bar_op) asset_inspector = reload(asset_inspector) autothumb = reload(autothumb) bg_blender = reload(bg_blender) bkit_oauth = reload(bkit_oauth) categories = reload(categories) colors = reload(colors) download = reload(download) icons = reload(icons) image_utils = reload(image_utils) oauth = reload(oauth) overrides = reload(overrides) paths = reload(paths) ratings = reload(ratings) ratings_utils = reload(ratings_utils) resolutions = reload(resolutions) search = reload(search) tasks_queue = reload(tasks_queue) ui = reload(ui) ui_bgl = reload(ui_bgl) ui_panels = reload(ui_panels) upload = reload(upload) upload_bg = reload(upload_bg) utils = reload(utils) bl_ui_label = reload(bl_ui_label) bl_ui_button = reload(bl_ui_button) # bl_ui_checkbox = reload(bl_ui_checkbox) # bl_ui_slider = reload(bl_ui_slider) # bl_ui_up_down = reload(bl_ui_up_down) bl_ui_drag_panel = reload(bl_ui_drag_panel) bl_ui_draw_op = reload(bl_ui_draw_op) # bl_ui_textbox = reload(bl_ui_textbox) else: from blenderkit import append_link from blenderkit import asset_bar_op from blenderkit import asset_inspector from blenderkit import autothumb from blenderkit import bg_blender from blenderkit import bkit_oauth from blenderkit import categories from blenderkit import colors from blenderkit import download from blenderkit import icons from blenderkit import image_utils from blenderkit import oauth from blenderkit import overrides from blenderkit import paths from blenderkit import ratings from blenderkit import ratings_utils from blenderkit import resolutions from blenderkit import search from blenderkit import tasks_queue from blenderkit import ui from blenderkit import ui_bgl from blenderkit import ui_panels from blenderkit import upload from blenderkit import upload_bg from blenderkit import utils from blenderkit.bl_ui_widgets import bl_ui_label from blenderkit.bl_ui_widgets import bl_ui_button # from blenderkit.bl_ui_widgets import bl_ui_checkbox # from blenderkit.bl_ui_widgets import bl_ui_slider # from blenderkit.bl_ui_widgets import bl_ui_up_down from blenderkit.bl_ui_widgets import bl_ui_drag_panel from blenderkit.bl_ui_widgets import bl_ui_draw_op # from blenderkit.bl_ui_widgets import bl_ui_textbox import os import math import time import logging import bpy import pathlib log = logging.getLogger(__name__) from bpy.app.handlers import persistent import bpy.utils.previews import mathutils from mathutils import Vector from bpy.props import ( IntProperty, FloatProperty, FloatVectorProperty, StringProperty, EnumProperty, BoolProperty, PointerProperty, ) from bpy.types import ( Operator, Panel, AddonPreferences, PropertyGroup, ) # logging.basicConfig(filename = 'blenderkit.log', level = logging.INFO, # format = ' %(asctime)s:%(filename)s:%(funcName)s:%(lineno)d:%(message)s') @persistent def scene_load(context): print('loading in background') print(bpy.context.window_manager) if not bpy.app.background: search.load_previews() ui_props = bpy.context.scene.blenderkitUI ui_props.assetbar_on = False ui_props.turn_off = False preferences = bpy.context.preferences.addons['blenderkit'].preferences preferences.login_attempt = False @bpy.app.handlers.persistent 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.search_timer): bpy.app.timers.register(search.search_timer) if not bpy.app.timers.is_registered(download.download_timer): bpy.app.timers.register(download.download_timer) if not (bpy.app.timers.is_registered(tasks_queue.queue_worker)): bpy.app.timers.register(tasks_queue.queue_worker) if not bpy.app.timers.is_registered(bg_blender.bg_update): bpy.app.timers.register(bg_blender.bg_update) return 5.0 conditions = ( ('UNSPECIFIED', 'Unspecified', ""), ('NEW', 'New', 'Shiny new item'), ('USED', 'Used', 'Casually used item'), ('OLD', 'Old', 'Old item'), ('DESOLATE', 'Desolate', 'Desolate item - dusty & rusty'), ) model_styles = ( ('REALISTIC', 'Realistic', "Photo realistic model"), ('PAINTERLY', 'Painterly', 'Hand painted with visible strokes'), ('LOWPOLY', 'Lowpoly', "Lowpoly art -don't mix up with polycount!"), ('ANIME', 'Anime', 'Anime style'), ('2D_VECTOR', '2D Vector', '2D vector'), ('3D_GRAPHICS', '3D Graphics', '3D graphics'), ('OTHER', 'Other', 'Other styles'), ) search_model_styles = ( ('REALISTIC', 'Realistic', "Photo realistic model"), ('PAINTERLY', 'Painterly', 'Hand painted with visible strokes'), ('LOWPOLY', 'Lowpoly', "Lowpoly art -don't mix up with polycount!"), ('ANIME', 'Anime', 'Anime style'), ('2D_VECTOR', '2D Vector', '2D vector'), ('3D_GRAPHICS', '3D Graphics', '3D graphics'), ('OTHER', 'Other', 'Other Style'), ('ANY', 'Any', 'Any Style'), ) material_styles = ( ('REALISTIC', 'Realistic', "Photo realistic model"), ('NPR', 'Non photorealistic', 'Hand painted with visible strokes'), ('OTHER', 'Other', 'Other style'), ) search_material_styles = ( ('REALISTIC', 'Realistic', "Photo realistic model"), ('NPR', 'Non photorealistic', 'Hand painted with visible strokes'), ('ANY', 'Any', 'Any'), ) engines = ( ('CYCLES', 'Cycles', 'Blender Cycles'), ('EEVEE', 'Eevee', 'Blender eevee renderer'), ('OCTANE', 'Octane', 'Octane render enginge'), ('ARNOLD', 'Arnold', 'Arnold render engine'), ('V-RAY', 'V-Ray', 'V-Ray renderer'), ('UNREAL', 'Unreal', 'Unreal engine'), ('UNITY', 'Unity', 'Unity engine'), ('GODOT', 'Godot', 'Godot engine'), ('3D-PRINT', '3D printer', 'object can be 3D printed'), ('OTHER', 'Other', 'any other engine'), ('NONE', 'None', 'no more engine block'), ) pbr_types = ( ('METALLIC', 'Metallic-Roughness', 'Metallic/Roughness PBR material type'), ('SPECULAR', 'Specular Glossy', ''), ) mesh_poly_types = ( ('QUAD', 'quad', ''), ('QUAD_DOMINANT', 'quad_dominant', ''), ('TRI_DOMINANT', 'tri_dominant', ''), ('TRI', 'tri', ''), ('NGON', 'ngon_dominant', ''), ('OTHER', 'other', ''), ) def udate_down_up(self, context): """Perform a search if results are empty.""" s = context.scene wm = bpy.context.window_manager props = s.blenderkitUI if wm.get('search results') == None and props.down_up == 'SEARCH': search.search() def switch_search_results(self, context): s = bpy.context.scene wm = bpy.context.window_manager props = s.blenderkitUI if props.asset_type == 'MODEL': wm['search results'] = wm.get('bkit model search') wm['search results orig'] = wm.get('bkit model search orig') elif props.asset_type == 'SCENE': wm['search results'] = wm.get('bkit scene search') wm['search results orig'] = wm.get('bkit scene search orig') elif props.asset_type == 'HDR': wm['search results'] = wm.get('bkit hdr search') wm['search results orig'] = wm.get('bkit hdr search orig') elif props.asset_type == 'MATERIAL': wm['search results'] = wm.get('bkit material search') wm['search results orig'] = wm.get('bkit material search orig') elif props.asset_type == 'TEXTURE': wm['search results'] = wm.get('bkit texture search') wm['search results orig'] = wm.get('bkit texture search orig') elif props.asset_type == 'BRUSH': wm['search results'] = wm.get('bkit brush search') wm['search results orig'] = wm.get('bkit brush search orig') if not (context.sculpt_object or context.image_paint_object): ui.add_report( 'Switch to paint or sculpt mode to search in BlenderKit brushes.') search.load_previews() if wm['search results'] == None and props.down_up == 'SEARCH': search.search() def asset_type_callback(self, context): ''' Returns items for Enum property, depending on the down_up property - BlenderKit is either in search or in upload mode. ''' user_preferences = bpy.context.preferences.addons['blenderkit'].preferences if self.down_up == 'SEARCH': items = ( ('MODEL', 'Models', 'Find models', 'OBJECT_DATAMODE', 0), ('MATERIAL', 'Materials', 'Find materials', 'MATERIAL', 2), # ('TEXTURE', 'Texture', 'Browse textures', 'TEXTURE', 3), ('SCENE', 'Scenes', 'Find scenes', 'SCENE_DATA', 3), ('HDR', 'HDRs', 'Find HDRs', 'WORLD', 4), ('BRUSH', 'Brushes', 'Find brushes', 'BRUSH_DATA', 5) ) else: items = ( ('MODEL', 'Model', 'Upload a model', 'OBJECT_DATAMODE', 0), # ('SCENE', 'SCENE', 'Browse scenes', 'SCENE_DATA', 1), ('MATERIAL', 'Material', 'Upload a material', 'MATERIAL', 2), # ('TEXTURE', 'Texture', 'Browse textures', 'TEXTURE', 3), ('SCENE', 'Scene', 'Upload a scene', 'SCENE_DATA', 3), ('HDR', 'HDR', 'Upload a HDR', 'WORLD', 4), ('BRUSH', 'Brush', 'Upload a brush', 'BRUSH_DATA', 5) ) return items class BlenderKitUIProps(PropertyGroup): down_up: EnumProperty( name="Download vs Upload", items=( ('SEARCH', 'Search', 'Activate searching', 'VIEWZOOM', 0), ('UPLOAD', 'Upload', 'Activate uploading', 'COPYDOWN', 1), # ('RATING', 'Rating', 'Activate rating', 'SOLO_ON', 2) ), description="BlenderKit", default="SEARCH", update=udate_down_up ) asset_type: EnumProperty( name=" ", items=asset_type_callback, description="", default=None, update=switch_search_results ) asset_type_fold: BoolProperty(name="Expand asset types", default=False) # these aren't actually used ( by now, seems to better use globals in UI module: draw_tooltip: BoolProperty(name="Draw Tooltip", default=False) addon_update: BoolProperty(name="Should Update Addon", default=False) tooltip: StringProperty( name="Tooltip", description="asset preview info", default="") ui_scale = 1 thumb_size_def = 96 margin_def = 0 thumb_size: IntProperty(name="Thumbnail Size", default=thumb_size_def, min=-1, max=256) margin: IntProperty(name="Margin", default=margin_def, min=-1, max=256) highlight_margin: IntProperty(name="Highlight Margin", default=int(margin_def / 2), min=-10, max=256) bar_height: IntProperty(name="Bar Height", default=thumb_size_def + 2 * margin_def, min=-1, max=2048) bar_x_offset: IntProperty(name="Bar X Offset", default=20, min=0, max=5000) bar_y_offset: IntProperty(name="Bar Y Offset", default=80, min=0, max=5000) bar_x: IntProperty(name="Bar X", default=100, min=0, max=5000) bar_y: IntProperty(name="Bar Y", default=100, min=50, max=5000) bar_end: IntProperty(name="Bar End", default=100, min=0, max=5000) bar_width: IntProperty(name="Bar Width", default=100, min=0, max=5000) wcount: IntProperty(name="Width Count", default=10, min=0, max=5000) hcount: IntProperty(name="Rows", default=5, min=0, max=5000) reports_y: IntProperty(name="Reports Y", default=5, min=0, max=5000) reports_x: IntProperty(name="Reports X", default=5, min=0, max=5000) assetbar_on: BoolProperty(name="Assetbar On", default=False) turn_off: BoolProperty(name="Turn Off", default=False) mouse_x: IntProperty(name="Mouse X", default=0) mouse_y: IntProperty(name="Mouse Y", default=0) active_index: IntProperty(name="Active Index", default=-3) scrolloffset: IntProperty(name="Scroll Offset", default=0) drawoffset: IntProperty(name="Draw Offset", default=0) dragging: BoolProperty(name="Dragging", default=False) drag_init: BoolProperty(name="Drag Initialisation", default=False) drag_length: IntProperty(name="Drag length", default=0) draw_drag_image: BoolProperty(name="Draw Drag Image", default=False) draw_snapped_bounds: BoolProperty(name="Draw Snapped Bounds", default=False) snapped_location: FloatVectorProperty(name="Snapped Location", default=(0, 0, 0)) snapped_bbox_min: FloatVectorProperty(name="Snapped Bbox Min", default=(0, 0, 0)) snapped_bbox_max: FloatVectorProperty(name="Snapped Bbox Max", default=(0, 0, 0)) snapped_normal: FloatVectorProperty(name="Snapped Normal", default=(0, 0, 0)) snapped_rotation: FloatVectorProperty(name="Snapped Rotation", default=(0, 0, 0), subtype='QUATERNION') has_hit: BoolProperty(name="has_hit", default=False) thumbnail_image = StringProperty( name="Thumbnail Image", description="", default=paths.get_addon_thumbnail_path('thumbnail_notready.jpg')) #### rating UI props rating_ui_scale = ui_scale rating_button_on: BoolProperty(name="Rating Button On", default=True) rating_menu_on: BoolProperty(name="Rating Menu On", default=False) rating_on: BoolProperty(name="Rating on", default=True) rating_button_width: IntProperty(name="Rating Button Width", default=50 * ui_scale) rating_button_height: IntProperty(name="Rating Button Height", default=50 * ui_scale) rating_x: IntProperty(name="Rating UI X", default=10) rating_y: IntProperty(name="Rating UI Y", default=10) rating_ui_width: IntProperty(name="Rating UI Width", default=rating_ui_scale * 600) rating_ui_height: IntProperty(name="Rating UI Heightt", default=rating_ui_scale * 256) quality_stars_x: IntProperty(name="Rating UI Stars X", default=rating_ui_scale * 90) quality_stars_y: IntProperty(name="Rating UI Stars Y", default=rating_ui_scale * 190) star_size: IntProperty(name="Star Size", default=rating_ui_scale * 50) workhours_bar_slider_size: IntProperty(name="Workhours Bar Slider Size", default=rating_ui_scale * 30) workhours_bar_x: IntProperty(name="Workhours Bar X", default=rating_ui_scale * (100 - 15)) workhours_bar_y: IntProperty(name="Workhours Bar Y", default=rating_ui_scale * (45 - 15)) workhours_bar_x_max: IntProperty(name="Workhours Bar X Max", default=rating_ui_scale * (480 - 15)) dragging_rating: BoolProperty(name="Dragging Rating", default=False) dragging_rating_quality: BoolProperty(name="Dragging Rating Quality", default=False) dragging_rating_work_hours: BoolProperty(name="Dragging Rating Work Hours", default=False) last_rating_time: FloatProperty(name="Last Rating Time", default=0.0) hdr_upload_image: PointerProperty(name='Upload HDR', type=bpy.types.Image, description='Pick an image to upload') # StringProperty( # name="Upload HDR", # description="Active HDR image to upload", # default="") def search_procedural_update(self, context): if self.search_procedural in ('PROCEDURAL', 'BOTH'): self.search_texture_resolution = False search.search_update(self, context) class BlenderKitCommonSearchProps(object): # STATES is_searching: BoolProperty(name="Searching", description="search is currently running (internal)", default=False) is_downloading: BoolProperty(name="Downloading", description="download is currently running (internal)", default=False) search_done: BoolProperty(name="Search Completed", description="at least one search did run (internal)", default=False) own_only: BoolProperty(name="My Assets Only", description="Search only for your assets", default=False, update=search.search_update) search_advanced: BoolProperty(name="Advanced Search Options", description="use advanced search properties", default=False, update=search.search_update) 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="Limit 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, ) # file_size search_file_size: BoolProperty(name="File Size", description="Limit file sizes", default=False, update=search.search_update, ) search_file_size_min: IntProperty(name="Min File Size", description="Minimum file size", default=0, min=0, max=2000, update=search.search_update, ) search_file_size_max: IntProperty(name="Max File Size", description="Maximum file size", default=500, min=0, max=2000, update=search.search_update, ) search_procedural: EnumProperty( items=( ('BOTH', 'Both', ''), ('PROCEDURAL', 'Procedural', ''), ('TEXTURE_BASED', 'Texture based', ''), ), default='BOTH', description='Search only procedural/texture based assets', update=search_procedural_update ) search_verification_status: EnumProperty( name="Verification status", description="Search by verification status", items= ( ('ALL', 'All', 'All'), ('UPLOADING', 'Uploading', 'Uploading'), ('UPLOADED', 'Uploaded', 'Uploaded'), ('READY', 'Ready for V.', 'Ready for validation (deprecated since 2.8)'), ('VALIDATED', 'Validated', 'Validated'), ('ON_HOLD', 'On Hold', 'On Hold'), ('REJECTED', 'Rejected', 'Rejected'), ('DELETED', 'Deleted', 'Deleted'), ), default='ALL', update=search.search_update, ) # resolution download/import settings resolution: EnumProperty( name="Max resolution", description="Cap texture sizes in the file to this resolution", items= ( # ('256', '256x256', ''), ('512', '512x512', ''), ('1024', '1024x1024', ''), ('2048', '2048x2048', ''), ('4096', '4096x4096', ''), ('8192', '8192x8192', ''), ('ORIGINAL', 'ORIGINAL FILE', ''), ), default='1024', ) free_only: BoolProperty(name="Free first", description="Show free models first", default=False, update=search.search_update) unpack_files: BoolProperty(name="Unpack Files", description="Unpack files after download", default=True ) unrated_only: BoolProperty(name="Unrated only", description="Show only unrated models", default=False, 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 and that's the reason.''' utils.name_update(self) def update_free(self, context): if self.is_free == 'FULL': self.is_free = 'FREE' ui_panels.ui_message(title="All BlenderKit materials are free", message="Any material uploaded to BlenderKit is free." \ " However, it can still earn money for the author," \ " based on our fair share system. " \ "Part of subscription is sent to artists based on usage by paying users.\n") # common_upload_props = [ # { # 'identifier':'id', # 'name':"Asset Version Id", # 'type':'StringProperty', # 'description':'Unique name of the asset version(hidden)', # 'default':'' # } # { # 'identifier':'id', # 'name':"Asset Version Id", # 'type':'StringProperty', # 'description':'Unique name of the asset version(hidden)', # 'default':'' # } # ] class BlenderKitCommonUploadProps(object): # for p in common_upload_props: # exec(f"{p['identifier']}: {p['type']}(name='{p['name']}',description='{p['description']}',default='{p['default']}')") id: StringProperty( name="Asset Version Id", description="Unique name of the asset version(hidden)", default="") asset_base_id: StringProperty( name="Asset Base Id", description="Unique name of the asset (hidden)", default="") name: StringProperty( name="Name", description="Main name of the asset", default="", update=name_update ) # this is to store name for purpose of checking if name has changed. name_old: StringProperty( name="Old Name", description="Old name of the asset", default="", ) description: StringProperty( name="Description", description="Description of the asset", default="") tags: StringProperty( name="Tags", description="List of tags, separated by commas (optional)", default="", update=utils.update_tags ) name_changed: BoolProperty(name="Name Changed", description="Name has changed, the asset has to be re-uploaded with all data", default=False) pbr: BoolProperty(name="Pure PBR Compatible", description="Is compatible with PBR standard. This means only image textures are used with no" " procedurals and no color correction, only principled shader is used", default=False) pbr_type: EnumProperty( name="PBR Type", items=pbr_types, description="PBR type", default="METALLIC", ) license: EnumProperty( items=upload.licenses, default='royalty_free', description='License. Please read our help for choosing the right licenses', ) is_private: EnumProperty( name="Thumbnail Style", items=( ('PRIVATE', 'Private', ""), ('PUBLIC', 'Public', "") ), description="Public assets go into the validation process. \n" "Validated assets are visible to all users.\n" "Private assets are limited by your plan quota\n" "State", default="PUBLIC", ) is_procedural: BoolProperty(name="Procedural", 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) # is_private: BoolProperty(name="Asset is Private", # description="If not marked private, your asset will go into the validation process automatically\n" # "Private assets are limited by quota", # default=False) is_free: EnumProperty( name="Thumbnail Style", items=( ('FULL', 'Full', "Your asset will be only available for subscribers"), ('FREE', 'Free', "You consent you want to release this asset as free for everyone.") ), description="Assets can be in Free or in Full plan. Also free assets generate credits.", default="FULL", ) uploading: BoolProperty(name="Uploading", description="True when background process is running", default=False, update=autothumb.update_upload_material_preview) upload_state: StringProperty( name="State Of Upload", description="bg process reports for upload", default='') has_thumbnail: BoolProperty(name="Has Thumbnail", description="True when thumbnail was checked and loaded", default=False) thumbnail_generating_state: StringProperty( name="Thumbnail Generating State", description="bg process reports for thumbnail generation", default='Please add thumbnail(jpg or png, at least 512x512)') report: StringProperty( name="Missing Upload Properties", description="used to write down what's missing", default='') category: EnumProperty( name="Category", description="main category to put into", items=categories.get_category_enums, update=categories.update_category_enums ) subcategory: EnumProperty( name="Subcategory", description="Subcategory to put into", items=categories.get_subcategory_enums, update=categories.update_subcategory_enums ) subcategory1: EnumProperty( name="Subcategory lvl2", description="Subcategory to put into", items=categories.get_subcategory1_enums ) class BlenderKitRatingProps(PropertyGroup): rating_quality: IntProperty(name="Quality", description="quality of the material", default=0, min=-1, max=10, update=ratings_utils.update_ratings_quality) # the following enum is only to ease interaction - enums support 'drag over' and enable to draw the stars easily. rating_quality_ui: EnumProperty(name='rating_quality_ui', items=ratings_utils.stars_enum_callback, description='Rating stars 0 - 10', default=None, update=ratings_utils.update_quality_ui, ) rating_work_hours: FloatProperty(name="Work Hours", description="How many hours did this work take?", default=0.00, min=0.0, max=150, update=ratings_utils.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) # rating_virtual_price: FloatProperty(name="Virtual Price", # description="How much would you pay for this object if buing it?", # default=0, min=0, max=10000) rating_problems: StringProperty( name="Problems", description="Problems found/ why did you take points down - this will be available for the author" " As short as possible", default="", ) rating_compliments: StringProperty( name="Compliments", description="Comliments - let the author know you like his work! " " As short as possible", default="", ) class BlenderKitMaterialSearchProps(PropertyGroup, BlenderKitCommonSearchProps): search_keywords: StringProperty( name="Search", description="Search for these keywords", default="", update=search.search_update ) search_style: EnumProperty( name="Style", 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, ) append_method: EnumProperty( name="Import Method", items=( ('LINK', 'Link', "Link Material - will be in external file and can't be directly edited"), ('APPEND', 'Append', 'Append if you need to edit the material'), ), description="Appended materials are editable in your scene. Linked assets are saved in original files, " "aren't editable directly, but also don't increase your file size", default="APPEND" ) automap: BoolProperty(name="Auto-Map", description="reset object texture space and also add automatically a cube mapped UV " "to the object. \n this allows most materials to apply instantly to any mesh", default=True) class BlenderKitMaterialUploadProps(PropertyGroup, BlenderKitCommonUploadProps): style: EnumProperty( name="Style", items=material_styles, description="Style of material", default="REALISTIC", ) style_other: StringProperty( name="Style Other", description="Style not in the list", default="", ) engine: EnumProperty( name='Engine', items=engines, default='CYCLES', description='Output engine', ) engine_other: StringProperty( name="Engine Other", description="engine not specified by addon", default="", ) shaders: StringProperty( name="Shaders Used", description="shaders used in asset, autofilled", default="", ) is_free: EnumProperty( name="Thumbnail Style", items=( ('FULL', 'Full', "Your asset will be only available for subscribers."), ('FREE', 'Free', "You consent you want to release this asset as free for everyone.") ), description="Assets can be in Free or in Full plan. Also free assets generate credits. \n" "All BlenderKit materials are free.", default="FREE", update=update_free ) uv: BoolProperty(name="Needs UV", description="needs an UV set", default=False) # printable_3d : BoolProperty( name = "3d printable", description = "can be 3d printed", default = False) animated: BoolProperty(name="Animated", description="is animated", default=False) texture_resolution_min: IntProperty(name="Texture Resolution Min", description="texture resolution minimum", default=0) texture_resolution_max: IntProperty(name="Texture Resolution Max", description="texture resolution maximum", default=0) texture_size_meters: FloatProperty(name="Texture Size in Meters", description="Size of texture in real world units.", default=1.0, min=0) thumbnail_scale: FloatProperty(name="Thumbnail Object Size", description="Size of material preview object in meters." "Change for materials that look better at sizes different than 1m", default=1, min=0.00001, max=10) thumbnail_background: BoolProperty(name="Thumbnail Background (for Glass only)", description="For refractive materials, you might need a background.\n" "Don't use for other types of materials.\n" "Transparent background is preferred", default=False) thumbnail_background_lightness: FloatProperty(name="Thumbnail Background Lightness", description="Set to make your material stand out with enough contrast", default=.9, min=0.00001, max=1) thumbnail_samples: IntProperty(name="Cycles Samples", description="Cycles samples", default=100, min=5, max=5000) thumbnail_denoising: BoolProperty(name="Use Denoising", description="Use denoising", default=True) adaptive_subdivision: BoolProperty(name="Adaptive Subdivide", description="Use adaptive displacement subdivision", default=False) thumbnail_resolution: EnumProperty( name="Resolution", items=autothumb.thumbnail_resolutions, description="Thumbnail resolution", default="1024", ) thumbnail_generator_type: EnumProperty( name="Thumbnail Style", items=( ('BALL', 'Ball', ""), ('BALL_COMPLEX', 'Ball complex', 'Complex ball to highlight edgewear or material thickness'), ('FLUID', 'Fluid', 'Fluid'), ('CLOTH', 'Cloth', 'Cloth'), ('HAIR', 'Hair', 'Hair ') ), description="Style of asset", default="BALL", ) thumbnail: StringProperty( name="Thumbnail", description="Thumbnail path - 512x512 .jpg image, rendered with cycles. \n" "Only standard BlenderKit previews will be accepted.\n" "Only exception are special effects like fire or similar.", subtype='FILE_PATH', default="", update=autothumb.update_upload_material_preview) is_generating_thumbnail: BoolProperty(name="Generating Thumbnail", description="True when background process is running", default=False, update=autothumb.update_upload_material_preview) class BlenderKitTextureUploadProps(PropertyGroup, BlenderKitCommonUploadProps): style: EnumProperty( name="Style", items=material_styles, description="Style of texture", default="REALISTIC", ) style_other: StringProperty( name="Style Other", description="Style not in the list", default="", ) pbr: BoolProperty(name="PBR Compatible", description="Is compatible with PBR standard", default=False) # printable_3d : BoolProperty( name = "3d printable", description = "can be 3d printed", default = False) animated: BoolProperty(name="Animated", description="is animated", default=False) resolution: IntProperty(name="Texture Resolution", description="texture resolution", default=0) class BlenderKitBrushSearchProps(PropertyGroup, BlenderKitCommonSearchProps): search_keywords: StringProperty( name="Search", description="Search for these keywords", default="", update=search.search_update ) class BlenderKitHDRUploadProps(PropertyGroup, BlenderKitCommonUploadProps): texture_resolution_max: IntProperty(name="Texture Resolution Max", description="texture resolution maximum", default=0) class BlenderKitBrushUploadProps(PropertyGroup, BlenderKitCommonUploadProps): mode: EnumProperty( name="Mode", items=( ('IMAGE', 'Texture paint', "Texture brush"), ('SCULPT', 'Sculpt', 'Sculpt brush'), ('VERTEX', 'Vertex paint', 'Vertex paint brush'), ('WEIGHT', 'Weight paint', 'Weight paint brush'), ), description="Mode where the brush works", default="SCULPT", ) # upload properties class BlenderKitModelUploadProps(PropertyGroup, BlenderKitCommonUploadProps): style: EnumProperty( name="Style", items=model_styles, description="Style of asset", default="REALISTIC", ) style_other: StringProperty( name="Style Other", description="Style not in the list", default="", ) engine: EnumProperty( name='Engine', items=engines, default='CYCLES', description='Output engine', ) production_level: EnumProperty( name='Production Level', items=( ('FINISHED', 'Finished', 'Render or animation ready asset'), ('TEMPLATE', 'Template', 'Asset intended to help in creation of something else'), ), default='FINISHED', description='Production state of the asset. \n' 'Templates should be tools to finish certain tasks, like a thumbnailer scene, \n ' 'finished mesh topology as start for modelling or others', ) engine_other: StringProperty( name="Engine", description="engine not specified by addon", default="", ) engine1: EnumProperty( name='2nd Engine', items=engines, default='NONE', description='Output engine', ) engine2: EnumProperty( name='3rd Engine', items=engines, default='NONE', description='Output engine', ) engine3: EnumProperty( name='4th Engine', items=engines, default='NONE', description='Output engine', ) manufacturer: StringProperty( name="Manufacturer", description="Manufacturer, company making a design piece or product. Not you", default="", ) designer: StringProperty( name="Designer", description="Author of the original design piece depicted. Usually not you", default="", ) design_collection: StringProperty( name="Design Collection", description="Fill if this piece is part of a real world design collection", default="", ) design_variant: StringProperty( name="Variant", description="Colour or material variant of the product", default="", ) thumbnail: StringProperty( name="Thumbnail", description="Thumbnail path - 512x512 .jpg\n" "Rendered with cycles", subtype='FILE_PATH', default="", update=autothumb.update_upload_model_preview) thumbnail_background_lightness: FloatProperty(name="Thumbnail Background Lightness", description="set to make your material stand out", default=1.0, min=0.01, max=10) thumbnail_angle: EnumProperty( name='Thumbnail Angle', items=autothumb.thumbnail_angles, default='DEFAULT', description='thumbnailer angle', ) thumbnail_snap_to: EnumProperty( name='Model Snaps To:', items=autothumb.thumbnail_snap, default='GROUND', description='typical placing of the interior. Leave on ground for most objects that respect gravity :)', ) thumbnail_resolution: EnumProperty( name="Resolution", items=autothumb.thumbnail_resolutions, description="Thumbnail resolution", default="1024", ) thumbnail_samples: IntProperty(name="Cycles Samples", description="cycles samples setting", default=100, min=5, max=5000) thumbnail_denoising: BoolProperty(name="Use Denoising", description="Use denoising", default=True) use_design_year: BoolProperty(name="Use Design Year", description="When this thing came into world for the first time\n" " e.g. for dinosaur, you set -240 million years ;) ", default=False) design_year: IntProperty(name="Design Year", description="when was this item designed", default=1960) # use_age : BoolProperty( name = "use item age", description = "use item age", default = False) condition: EnumProperty( items=conditions, default='UNSPECIFIED', description='age of the object', ) adult: BoolProperty(name="Adult Content", description="adult content", default=False) work_hours: FloatProperty(name="Work Hours", description="How long did it take you to finish the asset?", default=0.0, min=0.0, max=8760) modifiers: StringProperty( name="Modifiers Used", description="if you need specific modifiers, autofilled", default="", ) materials: StringProperty( name="Material Names", description="names of materials in the file, autofilled", default="", ) shaders: StringProperty( name="Shaders Used", description="shaders used in asset, autofilled", default="", ) dimensions: FloatVectorProperty( name="Dimensions", description="dimensions of the whole asset hierarchy", default=(0, 0, 0), ) bbox_min: FloatVectorProperty( name="Bbox Min", description="dimensions of the whole asset hierarchy", default=(-.25, -.25, 0), ) bbox_max: FloatVectorProperty( name="Bbox Max", description="dimensions of the whole asset hierarchy", default=(.25, .25, .5), ) texture_resolution_min: IntProperty(name="Texture Resolution Min", description="texture resolution min, autofilled", default=0) texture_resolution_max: IntProperty(name="Texture Resolution Max", description="texture resolution max, autofilled", default=0) pbr: BoolProperty(name="PBR Compatible", description="Is compatible with PBR standard", default=False) uv: BoolProperty(name="Has UV", description="has an UV set", default=False) # printable_3d : BoolProperty( name = "3d printable", description = "can be 3d printed", default = False) animated: BoolProperty(name="Animated", description="is animated", default=False) face_count: IntProperty(name="Face count", description="face count, autofilled", default=0) face_count_render: IntProperty(name="Render Face Count", description="render face count, autofilled", default=0) object_count: IntProperty(name="Number of Objects", description="how many objects are in the asset, autofilled", default=0) mesh_poly_type: EnumProperty( name='Dominant Poly Type', items=mesh_poly_types, default='OTHER', description='', ) manifold: BoolProperty(name="Manifold", description="asset is manifold, autofilled", default=False) rig: BoolProperty(name="Rig", description="asset is rigged, autofilled", default=False) simulation: BoolProperty(name="Simulation", description="asset uses simulation, autofilled", default=False) ''' filepath : StringProperty( name="Filepath", description="file path", default="", ) ''' # THUMBNAIL STATES is_generating_thumbnail: BoolProperty(name="Generating Thumbnail", description="True when background process is running", default=False, update=autothumb.update_upload_model_preview) has_autotags: BoolProperty(name="Has Autotagging Done", description="True when autotagging done", default=False) class BlenderKitSceneUploadProps(PropertyGroup, BlenderKitCommonUploadProps): style: EnumProperty( name="Style", items=model_styles, description="Style of asset", default="REALISTIC", ) style_other: StringProperty( name="Style Other", description="Style not in the list", default="", ) engine: EnumProperty( name='Engine', items=engines, default='CYCLES', description='Output engine', ) production_level: EnumProperty( name='Production Level', items=( ('FINISHED', 'Finished', 'Render or animation ready asset'), ('TEMPLATE', 'Template', 'Asset intended to help in creation of something else'), ), default='FINISHED', description='Production state of the asset, \n also template should be actually finished, \n' 'just the nature of it can be a template, like a thumbnailer scene, \n ' 'finished mesh topology as start for modelling or similar', ) engine_other: StringProperty( name="Engine", description="engine not specified by addon", default="", ) engine1: EnumProperty( name='2nd Engine', items=engines, default='NONE', description='Output engine', ) engine2: EnumProperty( name='3rd Engine', items=engines, default='NONE', description='Output engine', ) engine3: EnumProperty( name='4th Engine', items=engines, default='NONE', description='Output engine', ) thumbnail: StringProperty( name="Thumbnail", description="Thumbnail path - 512x512 .jpg\n" "Rendered with cycles", subtype='FILE_PATH', default="", update=autothumb.update_upload_scene_preview) use_design_year: BoolProperty(name="Use Design Year", description="When this thing came into world for the first time\n" " e.g. for dinosaur, you set -240 million years ;) ", default=False) design_year: IntProperty(name="Design Year", description="when was this item designed", default=1960) # use_age : BoolProperty( name = "use item age", description = "use item age", default = False) condition: EnumProperty( items=conditions, default='UNSPECIFIED', description='age of the object', ) adult: BoolProperty(name="Adult Content", description="adult content", default=False) work_hours: FloatProperty(name="Work Hours", description="How long did it take you to finish the asset?", default=0.0, min=0.0, max=8760) modifiers: StringProperty( name="Modifiers Used", description="if you need specific modifiers, autofilled", default="", ) materials: StringProperty( name="Material Names", description="names of materials in the file, autofilled", default="", ) shaders: StringProperty( name="Shaders Used", description="shaders used in asset, autofilled", default="", ) dimensions: FloatVectorProperty( name="Dimensions", description="dimensions of the whole asset hierarchy", default=(0, 0, 0), ) bbox_min: FloatVectorProperty( name="Dimensions", description="dimensions of the whole asset hierarchy", default=(-.25, -.25, 0), ) bbox_max: FloatVectorProperty( name="Dimensions", description="dimensions of the whole asset hierarchy", default=(.25, .25, .5), ) texture_resolution_min: IntProperty(name="Texture Resolution Min", description="texture resolution min, autofilled", default=0) texture_resolution_max: IntProperty(name="Texture Resolution Max", description="texture resolution max, autofilled", default=0) pbr: BoolProperty(name="PBR Compatible", description="Is compatible with PBR standard", default=False) uv: BoolProperty(name="Has UV", description="has an UV set", default=False) # printable_3d : BoolProperty( name = "3d printable", description = "can be 3d printed", default = False) animated: BoolProperty(name="Animated", description="is animated", default=False) face_count: IntProperty(name="Face Count", description="face count, autofilled", default=0) face_count_render: IntProperty(name="Render Face Count", description="render face count, autofilled", default=0) object_count: IntProperty(name="Number of Objects", description="how many objects are in the asset, autofilled", default=0) mesh_poly_type: EnumProperty( name='Dominant Poly Type', items=mesh_poly_types, default='OTHER', description='', ) rig: BoolProperty(name="Rig", description="asset is rigged, autofilled", default=False) simulation: BoolProperty(name="Simulation", description="asset uses simulation, autofilled", default=False) # THUMBNAIL STATES is_generating_thumbnail: BoolProperty(name="Generating Thumbnail", description="True when background process is running", default=False, update=autothumb.update_upload_model_preview) has_autotags: BoolProperty(name="Has Autotagging Done", description="True when autotagging done", default=False) class BlenderKitModelSearchProps(PropertyGroup, BlenderKitCommonSearchProps): search_keywords: StringProperty( name="Search", description="Search for these keywords", default="", update=search.search_update ) search_style: EnumProperty( name="Style", items=search_model_styles, description="Keywords defining style (realistic, painted, polygonal, other)", default="ANY", update=search.search_update ) search_style_other: StringProperty( name="Style", description="Search style - other", default="", update=search.search_update ) search_engine: EnumProperty( items=engines, default='CYCLES', description='Output engine', update=search.search_update ) search_engine_other: StringProperty( name="Engine", description="Engine not specified by addon", default="", update=search.search_update ) # CONDITION search_condition: EnumProperty( items=conditions, default='UNSPECIFIED', description='Condition of the object', update=search.search_update ) search_adult: BoolProperty( name="Adult Content", description="You're adult and agree with searching adult content", default=False, update=search.search_update ) # DESIGN YEAR search_design_year: BoolProperty(name="Sesigned in Year", description="When the object was approximately designed. \n" "Useful for search of historical or future objects", default=False, update=search.search_update, ) search_design_year_min: IntProperty(name="Minimum Design Year", description="Minimum design year", default=1950, min=-100000000, max=1000000000, update=search.search_update, ) search_design_year_max: IntProperty(name="Maximum Design Year", description="Maximum design year", default=2017, min=0, max=10000000, update=search.search_update, ) # POLYCOUNT search_polycount: BoolProperty(name="Use Polycount", description="Limit polycount", default=False, update=search.search_update, ) search_polycount_min: IntProperty(name="Min Polycount", description="Minimum poly count", default=0, min=0, max=100000000, update=search.search_update, ) search_polycount_max: IntProperty(name="Max Polycount", description="Maximum poly count", default=100000000, min=0, max=100000000, update=search.search_update, ) append_method: EnumProperty( name="Import Method", items=( ('LINK_COLLECTION', 'Link', 'Link Collection'), ('APPEND_OBJECTS', 'Append', 'Append as Objects'), ), description="Appended objects are editable in your scene. Linked assets are saved in original files, " "aren't editable but also don't increase your file size", default="APPEND_OBJECTS" ) append_link: EnumProperty( name="How to Attach", items=( ('LINK', 'Link', ''), ('APPEND', 'Append', ''), ), description="choose if the assets will be linked or appended", default="LINK" ) import_as: EnumProperty( name="Import as", items=( ('GROUP', 'group', ''), ('INDIVIDUAL', 'objects', ''), ), description="choose if the assets will be linked or appended", default="GROUP" ) randomize_rotation: BoolProperty(name='Randomize Rotation', description="randomize rotation at placement", default=False) randomize_rotation_amount: FloatProperty(name="Randomization Max Angle", description="maximum angle for random rotation", default=math.pi / 36, min=0, max=2 * math.pi, subtype='ANGLE') offset_rotation_amount: FloatProperty(name="Offset Rotation", description="offset rotation, hidden prop", default=0, min=0, max=360, subtype='ANGLE') offset_rotation_step: FloatProperty(name="Offset Rotation Step", description="offset rotation, hidden prop", default=math.pi / 2, min=0, 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 BlenderKitHDRSearchProps(PropertyGroup, BlenderKitCommonSearchProps): search_keywords: StringProperty( name="Search", description="Search for these keywords", default="", update=search.search_update ) class BlenderKitSceneSearchProps(PropertyGroup, BlenderKitCommonSearchProps): search_keywords: StringProperty( name="Search", description="Search for these keywords", default="", update=search.search_update ) search_style: EnumProperty( name="Style", items=search_model_styles, description="Restrict search for style", default="ANY", update=search.search_update ) search_style_other: StringProperty( name="Style", description="Search style - other", default="", update=search.search_update ) search_engine: EnumProperty( items=engines, default='CYCLES', description='Output engine', update=search.search_update ) search_engine_other: StringProperty( name="Engine", description="Engine not specified by addon", default="", update=search.search_update ) append_link: EnumProperty( name="Append or link", items=( ('LINK', 'Link', ''), ('APPEND', 'Append', ''), ), description="choose if the scene will be linked or appended", default="APPEND" ) switch_after_append: BoolProperty( name='Switch to scene after download', default=True ) def fix_subdir(self, context): '''Fixes project subdicrectory settings if people input invalid path.''' # pp = pathlib.PurePath(self.project_subdir) pp = self.project_subdir[:] pp = pp.replace('\\', '') pp = pp.replace('/', '') pp = pp.replace(':', '') pp = '//' + pp if self.project_subdir != pp: self.project_subdir = pp ui_panels.ui_message(title="Fixed to relative path", message="This path should be always realative.\n" \ " It's a directory BlenderKit creates where your .blend is \n " \ "and uses it for storing assets.") class BlenderKitAddonPreferences(AddonPreferences): # this must match the addon name, use '__package__' # when defining this in a submodule of a python package. bl_idname = __name__ default_global_dict = paths.default_global_dict() enable_oauth = True api_key: StringProperty( name="BlenderKit API Key", description="Your blenderkit API Key. Get it from your page on the website", default="", subtype="PASSWORD", update=utils.save_prefs ) api_key_refresh: StringProperty( name="BlenderKit refresh API Key", description="API key used to refresh the token regularly", default="", subtype="PASSWORD", ) api_key_timeout: IntProperty( name='api key timeout', description='time where the api key will need to be refreshed', default=0, ) api_key_life: IntProperty( name='api key life time', description='maximum lifetime of the api key, in seconds', default=0, ) refresh_in_progress: BoolProperty( name="Api key refresh in progress", description="Api key is currently being refreshed. Don't refresh it again", default=False ) login_attempt: BoolProperty( name="Login/Signup attempt", description="When this is on, BlenderKit is trying to connect and login", default=False ) show_on_start: BoolProperty( name="Show assetbar when starting blender", description="Show assetbar when starting blender", default=False ) tips_on_start: BoolProperty( name="Show tips when starting blender", description="Show tips when starting blender", default=False ) search_in_header: BoolProperty( name="Show BlenderKit search in 3D view header", description="Show BlenderKit search in 3D view header", default=True ) global_dir: StringProperty( name="Global Files Directory", description="Global storage for your assets, will use subdirectories for the contents", subtype='DIR_PATH', default=default_global_dict, update=utils.save_prefs ) project_subdir: StringProperty( name="Project Assets Subdirectory", description="where data will be stored for individual projects", # subtype='DIR_PATH', default="//assets", update=fix_subdir ) directory_behaviour: EnumProperty( name="Use Directories", items=( ('BOTH', 'Global and subdir', 'store files both in global lib and subdirectory of current project. ' 'Warning - each file can be many times on your harddrive, but helps you keep your projects in one piece'), ('GLOBAL', 'Global', "store downloaded files only in global directory. \n " "This can bring problems when moving your projects, \n" "since assets won't be in subdirectory of current project"), ('LOCAL', 'Local', 'store downloaded files only in local directory.\n' ' This can use more bandwidth when you reuse assets in different projects. ') ), description="Which directories will be used for storing downloaded data", default="BOTH", ) thumbnail_use_gpu: BoolProperty( name="Use GPU for Thumbnails Rendering (For assets upload)", description="By default this is off so you can continue your work without any lag", default=False ) panel_behaviour: EnumProperty( name="Panels Locations", items=( ('BOTH', 'Both Types', ''), ('UNIFIED', 'Unified 3D View Panel', ""), ('LOCAL', 'Relative to Data', '') ), description="Which directories will be used for storing downloaded data", default="UNIFIED", ) max_assetbar_rows: IntProperty(name="Max Assetbar Rows", description="max rows of assetbar in the 3D view", default=1, 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, min=0, max=20000) # 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", description="Use timers for BlenderKit. Usefull for debugging since timers seem to be unstable", default=True, update=utils.save_prefs ) # single_timer: BoolProperty( # name="Use timers", # description="Use timers for BlenderKit. Usefull for debugging since timers seem to be unstable", # default=True, # update=utils.save_prefs # ) experimental_features: BoolProperty( name="Enable experimental features", description="Enable all experimental features of BlenderKit. Use at your own risk.", default=False, update=utils.save_prefs ) categories_fix: BoolProperty( name="Enable category fixing mode", description="Enable category fixing mode.", default=False, update=utils.save_prefs ) # allow_proximity : BoolProperty( # name="allow proximity data reports", # description="This sends anonymized proximity data \n \ # and allows us to make relations between database objects \n \ # without user interaction", # default=False # ) def draw(self, context): layout = self.layout layout.prop(self, "show_on_start") if self.api_key.strip() == '': if self.enable_oauth: ui_panels.draw_login_buttons(layout) else: op = layout.operator("wm.url_open", text="Register online and get your API Key", icon='QUESTION') op.url = paths.BLENDERKIT_SIGNUP_URL else: if self.enable_oauth: layout.operator("wm.blenderkit_logout", text="Logout", icon='URL') # 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") layout.prop(self, "project_subdir") # layout.prop(self, "temp_dir") layout.prop(self, "directory_behaviour") # layout.prop(self, "allow_proximity") # layout.prop(self, "panel_behaviour") layout.prop(self, "thumb_size") layout.prop(self, "max_assetbar_rows") layout.prop(self, "tips_on_start") layout.prop(self, "search_in_header") layout.prop(self, "thumbnail_use_gpu") if bpy.context.preferences.view.show_developer_ui: layout.prop(self, "use_timers") layout.prop(self, "experimental_features") layout.prop(self, "categories_fix") # # @bpy.app.handlers.persistent # def blenderkit_timer(): # # # if not user_preferences.use_timers: # search.search_timer() # download.download_timer() # tasks_queue.queue_worker() # bg_blender.bg_update() # registration classes = ( BlenderKitAddonPreferences, BlenderKitUIProps, BlenderKitModelSearchProps, BlenderKitModelUploadProps, BlenderKitSceneSearchProps, BlenderKitSceneUploadProps, BlenderKitHDRSearchProps, BlenderKitHDRUploadProps, BlenderKitMaterialUploadProps, BlenderKitMaterialSearchProps, BlenderKitTextureUploadProps, BlenderKitBrushSearchProps, BlenderKitBrushUploadProps, BlenderKitRatingProps, ) def register(): for cls in classes: bpy.utils.register_class(cls) bpy.types.Scene.blenderkitUI = PointerProperty( type=BlenderKitUIProps) # MODELS bpy.types.Scene.blenderkit_models = PointerProperty( type=BlenderKitModelSearchProps) bpy.types.Object.blenderkit = PointerProperty( # for uploads, not now... type=BlenderKitModelUploadProps) bpy.types.Object.bkit_ratings = PointerProperty( # for uploads, not now... type=BlenderKitRatingProps) # SCENES bpy.types.Scene.blenderkit_scene = PointerProperty( type=BlenderKitSceneSearchProps) bpy.types.Scene.blenderkit = PointerProperty( # for uploads, not now... type=BlenderKitSceneUploadProps) bpy.types.Scene.bkit_ratings = PointerProperty( # for uploads, not now... type=BlenderKitRatingProps) # HDRs bpy.types.Scene.blenderkit_HDR = PointerProperty( type=BlenderKitHDRSearchProps) bpy.types.Image.blenderkit = PointerProperty( # for uploads, not now... type=BlenderKitHDRUploadProps) bpy.types.Image.bkit_ratings = PointerProperty( # for uploads, not now... type=BlenderKitRatingProps) # MATERIALS bpy.types.Scene.blenderkit_mat = PointerProperty( type=BlenderKitMaterialSearchProps) bpy.types.Material.blenderkit = PointerProperty( # for uploads, not now... type=BlenderKitMaterialUploadProps) bpy.types.Material.bkit_ratings = PointerProperty( # for uploads, not now... type=BlenderKitRatingProps) # BRUSHES bpy.types.Scene.blenderkit_brush = PointerProperty( type=BlenderKitBrushSearchProps) bpy.types.Brush.blenderkit = PointerProperty( # for uploads, not now... type=BlenderKitBrushUploadProps) bpy.types.Brush.bkit_ratings = PointerProperty( # for uploads, not now... type=BlenderKitRatingProps) search.register_search() asset_inspector.register_asset_inspector() download.register_download() upload.register_upload() ratings.register_ratings() autothumb.register_thumbnailer() ui.register_ui() icons.register_icons() ui_panels.register_ui_panels() bg_blender.register() utils.load_prefs() overrides.register_overrides() bkit_oauth.register() tasks_queue.register() asset_bar_op.register() user_preferences = bpy.context.preferences.addons['blenderkit'].preferences if user_preferences.use_timers: bpy.app.timers.register(check_timers_timer, persistent=True) bpy.app.handlers.load_post.append(scene_load) # detect if the user just enabled the addon in preferences, thus enable to run 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') #save preferences after manually enabling the addon tasks_queue.add_task((bpy.ops.wm.save_userpref, ()), fake_context=False,) def unregister(): if bpy.app.timers.is_registered(check_timers_timer): bpy.app.timers.unregister(check_timers_timer) ui_panels.unregister_ui_panels() ui.unregister_ui() icons.unregister_icons() search.unregister_search() asset_inspector.unregister_asset_inspector() download.unregister_download() upload.unregister_upload() ratings.unregister_ratings() autothumb.unregister_thumbnailer() bg_blender.unregister() overrides.unregister_overrides() bkit_oauth.unregister() tasks_queue.unregister() asset_bar_op.unregister() del bpy.types.Scene.blenderkit_models del bpy.types.Scene.blenderkit_scene del bpy.types.Scene.blenderkit_HDR del bpy.types.Scene.blenderkit_brush del bpy.types.Scene.blenderkit_mat del bpy.types.Scene.blenderkit del bpy.types.Object.blenderkit del bpy.types.Image.blenderkit del bpy.types.Material.blenderkit del bpy.types.Brush.blenderkit for cls in classes: bpy.utils.unregister_class(cls) bpy.app.handlers.load_post.remove(scene_load)