def send_to_bg(asset_data, fpath, command='generate_resolutions', wait=True): ''' Send varioust task to a new blender instance that runs and closes after finishing the task. This function waits until the process finishes. The function tries to set the same bpy.app.debug_value in the instance of Blender that is run. Parameters ---------- asset_data fpath - file that will be processed command - command which should be run in background. Returns ------- None ''' data = { 'fpath': fpath, 'debug_value': bpy.app.debug_value, 'asset_data': asset_data, 'command': command, } binary_path = bpy.app.binary_path tempdir = tempfile.mkdtemp() datafile = os.path.join(tempdir + 'resdata.json') script_path = os.path.dirname(os.path.realpath(__file__)) with open(datafile, 'w') as s: json.dump(data, s) print('opening Blender instance to do processing - ', command) if wait: proc = subprocess.run([ binary_path, "--background", "-noaudio", fpath, "--python", os.path.join(script_path, "resolutions_bg.py"), "--", datafile ], bufsize=1, stdout=sys.stdout, stdin=subprocess.PIPE, creationflags=utils.get_process_flags()) else: # TODO this should be fixed to allow multithreading. proc = subprocess.Popen([ binary_path, "--background", "-noaudio", fpath, "--python", os.path.join(script_path, "resolutions_bg.py"), "--", datafile ], bufsize=1, stdout=subprocess.PIPE, stdin=subprocess.PIPE, creationflags=utils.get_process_flags()) return proc
def start_thumbnailer(self=None, json_args=None, props=None, wait=False, add_bg_process=True): # Prepare to save the file binary_path = bpy.app.binary_path script_path = os.path.dirname(os.path.realpath(__file__)) ext = '.blend' tfpath = paths.get_thumbnailer_filepath() datafile = os.path.join(json_args['tempdir'], BLENDERKIT_EXPORT_DATA_FILE) try: with open(datafile, 'w', encoding='utf-8') as s: json.dump(json_args, s, ensure_ascii=False, indent=4) proc = subprocess.Popen([ binary_path, "--background", "-noaudio", tfpath, "--python", os.path.join(script_path, "autothumb_model_bg.py"), "--", datafile, ], bufsize=1, stdout=subprocess.PIPE, stdin=subprocess.PIPE, creationflags=utils.get_process_flags()) eval_path_computing = "bpy.data.objects['%s'].blenderkit.is_generating_thumbnail" % json_args['asset_name'] eval_path_state = "bpy.data.objects['%s'].blenderkit.thumbnail_generating_state" % json_args['asset_name'] eval_path = "bpy.data.objects['%s']" % json_args['asset_name'] bg_blender.add_bg_process(name = f"{json_args['asset_name']} thumbnailer" ,eval_path_computing=eval_path_computing, eval_path_state=eval_path_state, eval_path=eval_path, process_type='THUMBNAILER', process=proc) except Exception as e: self.report({'WARNING'}, "Error while exporting file: %s" % str(e)) return {'FINISHED'}
def start_material_thumbnailer(self=None, json_args=None, props=None, wait=False, add_bg_process=True): ''' Parameters ---------- self json_args - all arguments: props - blenderkit upload props with thumbnail settings, to communicate back, if not present, not used. wait - wait for the rendering to finish Returns ------- ''' if props: props.is_generating_thumbnail = True props.thumbnail_generating_state = 'starting blender instance' binary_path = bpy.app.binary_path script_path = os.path.dirname(os.path.realpath(__file__)) tfpath = paths.get_material_thumbnailer_filepath() datafile = os.path.join(json_args['tempdir'], BLENDERKIT_EXPORT_DATA_FILE) try: with open(datafile, 'w', encoding='utf-8') as s: json.dump(json_args, s, ensure_ascii=False, indent=4) proc = subprocess.Popen([ binary_path, "--background", "-noaudio", tfpath, "--python", os.path.join(script_path, "autothumb_material_bg.py"), "--", datafile, ], bufsize=1, stdout=subprocess.PIPE, stdin=subprocess.PIPE, creationflags=utils.get_process_flags()) eval_path_computing = "bpy.data.materials['%s'].blenderkit.is_generating_thumbnail" % json_args['asset_name'] eval_path_state = "bpy.data.materials['%s'].blenderkit.thumbnail_generating_state" % json_args['asset_name'] eval_path = "bpy.data.materials['%s']" % json_args['asset_name'] bg_blender.add_bg_process(name=f"{json_args['asset_name']} thumbnailer", eval_path_computing=eval_path_computing, eval_path_state=eval_path_state, eval_path=eval_path, process_type='THUMBNAILER', process=proc) if props: props.thumbnail_generating_state = 'Saving .blend file' if wait: while proc.poll() is None: stdout_data, stderr_data = proc.communicate() print(stdout_data) except Exception as e: if self: self.report({'WARNING'}, "Error while packing file: %s" % str(e)) else: print(e) return {'FINISHED'}
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 run(self): # utils.pprint(upload_data) self.upload_data['parameters'] = utils.dict_to_params( self.upload_data['parameters']) # weird array conversion only for upload, not for tooltips. script_path = os.path.dirname(os.path.realpath(__file__)) # first upload metadata to server, so it can be saved inside the current file url = paths.get_api_url() + 'assets/' headers = utils.get_headers(self.upload_data['token']) # self.upload_data['license'] = 'ovejajojo' json_metadata = self.upload_data # json.dumps(self.upload_data, ensure_ascii=False).encode('utf8') # tasks_queue.add_task((ui.add_report, ('Posting metadata',))) self.send_message('Posting metadata') if self.export_data['assetBaseId'] == '': try: r = rerequests.post(url, json=json_metadata, headers=headers, verify=True, immediate=True) # files = files, # tasks_queue.add_task((ui.add_report, ('uploaded metadata',))) utils.p(r.text) self.send_message('uploaded metadata') except requests.exceptions.RequestException as e: print(e) self.end_upload(e) return {'CANCELLED'} else: url += self.export_data['id'] + '/' try: if 'MAINFILE' in self.upload_set: json_metadata["verificationStatus"] = "uploading" r = rerequests.patch(url, json=json_metadata, headers=headers, verify=True, immediate=True) # files = files, self.send_message('uploaded metadata') # tasks_queue.add_task((ui.add_report, ('uploaded metadata',))) # parse the request # print('uploaded metadata') print(r.text) except requests.exceptions.RequestException as e: print(e) self.end_upload(e) return {'CANCELLED'} if self.stopped(): self.end_upload('Upload cancelled by user') return # props.upload_state = 'step 1' if self.upload_set == ['METADATA']: self.end_upload('Metadata posted successfully') return {'FINISHED'} try: rj = r.json() utils.pprint(rj) # if r.status_code not in (200, 201): # if r.status_code == 401: # ###ui.add_report(r.detail, 5, colors.RED) # return {'CANCELLED'} # if props.asset_base_id == '': # props.asset_base_id = rj['assetBaseId'] # props.id = rj['id'] if self.export_data['assetBaseId'] == '': self.export_data['assetBaseId'] = rj['assetBaseId'] self.export_data['id'] = rj['id'] # here we need to send asset ID's back into UI to be written in asset data. estring = f"{self.export_data['eval_path']}.blenderkit.asset_base_id = '{rj['assetBaseId']}'" tasks_queue.add_task((exec, (estring,))) estring = f"{self.export_data['eval_path']}.blenderkit.id = '{rj['id']}'" tasks_queue.add_task((exec, (estring,))) # after that, the user's file needs to be saved to save the self.upload_data['assetBaseId'] = self.export_data['assetBaseId'] self.upload_data['id'] = self.export_data['id'] # props.uploading = True if 'MAINFILE' in self.upload_set: if self.upload_data['assetType'] == 'hdr': fpath = self.export_data['hdr_filepath'] else: fpath = os.path.join(self.export_data['temp_dir'], self.upload_data['assetBaseId'] + '.blend') clean_file_path = paths.get_clean_filepath() data = { 'export_data': self.export_data, 'upload_data': self.upload_data, 'debug_value': self.export_data['debug_value'], 'upload_set': self.upload_set, } datafile = os.path.join(self.export_data['temp_dir'], BLENDERKIT_EXPORT_DATA_FILE) with open(datafile, 'w') as s: json.dump(data, s) # non waiting method - not useful here.. # proc = subprocess.Popen([ # binary_path, # "--background", # "-noaudio", # clean_file_path, # "--python", os.path.join(script_path, "upload_bg.py"), # "--", datafile # ,filepath, tempdir # ], bufsize=5000, stdout=subprocess.PIPE, stdin=subprocess.PIPE) # tasks_queue.add_task((ui.add_report, ('preparing scene - running blender instance',))) self.send_message('preparing scene - running blender instance') proc = subprocess.run([ self.export_data['binary_path'], "--background", "-noaudio", clean_file_path, "--python", os.path.join(script_path, "upload_bg.py"), "--", datafile ], bufsize=1, stdout=sys.stdout, stdin=subprocess.PIPE, creationflags=utils.get_process_flags()) if self.stopped(): self.end_upload('Upload stopped by user') return files = [] if 'THUMBNAIL' in self.upload_set: files.append({ "type": "thumbnail", "index": 0, "file_path": self.export_data["thumbnail_path"] }) if 'MAINFILE' in self.upload_set: files.append({ "type": "blend", "index": 0, "file_path": fpath }) self.send_message('Uploading files') uploaded = upload_bg.upload_files(self.upload_data, files) if uploaded: # mark on server as uploaded if 'MAINFILE' in self.upload_set: confirm_data = { "verificationStatus": "uploaded" } url = paths.get_api_url() + 'assets/' headers = utils.get_headers(self.upload_data['token']) url += self.upload_data["id"] + '/' r = rerequests.patch(url, json=confirm_data, headers=headers, verify=True) # files = files, self.end_upload('Upload finished successfully') else: self.end_upload('Upload failed') except Exception as e: self.end_upload(e) print(e) return {'CANCELLED'}