def get_autotags(): """ call all analysis functions """ ui = bpy.context.scene.blenderkitUI if ui.asset_type == 'MODEL': ob = utils.get_active_model() obs = utils.get_hierarchy(ob) props = ob.blenderkit if props.name == "": props.name = ob.name # reset some properties here, because they might not get re-filled at all when they aren't needed anymore. props.texture_resolution_max = 0 props.texture_resolution_min = 0 # disabled printing checking, some 3d print addon bug. # check_printable( props, obs) check_render_engine(props, obs) dim, bbox_min, bbox_max = utils.get_dimensions(obs) props.dimensions = dim props.bbox_min = bbox_min props.bbox_max = bbox_max check_rig(props, obs) check_anim(props, obs) check_meshprops(props, obs) check_modifiers(props, obs) countObs(props, obs) elif ui.asset_type == 'MATERIAL': # reset some properties here, because they might not get re-filled at all when they aren't needed anymore. mat = utils.get_active_asset() props = mat.blenderkit props.texture_resolution_max = 0 props.texture_resolution_min = 0 check_material(props, mat)
def get_autotags(): """ call all analysis functions """ ui = bpy.context.scene.blenderkitUI if ui.asset_type =='MODEL': ob = utils.get_active_model() obs = utils.get_hierarchy(ob) props = ob.blenderkit if props.name == "": props.name = ob.name # reset some properties here, because they might not get re-filled at all when they aren't needed anymore. props.texture_resolution_max = 0 props.texture_resolution_min = 0 # disabled printing checking, some 3d print addon bug. # check_printable( props, obs) check_render_engine(props, obs) dim, bbox_min, bbox_max = utils.get_dimensions(obs) props.dimensions = dim props.bbox_min = bbox_min props.bbox_max = bbox_max check_rig(props, obs) check_anim(props, obs) check_meshprops(props, obs) check_modifiers(props, obs) countObs(props, obs) elif ui.asset_type =='MATERIAL': # reset some properties here, because they might not get re-filled at all when they aren't needed anymore. mat = utils.get_active_asset() props = mat.blenderkit props.texture_resolution_max = 0 props.texture_resolution_min = 0 check_material(props, mat)
def get_upload_location(props): ''' not used by now, gets location of uploaded asset - potentially usefull if we draw a nice upload gizmo in viewport. Parameters ---------- props Returns ------- ''' scene = bpy.context.scene ui_props = scene.blenderkitUI if ui_props.asset_type == 'MODEL': if bpy.context.view_layer.objects.active is not None: ob = utils.get_active_model() return ob.location if ui_props.asset_type == 'SCENE': return None elif ui_props.asset_type == 'MATERIAL': if bpy.context.view_layer.objects.active is not None and bpy.context.active_object.active_material is not None: return bpy.context.active_object.location elif ui_props.asset_type == 'TEXTURE': return None elif ui_props.asset_type == 'BRUSH': return None return None
def get_upload_location(props): scene = bpy.context.scene ui_props = scene.blenderkitUI if ui_props.asset_type == 'MODEL': if bpy.context.active_object is not None: ob = utils.get_active_model() return ob.location if ui_props.asset_type == 'SCENE': return None elif ui_props.asset_type == 'MATERIAL': if bpy.context.active_object is not None and bpy.context.active_object.active_material is not None: return bpy.context.active_object.location elif ui_props.asset_type == 'TEXTURE': return None elif ui_props.asset_type == 'BRUSH': return None return None
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.') layout.prop(o, 'name') 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') draw_panel_model_rating(self, context)
def get_upload_data(self, context, asset_type): user_preferences = bpy.context.preferences.addons['blenderkit'].preferences api_key = user_preferences.api_key export_data = { "type": asset_type, } upload_params = {} if asset_type == 'MODEL': # Prepare to save the file mainmodel = utils.get_active_model() props = mainmodel.blenderkit obs = utils.get_hierarchy(mainmodel) obnames = [] for ob in obs: obnames.append(ob.name) export_data["models"] = obnames export_data["thumbnail_path"] = bpy.path.abspath(props.thumbnail) eval_path_computing = "bpy.data.objects['%s'].blenderkit.uploading" % mainmodel.name eval_path_state = "bpy.data.objects['%s'].blenderkit.upload_state" % mainmodel.name eval_path = "bpy.data.objects['%s']" % mainmodel.name engines = [props.engine.lower()] if props.engine1 != 'NONE': engines.append(props.engine1.lower()) if props.engine2 != 'NONE': engines.append(props.engine2.lower()) if props.engine3 != 'NONE': engines.append(props.engine3.lower()) if props.engine == 'OTHER': engines.append(props.engine_other.lower()) style = props.style.lower() if style == 'OTHER': style = props.style_other.lower() pl_dict = {'FINISHED': 'finished', 'TEMPLATE': 'template'} upload_data = { "assetType": 'model', } upload_params = { "productionLevel": props.production_level.lower(), "model_style": style, "engines": engines, "modifiers": comma2array(props.modifiers), "materials": comma2array(props.materials), "shaders": comma2array(props.shaders), "uv": props.uv, "dimensionX": round(props.dimensions[0], 4), "dimensionY": round(props.dimensions[1], 4), "dimensionZ": round(props.dimensions[2], 4), "boundBoxMinX": round(props.bbox_min[0], 4), "boundBoxMinY": round(props.bbox_min[1], 4), "boundBoxMinZ": round(props.bbox_min[2], 4), "boundBoxMaxX": round(props.bbox_max[0], 4), "boundBoxMaxY": round(props.bbox_max[1], 4), "boundBoxMaxZ": round(props.bbox_max[2], 4), "animated": props.animated, "rig": props.rig, "simulation": props.simulation, "purePbr": props.pbr, "faceCount": props.face_count, "faceCountRender": props.face_count_render, "manifold": props.manifold, "objectCount": props.object_count, # "scene": props.is_scene, } if props.use_design_year: upload_params["designYear"] = props.design_year if props.condition != 'UNSPECIFIED': upload_params["condition"] = props.condition.lower() if props.pbr: pt = props.pbr_type pt = pt.lower() upload_params["pbrType"] = pt if props.texture_resolution_max > 0: upload_params["textureResolutionMax"] = props.texture_resolution_max upload_params["textureResolutionMin"] = props.texture_resolution_min if props.mesh_poly_type != 'OTHER': upload_params["meshPolyType"] = props.mesh_poly_type.lower() # .replace('_',' ') optional_params = ['manufacturer', 'designer', 'design_collection', 'design_variant'] for p in optional_params: if eval('props.%s' % p) != '': upload_params[sub_to_camel(p)] = eval('props.%s' % p) if asset_type == 'SCENE': # Prepare to save the file s = bpy.context.scene props = s.blenderkit export_data["scene"] = s.name export_data["thumbnail_path"] = bpy.path.abspath(props.thumbnail) eval_path_computing = "bpy.data.scenes['%s'].blenderkit.uploading" % s.name eval_path_state = "bpy.data.scenes['%s'].blenderkit.upload_state" % s.name eval_path = "bpy.data.scenes['%s']" % s.name engines = [props.engine.lower()] if props.engine1 != 'NONE': engines.append(props.engine1.lower()) if props.engine2 != 'NONE': engines.append(props.engine2.lower()) if props.engine3 != 'NONE': engines.append(props.engine3.lower()) if props.engine == 'OTHER': engines.append(props.engine_other.lower()) style = props.style.lower() if style == 'OTHER': style = props.style_other.lower() pl_dict = {'FINISHED': 'finished', 'TEMPLATE': 'template'} upload_data = { "assetType": 'scene', } upload_params = { "productionLevel": props.production_level.lower(), "model_style": style, "engines": engines, "modifiers": comma2array(props.modifiers), "materials": comma2array(props.materials), "shaders": comma2array(props.shaders), "uv": props.uv, "animated": props.animated, # "simulation": props.simulation, "purePbr": props.pbr, "faceCount": 1, # props.face_count, "faceCountRender": 1, # props.face_count_render, "objectCount": 1, # props.object_count, # "scene": props.is_scene, } if props.use_design_year: upload_params["designYear"] = props.design_year if props.condition != 'UNSPECIFIED': upload_params["condition"] = props.condition.lower() if props.pbr: pt = props.pbr_type pt = pt.lower() upload_params["pbrType"] = pt if props.texture_resolution_max > 0: upload_params["textureResolutionMax"] = props.texture_resolution_max upload_params["textureResolutionMin"] = props.texture_resolution_min if props.mesh_poly_type != 'OTHER': upload_params["meshPolyType"] = props.mesh_poly_type.lower() # .replace('_',' ') elif asset_type == 'MATERIAL': mat = bpy.context.active_object.active_material props = mat.blenderkit # props.name = mat.name export_data["material"] = str(mat.name) export_data["thumbnail_path"] = bpy.path.abspath(props.thumbnail) # mat analytics happen here, since they don't take up any time... asset_inspector.check_material(props, mat) eval_path_computing = "bpy.data.materials['%s'].blenderkit.uploading" % mat.name eval_path_state = "bpy.data.materials['%s'].blenderkit.upload_state" % mat.name eval_path = "bpy.data.materials['%s']" % mat.name engine = props.engine if engine == 'OTHER': engine = props.engine_other engine = engine.lower() style = props.style.lower() if style == 'OTHER': style = props.style_other.lower() upload_data = { "assetType": 'material', } upload_params = { "material_style": style, "engine": engine, "shaders": comma2array(props.shaders), "uv": props.uv, "animated": props.animated, "purePbr": props.pbr, "textureSizeMeters": props.texture_size_meters, } if props.pbr: upload_params["pbrType"] = props.pbr_type.lower() if props.texture_resolution_max > 0: upload_params["textureResolutionMax"] = props.texture_resolution_max upload_params["textureResolutionMin"] = props.texture_resolution_min elif asset_type == 'BRUSH': brush = utils.get_active_brush() props = brush.blenderkit # props.name = brush.name export_data["brush"] = str(brush.name) export_data["thumbnail_path"] = bpy.path.abspath(brush.icon_filepath) eval_path_computing = "bpy.data.brushes['%s'].blenderkit.uploading" % brush.name eval_path_state = "bpy.data.brushes['%s'].blenderkit.upload_state" % brush.name eval_path = "bpy.data.brushes['%s']" % brush.name # mat analytics happen here, since they don't take up any time... brush_type = '' if bpy.context.sculpt_object is not None: brush_type = 'sculpt' elif bpy.context.image_paint_object: # could be just else, but for future p brush_type = 'texture_paint' upload_params = { "mode": brush_type, } upload_data = { "assetType": 'brush', } elif asset_type == 'TEXTURE': style = props.style if style == 'OTHER': style = props.style_other upload_data = { "assetType": 'texture', } upload_params = { "style": style, "animated": props.animated, "purePbr": props.pbr, "resolution": props.resolution, } if props.pbr: pt = props.pbr_type pt = pt.lower() upload_data["pbrType"] = pt add_version(upload_data) upload_data["name"] = props.name upload_data["description"] = props.description upload_data["tags"] = comma2array(props.tags) if props.category == '': upload_data["category"] = asset_type.lower() else: upload_data["category"] = props.category if props.subcategory != '': upload_data["category"] = props.subcategory upload_data["license"] = props.license upload_data["isFree"] = props.is_free upload_data["isPrivate"] = props.is_private == 'PRIVATE' upload_data["token"] = user_preferences.api_key if props.asset_base_id != '': upload_data['assetBaseId'] = props.asset_base_id upload_data['id'] = props.id upload_data['parameters'] = upload_params return export_data, upload_data, eval_path_computing, eval_path_state, eval_path, props
def start_thumbnailer(self, context): # Prepare to save the file mainmodel = utils.get_active_model() mainmodel.blenderkit.is_generating_thumbnail = True mainmodel.blenderkit.thumbnail_generating_state = 'starting blender instance' binary_path = bpy.app.binary_path script_path = os.path.dirname(os.path.realpath(__file__)) basename, ext = os.path.splitext(bpy.data.filepath) if not basename: basename = os.path.join(basename, "temp") if not ext: ext = ".blend" asset_name = mainmodel.name tempdir = tempfile.mkdtemp() file_dir = os.path.dirname(bpy.data.filepath) thumb_path = os.path.join(file_dir, asset_name) rel_thumb_path = os.path.join('//', asset_name) i = 0 while os.path.isfile(thumb_path + '.jpg'): thumb_path = os.path.join(file_dir, asset_name + '_' + str(i).zfill(4)) rel_thumb_path = os.path.join('//', asset_name + '_' + str(i).zfill(4)) i += 1 filepath = os.path.join(tempdir, "thumbnailer_blenderkit" + ext) tfpath = paths.get_thumbnailer_filepath() datafile = os.path.join(tempdir, BLENDERKIT_EXPORT_DATA_FILE) try: # save a copy of actual scene but don't interfere with the users models bpy.ops.wm.save_as_mainfile(filepath=filepath, compress=False, copy=True) obs = utils.get_hierarchy(mainmodel) obnames = [] for ob in obs: obnames.append(ob.name) with open(datafile, 'w') as s: bkit = mainmodel.blenderkit json.dump( { "type": "model", "models": str(obnames), "thumbnail_angle": bkit.thumbnail_angle, "thumbnail_snap_to": bkit.thumbnail_snap_to, "thumbnail_background_lightness": bkit.thumbnail_background_lightness, "thumbnail_resolution": bkit.thumbnail_resolution, "thumbnail_samples": bkit.thumbnail_samples, "thumbnail_denoising": bkit.thumbnail_denoising, }, s) proc = subprocess.Popen([ binary_path, "--background", "-noaudio", tfpath, "--python", os.path.join(script_path, "autothumb_model_bg.py"), "--", datafile, filepath, thumb_path, tempdir ], bufsize=1, stdout=subprocess.PIPE, stdin=subprocess.PIPE, creationflags=utils.get_process_flags()) eval_path_computing = "bpy.data.objects['%s'].blenderkit.is_generating_thumbnail" % mainmodel.name eval_path_state = "bpy.data.objects['%s'].blenderkit.thumbnail_generating_state" % mainmodel.name eval_path = "bpy.data.objects['%s']" % mainmodel.name bg_blender.add_bg_process(eval_path_computing=eval_path_computing, eval_path_state=eval_path_state, eval_path=eval_path, process_type='THUMBNAILER', process=proc) mainmodel.blenderkit.thumbnail = rel_thumb_path + '.jpg' mainmodel.blenderkit.thumbnail_generating_state = 'Saving .blend file' except Exception as e: self.report({'WARNING'}, "Error while exporting file: %s" % str(e)) return {'FINISHED'}
def update_upload_model_preview(self, context): ob = utils.get_active_model() if ob is not None: props = ob.blenderkit imgpath = props.thumbnail check_thumbnail(props, imgpath)
def start_thumbnailer(self, context): # Prepare to save the file mainmodel = utils.get_active_model() mainmodel.blenderkit.is_generating_thumbnail = True mainmodel.blenderkit.thumbnail_generating_state = 'starting blender instance' binary_path = bpy.app.binary_path script_path = os.path.dirname(os.path.realpath(__file__)) basename, ext = os.path.splitext(bpy.data.filepath) if not basename: basename = os.path.join(basename, "temp") if not ext: ext = ".blend" asset_name = mainmodel.blenderkit.name tempdir = tempfile.mkdtemp() file_dir = os.path.dirname(bpy.data.filepath) thumb_path = os.path.join(file_dir, asset_name) rel_thumb_path = os.path.join('//', asset_name) i = 0 while os.path.isfile(thumb_path + '.jpg'): thumb_path = os.path.join(file_dir, asset_name + '_' + str(i).zfill(4)) rel_thumb_path = os.path.join('//', asset_name + '_' + str(i).zfill(4)) i += 1 filepath = os.path.join(tempdir, "thumbnailer_blenderkit" + ext) tfpath = paths.get_thumbnailer_filepath() datafile = os.path.join(tempdir, BLENDERKIT_EXPORT_DATA_FILE) try: # save a copy of actual scene but don't interfere with the users models bpy.ops.wm.save_as_mainfile(filepath=filepath, compress=False, copy=True) obs = utils.get_hierarchy(mainmodel) obnames = [] for ob in obs: obnames.append(ob.name) with open(datafile, 'w') as s: bkit = mainmodel.blenderkit json.dump({ "type": "model", "models": str(obnames), "thumbnail_angle": bkit.thumbnail_angle, "thumbnail_snap_to": bkit.thumbnail_snap_to, "thumbnail_background_lightness": bkit.thumbnail_background_lightness, "thumbnail_samples": bkit.thumbnail_samples, "thumbnail_denoising": bkit.thumbnail_denoising, }, s) flags = BELOW_NORMAL_PRIORITY_CLASS if sys.platform != 'win32': # TODO test this on windows and find out how to change process priority on linux # without psutil - we don't want any more libs in the addon flags = 0 proc = subprocess.Popen([ binary_path, "--background", "-noaudio", tfpath, "--python", os.path.join(script_path, "autothumb_model_bg.py"), "--", datafile, filepath, thumb_path, tempdir ], bufsize=1, stdout=subprocess.PIPE, stdin=subprocess.PIPE, creationflags=flags) eval_path_computing = "bpy.data.objects['%s'].blenderkit.is_generating_thumbnail" % mainmodel.name eval_path_state = "bpy.data.objects['%s'].blenderkit.thumbnail_generating_state" % mainmodel.name eval_path = "bpy.data.objects['%s']" % mainmodel.name bg_blender.add_bg_process(eval_path_computing=eval_path_computing, eval_path_state=eval_path_state, eval_path=eval_path, process_type='THUMBNAILER', process=proc) mainmodel.blenderkit.thumbnail = rel_thumb_path + '.jpg' mainmodel.blenderkit.thumbnail_generating_state = 'Saving .blend file' except Exception as e: self.report({'WARNING'}, "Error while exporting file: %s" % str(e)) return {'FINISHED'}
def get_upload_data(caller=None, context=None, asset_type=None): ''' works though metadata from addom props and prepares it for upload to dicts. Parameters ---------- caller - upload operator or none context - context asset_type - asset type in capitals (blender enum) Returns ------- export_ddta- all extra data that the process needs to upload and communicate with UI from a thread. - eval_path_computing - string path to UI prop that denots if upload is still running - eval_path_state - string path to UI prop that delivers messages about upload to ui - eval_path - path to object holding upload data to be able to access it with various further commands - models - in case of model upload, list of objects - thumbnail_path - path to thumbnail file upload_data - asset_data generated from the ui properties ''' user_preferences = bpy.context.preferences.addons['blenderkit'].preferences api_key = user_preferences.api_key export_data = { # "type": asset_type, } upload_params = {} if asset_type == 'MODEL': # Prepare to save the file mainmodel = utils.get_active_model() props = mainmodel.blenderkit obs = utils.get_hierarchy(mainmodel) obnames = [] for ob in obs: obnames.append(ob.name) export_data["models"] = obnames export_data["thumbnail_path"] = bpy.path.abspath(props.thumbnail) eval_path_computing = "bpy.data.objects['%s'].blenderkit.uploading" % mainmodel.name eval_path_state = "bpy.data.objects['%s'].blenderkit.upload_state" % mainmodel.name eval_path = "bpy.data.objects['%s']" % mainmodel.name engines = [props.engine.lower()] if props.engine1 != 'NONE': engines.append(props.engine1.lower()) if props.engine2 != 'NONE': engines.append(props.engine2.lower()) if props.engine3 != 'NONE': engines.append(props.engine3.lower()) if props.engine == 'OTHER': engines.append(props.engine_other.lower()) style = props.style.lower() # if style == 'OTHER': # style = props.style_other.lower() pl_dict = {'FINISHED': 'finished', 'TEMPLATE': 'template'} upload_data = { "assetType": 'model', } upload_params = { "productionLevel": props.production_level.lower(), "model_style": style, "engines": engines, "modifiers": comma2array(props.modifiers), "materials": comma2array(props.materials), "shaders": comma2array(props.shaders), "uv": props.uv, "dimensionX": round(props.dimensions[0], 4), "dimensionY": round(props.dimensions[1], 4), "dimensionZ": round(props.dimensions[2], 4), "boundBoxMinX": round(props.bbox_min[0], 4), "boundBoxMinY": round(props.bbox_min[1], 4), "boundBoxMinZ": round(props.bbox_min[2], 4), "boundBoxMaxX": round(props.bbox_max[0], 4), "boundBoxMaxY": round(props.bbox_max[1], 4), "boundBoxMaxZ": round(props.bbox_max[2], 4), "animated": props.animated, "rig": props.rig, "simulation": props.simulation, "purePbr": props.pbr, "faceCount": props.face_count, "faceCountRender": props.face_count_render, "manifold": props.manifold, "objectCount": props.object_count, "procedural": props.is_procedural, "nodeCount": props.node_count, "textureCount": props.texture_count, "megapixels": round(props.total_megapixels / 1000000), # "scene": props.is_scene, } if props.use_design_year: upload_params["designYear"] = props.design_year if props.condition != 'UNSPECIFIED': upload_params["condition"] = props.condition.lower() if props.pbr: pt = props.pbr_type pt = pt.lower() upload_params["pbrType"] = pt if props.texture_resolution_max > 0: upload_params["textureResolutionMax"] = props.texture_resolution_max upload_params["textureResolutionMin"] = props.texture_resolution_min if props.mesh_poly_type != 'OTHER': upload_params["meshPolyType"] = props.mesh_poly_type.lower() # .replace('_',' ') optional_params = ['manufacturer', 'designer', 'design_collection', 'design_variant'] for p in optional_params: if eval('props.%s' % p) != '': upload_params[sub_to_camel(p)] = eval('props.%s' % p) if asset_type == 'SCENE': # Prepare to save the file s = bpy.context.scene props = s.blenderkit export_data["scene"] = s.name export_data["thumbnail_path"] = bpy.path.abspath(props.thumbnail) eval_path_computing = "bpy.data.scenes['%s'].blenderkit.uploading" % s.name eval_path_state = "bpy.data.scenes['%s'].blenderkit.upload_state" % s.name eval_path = "bpy.data.scenes['%s']" % s.name engines = [props.engine.lower()] if props.engine1 != 'NONE': engines.append(props.engine1.lower()) if props.engine2 != 'NONE': engines.append(props.engine2.lower()) if props.engine3 != 'NONE': engines.append(props.engine3.lower()) if props.engine == 'OTHER': engines.append(props.engine_other.lower()) style = props.style.lower() # if style == 'OTHER': # style = props.style_other.lower() pl_dict = {'FINISHED': 'finished', 'TEMPLATE': 'template'} upload_data = { "assetType": 'scene', } upload_params = { "productionLevel": props.production_level.lower(), "model_style": style, "engines": engines, "modifiers": comma2array(props.modifiers), "materials": comma2array(props.materials), "shaders": comma2array(props.shaders), "uv": props.uv, "animated": props.animated, # "simulation": props.simulation, "purePbr": props.pbr, "faceCount": 1, # props.face_count, "faceCountRender": 1, # props.face_count_render, "objectCount": 1, # props.object_count, # "scene": props.is_scene, } if props.use_design_year: upload_params["designYear"] = props.design_year if props.condition != 'UNSPECIFIED': upload_params["condition"] = props.condition.lower() if props.pbr: pt = props.pbr_type pt = pt.lower() upload_params["pbrType"] = pt if props.texture_resolution_max > 0: upload_params["textureResolutionMax"] = props.texture_resolution_max upload_params["textureResolutionMin"] = props.texture_resolution_min if props.mesh_poly_type != 'OTHER': upload_params["meshPolyType"] = props.mesh_poly_type.lower() # .replace('_',' ') elif asset_type == 'MATERIAL': mat = bpy.context.active_object.active_material props = mat.blenderkit # props.name = mat.name export_data["material"] = str(mat.name) export_data["thumbnail_path"] = bpy.path.abspath(props.thumbnail) # mat analytics happen here, since they don't take up any time... asset_inspector.check_material(props, mat) eval_path_computing = "bpy.data.materials['%s'].blenderkit.uploading" % mat.name eval_path_state = "bpy.data.materials['%s'].blenderkit.upload_state" % mat.name eval_path = "bpy.data.materials['%s']" % mat.name engine = props.engine if engine == 'OTHER': engine = props.engine_other engine = engine.lower() style = props.style.lower() # if style == 'OTHER': # style = props.style_other.lower() upload_data = { "assetType": 'material', } upload_params = { "material_style": style, "engine": engine, "shaders": comma2array(props.shaders), "uv": props.uv, "animated": props.animated, "purePbr": props.pbr, "textureSizeMeters": props.texture_size_meters, "procedural": props.is_procedural, "nodeCount": props.node_count, "textureCount": props.texture_count, "megapixels": round(props.total_megapixels / 1000000), } if props.pbr: upload_params["pbrType"] = props.pbr_type.lower() if props.texture_resolution_max > 0: upload_params["textureResolutionMax"] = props.texture_resolution_max upload_params["textureResolutionMin"] = props.texture_resolution_min elif asset_type == 'BRUSH': brush = utils.get_active_brush() props = brush.blenderkit # props.name = brush.name export_data["brush"] = str(brush.name) export_data["thumbnail_path"] = bpy.path.abspath(brush.icon_filepath) eval_path_computing = "bpy.data.brushes['%s'].blenderkit.uploading" % brush.name eval_path_state = "bpy.data.brushes['%s'].blenderkit.upload_state" % brush.name eval_path = "bpy.data.brushes['%s']" % brush.name # mat analytics happen here, since they don't take up any time... brush_type = '' if bpy.context.sculpt_object is not None: brush_type = 'sculpt' elif bpy.context.image_paint_object: # could be just else, but for future p brush_type = 'texture_paint' upload_params = { "mode": brush_type, } upload_data = { "assetType": 'brush', } elif asset_type == 'HDR': ui_props = bpy.context.scene.blenderkitUI # imagename = ui_props.hdr_upload_image image = ui_props.hdr_upload_image # bpy.data.images.get(imagename) if not image: return None, None props = image.blenderkit # props.name = brush.name base, ext = os.path.splitext(image.filepath) thumb_path = base + '.jpg' export_data["thumbnail_path"] = bpy.path.abspath(thumb_path) export_data["hdr"] = str(image.name) export_data["hdr_filepath"] = str(bpy.path.abspath(image.filepath)) # export_data["thumbnail_path"] = bpy.path.abspath(brush.icon_filepath) eval_path_computing = "bpy.data.images['%s'].blenderkit.uploading" % image.name eval_path_state = "bpy.data.images['%s'].blenderkit.upload_state" % image.name eval_path = "bpy.data.images['%s']" % image.name # mat analytics happen here, since they don't take up any time... upload_params = { "textureResolutionMax": props.texture_resolution_max } upload_data = { "assetType": 'hdr', } elif asset_type == 'TEXTURE': style = props.style # if style == 'OTHER': # style = props.style_other upload_data = { "assetType": 'texture', } upload_params = { "style": style, "animated": props.animated, "purePbr": props.pbr, "resolution": props.resolution, } if props.pbr: pt = props.pbr_type pt = pt.lower() upload_data["pbrType"] = pt add_version(upload_data) # caller can be upload operator, but also asset bar called from tooltip generator if caller and caller.main_file == True: upload_data["name"] = props.name upload_data["displayName"] = props.name else: upload_data["displayName"] = props.name upload_data["description"] = props.description upload_data["tags"] = comma2array(props.tags) # category is always only one value by a slug, that's why we go down to the lowest level and overwrite. if props.category == '': upload_data["category"] = asset_type.lower() else: upload_data["category"] = props.category if props.subcategory != 'NONE': upload_data["category"] = props.subcategory if props.subcategory1 != 'NONE': upload_data["category"] = props.subcategory1 upload_data["license"] = props.license upload_data["isFree"] = props.is_free upload_data["isPrivate"] = props.is_private == 'PRIVATE' upload_data["token"] = user_preferences.api_key upload_data['parameters'] = upload_params # if props.asset_base_id != '': export_data['assetBaseId'] = props.asset_base_id export_data['id'] = props.id export_data['eval_path_computing'] = eval_path_computing export_data['eval_path_state'] = eval_path_state export_data['eval_path'] = eval_path return export_data, upload_data
def execute(self, context): asset = utils.get_active_model() asset.blenderkit.is_generating_thumbnail = True asset.blenderkit.thumbnail_generating_state = 'starting blender instance' tempdir = tempfile.mkdtemp() ext = '.blend' filepath = os.path.join(tempdir, "thumbnailer_blenderkit" + ext) path_can_be_relative = True file_dir = os.path.dirname(bpy.data.filepath) if file_dir == '': file_dir = tempdir path_can_be_relative = False an_slug = paths.slugify(asset.name) thumb_path = os.path.join(file_dir, an_slug) if path_can_be_relative: rel_thumb_path = os.path.join('//', an_slug) else: rel_thumb_path = thumb_path i = 0 while os.path.isfile(thumb_path + '.jpg'): thumb_path = os.path.join(file_dir, an_slug + '_' + str(i).zfill(4)) rel_thumb_path = os.path.join('//', an_slug + '_' + str(i).zfill(4)) i += 1 bkit = asset.blenderkit bkit.thumbnail = rel_thumb_path + '.jpg' bkit.thumbnail_generating_state = 'Saving .blend file' # save a copy of actual scene but don't interfere with the users models bpy.ops.wm.save_as_mainfile(filepath=filepath, compress=False, copy=True) # get all included objects obs = utils.get_hierarchy(asset) obnames = [] for ob in obs: obnames.append(ob.name) args_dict = { "type": "material", "asset_name": asset.name, "filepath": filepath, "thumbnail_path": thumb_path, "tempdir": tempdir, } thumbnail_args = { "type": "model", "models": str(obnames), "thumbnail_angle": bkit.thumbnail_angle, "thumbnail_snap_to": bkit.thumbnail_snap_to, "thumbnail_background_lightness": bkit.thumbnail_background_lightness, "thumbnail_resolution": bkit.thumbnail_resolution, "thumbnail_samples": bkit.thumbnail_samples, "thumbnail_denoising": bkit.thumbnail_denoising, } args_dict.update(thumbnail_args) start_thumbnailer(self, json_args=args_dict, props=asset.blenderkit, wait=False) return {'FINISHED'}
def draw_asset_context_menu(self, context, asset_data): layout = self.layout ui_props = context.scene.blenderkitUI author_id = str(asset_data['author']['id']) wm = bpy.context.window_manager if wm.get('bkit authors') is not None: a = bpy.context.window_manager['bkit authors'].get(author_id) if a is not None: # utils.p('author:', a) if a.get('aboutMeUrl') is not None: op = layout.operator('wm.url_open', text="Open Author's Website") op.url = a['aboutMeUrl'] op = layout.operator('view3d.blenderkit_search', text="Show Assets By Author") op.keywords = '' op.author_id = author_id op = layout.operator('view3d.blenderkit_search', text='Search Similar') op.keywords = asset_data['name'] + ' ' + asset_data['description'] + ' ' + ' '.join(asset_data['tags']) if asset_data.get('canDownload') != 0: if len(bpy.context.selected_objects) > 0 and ui_props.asset_type == 'MODEL': aob = bpy.context.active_object if aob is None: aob = bpy.context.selected_objects[0] op = layout.operator('scene.blenderkit_download', text='Replace Active Models') #this checks if the menu got called from right-click in assetbar(then index is 0 - x) or # from a panel(then replacement happens from the active model) if ui_props.active_index == -3: #called from addon panel o = utils.get_active_model() op.asset_base_id = o['asset_data']['assetBaseId'] else: op.asset_index = ui_props.active_index op.asset_type = ui_props.asset_type op.model_location = aob.location op.model_rotation = aob.rotation_euler op.target_object = aob.name op.material_target_slot = aob.active_material_index op.replace = True wm = bpy.context.window_manager profile = wm.get('bkit profile') if profile is not None: # validation if utils.profile_is_validator(): layout.label(text='Validation tools:') if asset_data['verificationStatus'] != 'uploaded': op = layout.operator('object.blenderkit_change_status', text='set Uploaded') op.asset_id = asset_data['id'] op.state = 'uploaded' if asset_data['verificationStatus'] != 'validated': op = layout.operator('object.blenderkit_change_status', text='Validate') op.asset_id = asset_data['id'] op.state = 'validated' if asset_data['verificationStatus'] != 'on_hold': op = layout.operator('object.blenderkit_change_status', text='Put on Hold') op.asset_id = asset_data['id'] op.state = 'on_hold' if asset_data['verificationStatus'] != 'rejected': op = layout.operator('object.blenderkit_change_status', text='Reject') op.asset_id = asset_data['id'] op.state = 'rejected' if author_id == str(profile['user']['id']): layout.label(text='Management tools:') row = layout.row() row.operator_context = 'INVOKE_DEFAULT' op = row.operator('object.blenderkit_change_status', text='Delete') op.asset_id = asset_data['id'] op.state = 'deleted'
def draw_panel_model_rating(self, context): # o = bpy.context.active_object o = utils.get_active_model() # print('ratings active',o) draw_ratings(self.layout, context) # , props)
def get_upload_data(self, context, asset_type): user_preferences = bpy.context.preferences.addons['blenderkit'].preferences api_key = user_preferences.api_key export_data = { "type": asset_type, } upload_params = {} if asset_type == 'MODEL': # Prepare to save the file mainmodel = utils.get_active_model() props = mainmodel.blenderkit obs = utils.get_hierarchy(mainmodel) obnames = [] for ob in obs: obnames.append(ob.name) export_data["models"] = obnames export_data["thumbnail_path"] = bpy.path.abspath(props.thumbnail) eval_path_computing = "bpy.data.objects['%s'].blenderkit.uploading" % mainmodel.name eval_path_state = "bpy.data.objects['%s'].blenderkit.upload_state" % mainmodel.name eval_path = "bpy.data.objects['%s']" % mainmodel.name engines = [props.engine.lower()] if props.engine1 != 'NONE': engines.append(props.engine1.lower()) if props.engine2 != 'NONE': engines.append(props.engine2.lower()) if props.engine3 != 'NONE': engines.append(props.engine3.lower()) if props.engine == 'OTHER': engines.append(props.engine_other.lower()) style = props.style.lower() if style == 'OTHER': style = props.style_other.lower() pl_dict = {'FINISHED': 'finished', 'TEMPLATE': 'template'} upload_data = { "assetType": 'model', } upload_params = { "productionLevel": props.production_level.lower(), "model_style": style, "engines": engines, "modifiers": comma2array(props.modifiers), "materials": comma2array(props.materials), "shaders": comma2array(props.shaders), "uv": props.uv, "dimensionX": round(props.dimensions[0], 4), "dimensionY": round(props.dimensions[1], 4), "dimensionZ": round(props.dimensions[2], 4), "boundBoxMinX": round(props.bbox_min[0], 4), "boundBoxMinY": round(props.bbox_min[1], 4), "boundBoxMinZ": round(props.bbox_min[2], 4), "boundBoxMaxX": round(props.bbox_max[0], 4), "boundBoxMaxY": round(props.bbox_max[1], 4), "boundBoxMaxZ": round(props.bbox_max[2], 4), "animated": props.animated, "rig": props.rig, "simulation": props.simulation, "purePbr": props.pbr, "faceCount": props.face_count, "faceCountRender": props.face_count_render, "manifold": props.manifold, "objectCount": props.object_count, # "scene": props.is_scene, } if props.use_design_year: upload_params["designYear"] = props.design_year if props.condition != 'UNSPECIFIED': upload_params["condition"] = props.condition.lower() if props.pbr: pt = props.pbr_type pt = pt.lower() upload_params["pbrType"] = pt if props.texture_resolution_max > 0: upload_params["textureResolutionMax"] = props.texture_resolution_max upload_params["textureResolutionMin"] = props.texture_resolution_min if props.mesh_poly_type != 'OTHER': upload_params["meshPolyType"] = props.mesh_poly_type.lower() # .replace('_',' ') optional_params = ['manufacturer', 'designer', 'design_collection', 'design_variant'] for p in optional_params: if eval('props.%s' % p) != '': upload_params[sub_to_camel(p)] = eval('props.%s' % p) if asset_type == 'SCENE': # Prepare to save the file s = bpy.context.scene props = s.blenderkit export_data["scene"] = s.name export_data["thumbnail_path"] = bpy.path.abspath(props.thumbnail) eval_path_computing = "bpy.data.scenes['%s'].blenderkit.uploading" % s.name eval_path_state = "bpy.data.scenes['%s'].blenderkit.upload_state" % s.name eval_path = "bpy.data.scenes['%s']" % s.name engines = [props.engine.lower()] if props.engine1 != 'NONE': engines.append(props.engine1.lower()) if props.engine2 != 'NONE': engines.append(props.engine2.lower()) if props.engine3 != 'NONE': engines.append(props.engine3.lower()) if props.engine == 'OTHER': engines.append(props.engine_other.lower()) style = props.style.lower() if style == 'OTHER': style = props.style_other.lower() pl_dict = {'FINISHED': 'finished', 'TEMPLATE': 'template'} upload_data = { "assetType": 'scene', } upload_params = { "productionLevel": props.production_level.lower(), "model_style": style, "engines": engines, "modifiers": comma2array(props.modifiers), "materials": comma2array(props.materials), "shaders": comma2array(props.shaders), "uv": props.uv, "animated": props.animated, # "simulation": props.simulation, "purePbr": props.pbr, "faceCount": 1, # props.face_count, "faceCountRender": 1, # props.face_count_render, "objectCount": 1, # props.object_count, # "scene": props.is_scene, } if props.use_design_year: upload_params["designYear"] = props.design_year if props.condition != 'UNSPECIFIED': upload_params["condition"] = props.condition.lower() if props.pbr: pt = props.pbr_type pt = pt.lower() upload_params["pbrType"] = pt if props.texture_resolution_max > 0: upload_params["textureResolutionMax"] = props.texture_resolution_max upload_params["textureResolutionMin"] = props.texture_resolution_min if props.mesh_poly_type != 'OTHER': upload_params["meshPolyType"] = props.mesh_poly_type.lower() # .replace('_',' ') elif asset_type == 'MATERIAL': mat = bpy.context.active_object.active_material props = mat.blenderkit # props.name = mat.name export_data["material"] = str(mat.name) export_data["thumbnail_path"] = bpy.path.abspath(props.thumbnail) # mat analytics happen here, since they don't take up any time... asset_inspector.check_material(props, mat) eval_path_computing = "bpy.data.materials['%s'].blenderkit.uploading" % mat.name eval_path_state = "bpy.data.materials['%s'].blenderkit.upload_state" % mat.name eval_path = "bpy.data.materials['%s']" % mat.name engine = props.engine if engine == 'OTHER': engine = props.engine_other engine = engine.lower() style = props.style.lower() if style == 'OTHER': style = props.style_other.lower() upload_data = { "assetType": 'material', } upload_params = { "material_style": style, "engine": engine, "shaders": comma2array(props.shaders), "uv": props.uv, "animated": props.animated, "purePbr": props.pbr, "textureSizeMeters": props.texture_size_meters, } if props.pbr: upload_params["pbrType"] = props.pbr_type.lower() if props.texture_resolution_max > 0: upload_params["textureResolutionMax"] = props.texture_resolution_max upload_params["textureResolutionMin"] = props.texture_resolution_min elif asset_type == 'BRUSH': brush = utils.get_active_brush() props = brush.blenderkit # props.name = brush.name export_data["brush"] = str(brush.name) export_data["thumbnail_path"] = bpy.path.abspath(brush.icon_filepath) eval_path_computing = "bpy.data.brushes['%s'].blenderkit.uploading" % brush.name eval_path_state = "bpy.data.brushes['%s'].blenderkit.upload_state" % brush.name eval_path = "bpy.data.brushes['%s']" % brush.name # mat analytics happen here, since they don't take up any time... brush_type = '' if bpy.context.sculpt_object is not None: brush_type = 'sculpt' elif bpy.context.image_paint_object: # could be just else, but for future p brush_type = 'texture_paint' upload_params = { "mode": brush_type, } upload_data = { "assetType": 'brush', } elif asset_type == 'TEXTURE': style = props.style if style == 'OTHER': style = props.style_other upload_data = { "assetType": 'texture', } upload_params = { "style": style, "animated": props.animated, "purePbr": props.pbr, "resolution": props.resolution, } if props.pbr: pt = props.pbr_type pt = pt.lower() upload_data["pbrType"] = pt add_version(upload_data) upload_data["name"] = props.name upload_data["description"] = props.description upload_data["tags"] = comma2array(props.tags) if props.category == '': upload_data["category"] = asset_type.lower() else: upload_data["category"] = props.category if props.subcategory != '': upload_data["category"] = props.subcategory upload_data["license"] = props.license upload_data["isFree"] = props.is_free upload_data["token"] = user_preferences.api_key if props.asset_base_id != '': upload_data['assetBaseId'] = props.asset_base_id upload_data['id'] = props.id upload_data['parameters'] = upload_params return export_data, upload_data, eval_path_computing, eval_path_state, eval_path, props