Newer
Older
# ##### 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 #####
if "bpy" in locals():
import importlib
paths = importlib.reload(paths)
ratings = importlib.reload(ratings)
utils = importlib.reload(utils)
download = importlib.reload(download)
categories = importlib.reload(categories)
from blenderkit import paths, ratings, utils, download, categories, icons
from bpy.types import (
Panel
)
import bpy
def label_multiline(layout, text='', icon='NONE', width=-1):
''' draw a ui label, but try to split it in multiple lines.'''
if text.strip() == '':
return
lines = text.split('\n')
if width > 0:
threshold = int(width / 5.5)
else:
threshold = 35
for l in lines:
while len(l) > threshold:
i = l.rfind(' ', 0, threshold)
if i < 1:
i = threshold
l1 = l[:i]
layout.label(text=l1, icon=icon)
icon = 'NONE'
break;
layout.label(text=l, icon=icon)
icon = 'NONE'
# this was moved to separate interface:
def draw_ratings(layout, context):
# layout.operator("wm.url_open", text="Read rating instructions", icon='QUESTION').url = 'https://support.google.com/?hl=en'
asset = utils.get_active_asset()
# the following shouldn't happen at all in an optimal case,
# this function should run only when asset was already checked to be existing
if asset == None:
return;
bkit_ratings = asset.bkit_ratings
ratings.draw_rating(layout, bkit_ratings, 'rating_quality', 'Quality')
layout.separator()
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='')
# row = layout.row()
# op = row.operator("object.blenderkit_rating_upload", text="Send rating", icon='URL')
# return op
def draw_upload_common(layout, props, asset_type, context):
op = layout.operator("wm.url_open", text="Read upload instructions",
icon='QUESTION')
if asset_type == 'MODEL':
op.url = paths.BLENDERKIT_MODEL_UPLOAD_INSTRUCTIONS_URL
if asset_type == 'MATERIAL':
op.url = paths.BLENDERKIT_MATERIAL_UPLOAD_INSTRUCTIONS_URL
if asset_type == 'BRUSH':
op.url = paths.BLENDERKIT_BRUSH_UPLOAD_INSTRUCTIONS_URL
row = layout.row(align=True)
if props.upload_state != '':
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
op.process_type = 'UPLOAD'
layout = layout.column()
layout.enabled = False
# if props.upload_state.find('Error') > -1:
# layout.label(text = props.upload_state)
if props.asset_base_id == '':
optext = 'Upload %s' % asset_type.lower()
op = layout.operator("object.blenderkit_upload", text=optext, icon='EXPORT')
op.asset_type = asset_type
op = layout.operator("object.blenderkit_upload", text='Reupload asset', icon='EXPORT')
op = layout.operator("object.blenderkit_upload", text='Upload as new asset', icon='EXPORT')
op.asset_type = asset_type
# layout.label(text = 'asset id, overwrite only for reuploading')
layout.label(text='asset has a version online.')
# row = layout.row()
# row.enabled = False
# row.prop(props, 'asset_base_id', icon='FILE_TICK')
# row = layout.row()
# row.enabled = False
# row.prop(props, 'id', icon='FILE_TICK')
layout.prop(props, 'category')
if asset_type == 'MODEL' and props.subcategory != '': # by now block this for other asset types.
layout.prop(props, 'subcategory')
layout.prop(props, 'is_private', expand=True)
if props.is_private == 'PUBLIC':
layout.prop(props, 'license')
def poll_local_panels():
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
return user_preferences.panel_behaviour == 'BOTH' or user_preferences.panel_behaviour == 'LOCAL'
def prop_needed(layout, props, name, value, is_not_filled=''):
row = layout.row()
if value == is_not_filled:
# row.label(text='', icon = 'ERROR')
icon = 'ERROR'
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
else:
# row.label(text='', icon = 'FILE_TICK')
icon = None
row.prop(props, name)
def draw_panel_model_upload(self, context):
ob = bpy.context.active_object
while ob.parent is not None:
ob = ob.parent
props = ob.blenderkit
layout = self.layout
draw_upload_common(layout, props, 'MODEL', context)
prop_needed(layout, props, 'name', props.name)
col = layout.column()
if props.is_generating_thumbnail:
col.enabled = False
prop_needed(col, props, 'thumbnail', props.has_thumbnail, False)
if bpy.context.scene.render.engine in ('CYCLES', 'BLENDER_EEVEE'):
col.operator("object.blenderkit_generate_thumbnail", text='Generate thumbnail', icon='IMAGE')
# row = layout.row(align=True)
if props.is_generating_thumbnail:
row = layout.row(align=True)
row.label(text=props.thumbnail_generating_state)
op = row.operator('object.kill_bg_process', text="", icon='CANCEL')
op.process_source = 'MODEL'
op.process_type = 'THUMBNAILER'
elif props.thumbnail_generating_state != '':
label_multiline(layout, text=props.thumbnail_generating_state)
layout.prop(props, 'description')
layout.prop(props, 'tags')
# prop_needed(layout, props, 'style', props.style)
# prop_needed(layout, props, 'production_level', props.production_level)
layout.prop(props, 'style')
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
layout.prop(props, 'production_level')
layout.prop(props, 'condition')
layout.prop(props, 'is_free')
layout.prop(props, 'pbr')
layout.label(text='design props:')
layout.prop(props, 'manufacturer')
layout.prop(props, 'designer')
layout.prop(props, 'design_collection')
layout.prop(props, 'design_variant')
layout.prop(props, 'use_design_year')
if props.use_design_year:
layout.prop(props, 'design_year')
row = layout.row()
row.prop(props, 'work_hours')
layout.prop(props, 'adult')
def draw_panel_scene_upload(self, context):
s = bpy.context.scene
props = s.blenderkit
layout = self.layout
if bpy.app.debug_value != -1:
layout.label(text='Scene upload not Implemented')
return
draw_upload_common(layout, props, 'SCENE', context)
# layout = layout.column()
# row = layout.row()
# if props.dimensions[0] + props.dimensions[1] == 0 and props.face_count == 0:
# icon = 'ERROR'
# layout.operator("object.blenderkit_auto_tags", text='Auto fill tags', icon=icon)
# else:
# layout.operator("object.blenderkit_auto_tags", text='Auto fill tags')
prop_needed(layout, props, 'name', props.name)
col = layout.column()
# if props.is_generating_thumbnail:
# col.enabled = False
prop_needed(col, props, 'thumbnail', props.has_thumbnail, False)
# if bpy.context.scene.render.engine == 'CYCLES':
# col.operator("object.blenderkit_generate_thumbnail", text='Generate thumbnail', icon='IMAGE_COL')
# row = layout.row(align=True)
# if props.is_generating_thumbnail:
# row = layout.row(align=True)
# row.label(text = props.thumbnail_generating_state)
# op = row.operator('object.kill_bg_process', text="", icon='CANCEL')
# op.process_source = 'MODEL'
# op.process_type = 'THUMBNAILER'
# elif props.thumbnail_generating_state != '':
# label_multiline(layout, text = props.thumbnail_generating_state)
layout.prop(props, 'description')
layout.prop(props, 'tags')
layout.prop(props, 'style')
layout.prop(props, 'production_level')
layout.prop(props, 'use_design_year')
if props.use_design_year:
layout.prop(props, 'design_year')
layout.prop(props, 'condition')
row = layout.row()
row.prop(props, 'work_hours')
layout.prop(props, 'adult')
def draw_assetbar_show_hide(layout, props):
s = bpy.context.scene
ui_props = s.blenderkitUI
if ui_props.assetbar_on:
icon = 'HIDE_OFF'
op = layout.operator('view3d.blenderkit_asset_bar', text='', icon=icon)
op.keep_running = False
op.do_search = False
def draw_panel_model_search(self, context):
s = context.scene
props = s.blenderkit_models
layout = self.layout
row = layout.row()
row.prop(props, "search_keywords", text="", icon='VIEWZOOM')
draw_assetbar_show_hide(row, props)
if props.report == 'You need Full plan to get this item.':
icon = 'ERROR'
label_multiline(layout, text=props.report, icon=icon)
if props.report == 'You need Full plan to get this item.':
layout.operator("wm.url_open", text="Get Full plan", icon='URL').url = paths.BLENDERKIT_PLANS
layout.prop(props, "search_style")
Vilem Duha
committed
layout.prop(props, "free_only")
# if props.search_style == 'OTHER':
# layout.prop(props, "search_style_other")
# layout.prop(props, "search_engine")
# col = layout.column()
# layout.prop(props, 'append_link', expand=True, icon_only=False)
# layout.prop(props, 'import_as', expand=True, icon_only=False)
if props.search_advanced:
layout.separator()
# layout.label(text = "common searches keywords:")
# layout.prop(props, "search_global_keywords", text = "")
# layout.prop(props, "search_modifier_keywords")
# if props.search_engine == 'OTHER':
# layout.prop(props, "search_engine_keyword")
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 )')
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')
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 )')
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')
# FILE SIZE
layout.prop(props, "search_file_size", text='File size ( min - max )')
if props.search_file_size:
row = layout.row(align=True)
row.prop(props, "search_file_size_min", text='min')
row.prop(props, "search_file_size_max", text='max')
# layout.prop(props, "search_procedural", expand=True)
# layout.prop(props, "search_adult") # , text ='condition of object new/old e.t.c.')
draw_panel_categories(self, context)
layout.separator()
row = layout.row()
row.prop(props, 'append_method', expand=True, icon_only=False)
layout.prop(props, 'randomize_rotation')
if props.randomize_rotation:
layout.prop(props, 'randomize_rotation_amount')
def draw_panel_scene_search(self, context):
s = context.scene
props = s.blenderkit_scene
layout = self.layout
# layout.label(text = "common search properties:")
row = layout.row()
row.prop(props, "search_keywords", text="", icon='VIEWZOOM')
draw_assetbar_show_hide(row, props)
# layout.prop(props, "search_style")
# if props.search_style == 'OTHER':
# layout.prop(props, "search_style_other")
layout.separator()
draw_panel_categories(self, context)
class VIEW3D_PT_blenderkit_model_properties(Panel):
bl_category = "BlenderKit"
bl_idname = "VIEW3D_PT_blenderkit_model_properties"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_context = "objectmode"
@classmethod
def poll(cls, context):
p = bpy.context.view_layer.objects.active is not None
return p
def draw(self, context):
# draw asset properties here
layout = self.layout
o = utils.get_active_model()
# o = bpy.context.active_object
if o.get('asset_data') is None:
label_multiline(layout, text='To upload this asset to BlenderKit, go to the Find and Upload Assets panel.')
Vilém Duha
committed
if o.get('asset_data') is not None:
ad = o['asset_data']
layout.label(text=str(ad['name']))
if o.instance_type == 'COLLECTION' and o.instance_collection is not None:
layout.operator('object.blenderkit_bring_to_scene', text='Bring to scene')
Vilém Duha
committed
# if 'rig' in ad['tags']:
# # layout.label(text = 'can make proxy')
# layout.operator('object.blenderkit_make_proxy', text = 'Make Armature proxy')
Vilém Duha
committed
# else:
# op = layout.operator("object.blenderkit_upload", text='Store as private', icon='EXPORT')
# op.asset_type = 'MODEL'
# op.fast = True
# layout.operator('object.blenderkit_color_corrector')
def draw_login_progress(layout):
layout.label(text='Login through browser')
layout.label(text='in progress.')
layout.operator("wm.blenderkit_login_cancel", text="Cancel", icon='CANCEL')
class VIEW3D_PT_blenderkit_profile(Panel):
bl_category = "BlenderKit"
bl_idname = "VIEW3D_PT_blenderkit_profile"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
return True
def draw(self, context):
# draw asset properties here
layout = self.layout
user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
if user_preferences.login_attempt:
draw_login_progress(layout)
me = bpy.context.window_manager.get('bkit profile')
if me is not None:
me = me['user']
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
# 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']))
Vilem Duha
committed
if me.get('remainingPrivateQuota') is not None:
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
Loading
Loading full blame...