def config_load(): from extensions_framework import util as efutil bpy.bls_selection_override_right = efutil.find_config_value( bl_info['name'], 'defaults', 'selection_override_right', True) bpy.bls_selection_override_left = efutil.find_config_value( bl_info['name'], 'defaults', 'selection_override_left', False) update_selection_override()
def get_selection_overriden(self): if not (hasattr(bpy, 'bls_selection_override_left') and hasattr(bpy, 'bls_selection_override_right')): bpy.bls_selection_override_left = efutil.find_config_value( bl_info['name'], 'defaults', 'selection_override_left', False) bpy.bls_selection_override_right = efutil.find_config_value( bl_info['name'], 'defaults', 'selection_override_right', True) return update_selection_override()
def find_luxrender_path(): return os.getenv( # Use the env var path, if set ... 'LUXRENDER_ROOT', # .. or load the last path from CFG file efutil.find_config_value('luxrender', 'defaults', 'install_path', '') )
class sunflow_renderconfigure(declarative_property_group): """ Sunflow render configurations panel. """ ef_attach_to = ['Scene'] controls = [ 'sunflowPath', 'javaPath', 'memoryAllocated', ] visibility = {} enabled = {} alert = {} properties = [ { 'type' : 'string', 'attr' : 'sunflowPath', 'subtype' : 'FILE_PATH', 'name' : 'Sunflow Path', 'description': 'Path to sunflow rendering system sunflow.jar file.', 'default' : efutil.find_config_value('sunflow', 'defaults', 'jar_path', ''), 'save_in_preset': True }, { 'type' : 'string', 'attr' : 'javaPath', 'subtype' : 'FILE_PATH', 'name' : 'Java Server Path', 'description': 'Path to Java.exe file of the server', 'default' : efutil.find_config_value('sunflow', 'defaults', 'java_path', ''), 'save_in_preset': True }, { 'type': 'string', 'attr': 'memoryAllocated', 'name': 'Memory (MB)', 'description': 'Memory allocated for running jar executable in MB. ', 'default': efutil.find_config_value('sunflow', 'defaults', 'memoryalloc', ''), 'save_in_preset': True }, ]
def find_luxrender_path(): from os import getenv from extensions_framework import util as efutil return getenv( # Use the env var path, if set ... 'LUXRENDER_ROOT', # .. or load the last path from CFG file efutil.find_config_value('luxrender', 'defaults', 'install_path', ''))
def find_luxrender_path(): from os import getenv from extensions_framework import util as efutil return getenv( # Use the env var path, if set ... 'LUXRENDER_ROOT', # .. or load the last path from CFG file efutil.find_config_value('luxrender', 'defaults', 'install_path', '') )
class luxrender_networking(declarative_property_group): ef_attach_to = ['Scene'] controls = [ 'servers', 'serverinterval' ] visibility = { 'servers': { 'use_network_servers': True }, 'serverinterval': { 'use_network_servers': True }, } properties = [ { # drawn in panel header 'type': 'bool', 'attr': 'use_network_servers', 'name': 'Use Networking', 'default': efutil.find_config_value('luxrender', 'defaults', 'use_network_servers', False), 'save_in_preset': True }, { 'type': 'string', 'attr': 'servers', 'name': 'Servers', 'description': 'Comma separated list of Lux server IP addresses', 'default': efutil.find_config_value('luxrender', 'defaults', 'servers', ''), 'save_in_preset': True }, { 'type': 'int', 'attr': 'serverinterval', 'name': 'Upload interval', 'description': 'Interval for server image transfers (seconds)', 'default': int(efutil.find_config_value('luxrender', 'defaults', 'serverinterval', '180')), 'min': 10, 'soft_min': 10, 'save_in_preset': True }, ]
def render(self, scene): if self is None or scene is None: sunflowLog('ERROR: Scene is missing!') return scene.render.use_placeholder = False with self.render_lock: # just render one thing at a time if scene.name == 'preview': self.render_preview(scene) return scene_path = efutil.filesystem_path(scene.render.filepath) if os.path.isdir(scene_path): output_dir = scene_path else: output_dir = os.path.dirname(scene_path) output_dir = os.path.abspath(os.path.join(output_dir , efutil.scene_filename())) if not os.path.exists(output_dir): os.mkdir(output_dir) #----------- sunflowLog('Sunflow: Current directory = "%s"' % output_dir) #--------------------------------------- if DEBUG: pydevd.settrace() if not getExporter (output_dir, scene.name, scene.frame_current): return if self.is_animation: return arguments = self.getCommandLineArgs(scene) jarpath = efutil.find_config_value('sunflow', 'defaults', 'jar_path', '') javapath = efutil.find_config_value('sunflow', 'defaults', 'java_path', '') memory = "-Xmx%sm" % efutil.find_config_value('sunflow', 'defaults', 'memoryalloc', '') image_name = "%s.%03d.%s" % (scene.name , scene.frame_current, arguments['format']) if scene.sunflow_performance.useRandom: image_name = self.check_randomname(output_dir, image_name) sunflow_file = "%s.%03d.sc" % (scene.name , scene.frame_current) image_file = os.path.abspath(os.path.join(output_dir , image_name)) sc_file_path = os.path.abspath(os.path.join(output_dir , sunflow_file)) cmd_line = [ javapath , memory , '-server' , '-jar' , jarpath ] final_line = ['-o', image_file , sc_file_path] extra = [] for key in arguments: if key == 'format': continue if arguments[key] != '': values = arguments[key].split() extra.extend(values) if arguments['format'] != 'png': extra.append('-nogui') cmd_line.extend(extra) cmd_line.extend(final_line) sunflow_process = subprocess.Popen(cmd_line) refresh_interval = 5 framebuffer_thread = sunflowFilmDisplay() framebuffer_thread.set_kick_period(refresh_interval) framebuffer_thread.begin(self, image_file, resolution(scene)) render_update_timer = None while sunflow_process.poll() == None and not self.test_break(): render_update_timer = threading.Timer(1, self.process_wait_timer) render_update_timer.start() if render_update_timer.isAlive(): render_update_timer.join() # If we exit the wait loop (user cancelled) and sunflow is still running, then send SIGINT if sunflow_process.poll() == None: # Use SIGTERM because that's the only one supported on Windows sunflow_process.send_signal(subprocess.signal.SIGTERM) # Stop updating the render result and load the final image framebuffer_thread.stop() framebuffer_thread.join() if sunflow_process.poll() != None and sunflow_process.returncode != 0: sunflowLog("Sunflow: Rendering failed -- check the console") else: framebuffer_thread.kick(render_end=True) framebuffer_thread.shutdown()
def render_preview(self, scene): (width, height) = resolution(scene) if (width < 96 or height < 96): return objects_materials = {} for object_ in [ob for ob in scene.objects if ob.is_visible(scene) and not ob.hide_render]: for mat in get_instance_materials(object_): if mat is not None: if not object_.name in objects_materials.keys(): objects_materials[object_] = [] objects_materials[object_].append(mat) # find objects that are likely to be the preview objects preview_objects = [o for o in objects_materials.keys() if o.name.startswith('preview')] if len(preview_objects) < 1: return # find the materials attached to the likely preview object likely_materials = objects_materials[preview_objects[0]] if len(likely_materials) < 1: return tempdir = efutil.temp_directory() scenefile = os.path.abspath(os.path.join(tempdir, "Scene.sc")) outfile = os.path.abspath(os.path.join(tempdir, "matpreview.png")) matfile = os.path.abspath(os.path.join(tempdir, "ObjectMaterial.mat.sc")) pm = likely_materials[0] mat_dic = create_shader_block(pm) linenum = 0 found = False if (('Shader' in mat_dic.keys()) and (len(mat_dic['Shader']) > 0)): for eachline in mat_dic['Shader']: if eachline.find(' name "') >= 0 : found = True break linenum += 1 if not found: return matgot = mat_dic['Shader'][:] matgot[1] = ' name "ObjectMaterial"' out_write = [] out_write.append('image {') out_write.append('resolution %s %s' % (width, height)) out_write.append('aa 0 1 samples 4 filter mitchell jitter False } ') out_write.extend(matgot) fi = open(matfile , 'w') [ fi.write("\n%s " % line) for line in out_write] fi.close() src = os.path.join(plugin_path() , "preview", 'SceneFloorUVgrid.png') shutil.copy(src, tempdir) src = os.path.join(plugin_path() , "preview", 'Scene.sc') shutil.copy(src, tempdir) jarpath = efutil.find_config_value('sunflow', 'defaults', 'jar_path', '') javapath = efutil.find_config_value('sunflow', 'defaults', 'java_path', '') memory = "-Xmx%sm" % efutil.find_config_value('sunflow', 'defaults', 'memoryalloc', '') cmd_line = [ javapath , memory , '-server' , '-jar' , jarpath , '-nogui', '-v', '0', '-o', outfile , scenefile ] sunflow_process = subprocess.Popen(cmd_line) framebuffer_thread = sunflowFilmDisplay() framebuffer_thread.set_kick_period(2) framebuffer_thread.begin(self, outfile, resolution(scene)) render_update_timer = None while sunflow_process.poll() == None and not self.test_break(): render_update_timer = threading.Timer(1, self.process_wait_timer) render_update_timer.start() if render_update_timer.isAlive(): render_update_timer.join() # If we exit the wait loop (user cancelled) and sunflow is still running, then send SIGINT if sunflow_process.poll() == None: # Use SIGTERM because that's the only one supported on Windows sunflow_process.send_signal(subprocess.signal.SIGTERM) # Stop updating the render result and load the final image framebuffer_thread.stop() framebuffer_thread.join() if sunflow_process.poll() != None and sunflow_process.returncode != 0: sunflowLog("Sunflow: Rendering failed -- check the console") else: framebuffer_thread.kick(render_end=True) framebuffer_thread.shutdown()
# 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, see <http://www.gnu.org/licenses/>. # # ***** END GPL LICENCE BLOCK ***** # import collections, xml.etree.cElementTree as ET, time, os from extensions_framework import log, util as efutil REPORTER = None PRINT_CONSOLE = efutil.find_config_value('indigo', 'defaults', 'console_output', False) OBJECT_ANALYSIS = os.getenv('B25_OBJECT_ANALYSIS', False) def indigo_log(message, popup=False, message_type='INFO'): global REPORTER, PRINT_CONSOLE if REPORTER == None or PRINT_CONSOLE: log('%s: %s' % (message_type, message), popup, module_name='Indigo') else: REPORTER({message_type}, '[Indigo %s] %s' % (time.strftime('%Y-%b-%d %H:%M:%S'), message)) class xml_cdata(str): pass class xml_multichild(list): pass
def render_preview(self, scene): # Iterate through the preview scene, finding objects with materials attached objects_materials = {} (width, height) = resolution(scene) if (width, height) == (96, 96): return MtsLog('Preview Render Res: {0}'.format(width, height)) for object in [ob for ob in scene.objects if ob.is_visible(scene) and not ob.hide_render]: for mat in get_instance_materials(object): if mat is not None: if not object.name in objects_materials.keys(): objects_materials[object] = [] objects_materials[object].append(mat) # find objects that are likely to be the preview objects preview_objects = [o for o in objects_materials.keys() if o.name.startswith('preview')] if len(preview_objects) < 1: return # find the materials attached to the likely preview object likely_materials = objects_materials[preview_objects[0]] if len(likely_materials) < 1: return tempdir = efutil.temp_directory() matfile = "matpreview_materials.xml" output_file = os.path.join(tempdir, "matpreview.png") scene_file = os.path.join(os.path.join(plugin_path(), "matpreview"), "matpreview.xml") MtsLog('Scene path: %s'%scene_file) pm = likely_materials[0] exporter = SceneExporter(tempdir, matfile, bpy.data.materials, bpy.data.textures) exporter.adj_filename = os.path.join(tempdir, matfile) if not exporter.writeHeader(): MtsLog('Error while exporting -- check the console for details.') return; exporter.exportMaterial(pm) exporter.exportPreviewMesh(scene, pm) exporter.writeFooter() refresh_interval = 2 preview_spp = int(efutil.find_config_value('mitsuba', 'defaults', 'preview_spp', '16')) preview_depth = int(efutil.find_config_value('mitsuba', 'defaults', 'preview_depth', '2')) mitsuba_process = MtsLaunch(scene.mitsuba_engine.binary_path, tempdir, ['mitsuba', '-q', '-r%i' % refresh_interval, '-b16', '-Dmatfile=%s' % os.path.join(tempdir, matfile), '-Dwidth=%i' % width, '-Dheight=%i' % height, '-Dspp=%i' % preview_spp, '-Ddepth=%i' % preview_depth, '-o', output_file, scene_file], ) framebuffer_thread = MtsFilmDisplay() framebuffer_thread.set_kick_period(refresh_interval) framebuffer_thread.begin(self, output_file, resolution(scene), preview=True) render_update_timer = None while mitsuba_process.poll() == None and not self.test_break(): render_update_timer = threading.Timer(1, self.process_wait_timer) render_update_timer.start() if render_update_timer.isAlive(): render_update_timer.join() cancelled = False # If we exit the wait loop (user cancelled) and mitsuba is still running, then send SIGINT if mitsuba_process.poll() == None: MtsLog("MtsBlend: Terminating process..") # Use SIGTERM because that's the only one supported on Windows mitsuba_process.send_signal(subprocess.signal.SIGTERM) cancelled = True # Stop updating the render result and load the final image framebuffer_thread.stop() framebuffer_thread.join() if not cancelled: if mitsuba_process.poll() != None and mitsuba_process.returncode != 0: MtsLog("MtsBlend: Rendering failed -- check the console"); mitsuba_process.send_signal(subprocess.signal.SIGTERM) #fixes mitsuba preview not refresing after bad eg. reference else: framebuffer_thread.kick(render_end=True) framebuffer_thread.shutdown()
def find_indigo(): rp = getInstallPath() if rp != "": return getInstallPath() return efutil.find_config_value('indigo', 'defaults', 'install_path', '')
def render_preview(self, scene): # Iterate through the preview scene, finding objects with materials attached objects_materials = {} (width, height) = resolution(scene) if (width, height) == (96, 96): return MtsLog('Preview Render Res: {0}'.format(width, height)) for object in [ ob for ob in scene.objects if ob.is_visible(scene) and not ob.hide_render ]: for mat in get_instance_materials(object): if mat is not None: if not object.name in objects_materials.keys(): objects_materials[object] = [] objects_materials[object].append(mat) # find objects that are likely to be the preview objects preview_objects = [ o for o in objects_materials.keys() if o.name.startswith('preview') ] if len(preview_objects) < 1: return # find the materials attached to the likely preview object likely_materials = objects_materials[preview_objects[0]] if len(likely_materials) < 1: return tempdir = efutil.temp_directory() matfile = "matpreview_materials.xml" output_file = os.path.join(tempdir, "matpreview.png") scene_file = os.path.join(os.path.join(plugin_path(), "matpreview"), "matpreview.xml") MtsLog('Scene path: %s' % scene_file) pm = likely_materials[0] exporter = SceneExporter(tempdir, matfile, bpy.data.materials, bpy.data.textures) exporter.adj_filename = os.path.join(tempdir, matfile) if not exporter.writeHeader(): MtsLog('Error while exporting -- check the console for details.') return exporter.exportMaterial(pm) exporter.exportPreviewMesh(scene, pm) exporter.writeFooter() refresh_interval = 2 preview_spp = int( efutil.find_config_value('mitsuba', 'defaults', 'preview_spp', '16')) preview_depth = int( efutil.find_config_value('mitsuba', 'defaults', 'preview_depth', '2')) mitsuba_process = MtsLaunch( scene.mitsuba_engine.binary_path, tempdir, [ 'mitsuba', '-q', '-r%i' % refresh_interval, '-b16', '-Dmatfile=%s' % os.path.join(tempdir, matfile), '-Dwidth=%i' % width, '-Dheight=%i' % height, '-Dspp=%i' % preview_spp, '-Ddepth=%i' % preview_depth, '-o', output_file, scene_file ], ) framebuffer_thread = MtsFilmDisplay() framebuffer_thread.set_kick_period(refresh_interval) framebuffer_thread.begin(self, output_file, resolution(scene), preview=True) render_update_timer = None while mitsuba_process.poll() == None and not self.test_break(): render_update_timer = threading.Timer(1, self.process_wait_timer) render_update_timer.start() if render_update_timer.isAlive(): render_update_timer.join() cancelled = False # If we exit the wait loop (user cancelled) and mitsuba is still running, then send SIGINT if mitsuba_process.poll() == None: MtsLog("MtsBlend: Terminating process..") # Use SIGTERM because that's the only one supported on Windows mitsuba_process.send_signal(subprocess.signal.SIGTERM) cancelled = True # Stop updating the render result and load the final image framebuffer_thread.stop() framebuffer_thread.join() if not cancelled: if mitsuba_process.poll( ) != None and mitsuba_process.returncode != 0: MtsLog("MtsBlend: Rendering failed -- check the console") mitsuba_process.send_signal( subprocess.signal.SIGTERM ) #fixes mitsuba preview not refresing after bad eg. reference else: framebuffer_thread.kick(render_end=True) framebuffer_thread.shutdown()
def find_indigo(): rp = getInstallPath() if rp != "": return getInstallPath() return find_config_value(getAddonDir(), 'defaults', 'install_path', '')
class indigo_engine(declarative_property_group, indigo.export.xml_builder): ef_attach_to = ['Scene'] # declarative_property_group members controls = [ # Process options 'use_output_path', 'export_path', 'install_path', 'auto_start', ['threads_auto', 'threads'], # Output options ['save_igi', 'save_exr_tm', 'save_exr_utm'], ['ov_info', 'ov_watermark', 'logging'], ['halttime', 'haltspp'], 'skip_existing_meshes', 'period_save', # Render settings 'motionblur', 'foreground_alpha', 'render_mode', 'alpha_mask', 'material_id', 'metro', 'bidir', #'hybrid' 'gpu', 'shadow', # Filtering 'filter_preset', 'splat_filter', ['splat_filter_blur', 'splat_filter_ring'], 'ds_filter', ['ds_filter_blur', 'ds_filter_ring', 'ds_filter_radius'], ['supersample', 'bih_tri_threshold'], # Networking 'network_mode', 'network_host', 'network_port', 'console_output' ] visibility = { 'alpha_mask': { 'render_mode': 'custom' }, 'material_id': { 'render_mode': 'custom' }, 'metro': { 'render_mode': 'custom' }, 'bidir': { 'render_mode': 'custom' }, 'gpu': { 'render_mode': 'custom' }, 'shadow': { 'render_mode': 'custom' }, 'splat_filter': { 'filter_preset': 'custom' }, 'ds_filter': { 'filter_preset': 'custom' }, 'splat_filter_blur': { 'filter_preset': 'custom', 'splat_filter': 'mitchell' }, 'splat_filter_ring': { 'filter_preset': 'custom', 'splat_filter': 'mitchell' }, 'ds_filter_blur': { 'filter_preset': 'custom', 'ds_filter': 'mitchell' }, 'ds_filter_ring': { 'filter_preset': 'custom', 'ds_filter': 'mitchell' }, 'ds_filter_radius': { 'filter_preset': 'custom', 'ds_filter': 'mitchell' }, 'supersample': { 'filter_preset': 'custom' }, 'bih_tri_threshold': { 'filter_preset': 'custom' }, 'network_host': { 'network_mode': 'manual' }, 'network_port': { 'network_mode': O(['master', 'working_master', 'manual']) }, } enabled = { 'threads': { 'threads_auto': False }, 'export_path': { 'use_output_path': False }, } def set_export_console_output(self, context): indigo.export.PRINT_CONSOLE = self.console_output efutil.write_config_value('indigo', 'defaults', 'console_output', self.console_output) properties = [ { 'type': 'bool', 'attr': 'use_output_path', 'name': 'Use output directory for .igs files', 'description': 'Use the directory specified under Output to write the scene files to. When disabled the .igs export path can be customised below', 'default': True }, { 'type': 'string', 'subtype': 'FILE_PATH', 'attr': 'export_path', 'name': 'Scene (.igs) export path', 'description': 'Directory/name to save Indigo scene files. # characters define location and length of frame numbers', 'default': bpy.app.tempdir }, { 'type': 'string', 'subtype': 'DIR_PATH', 'attr': 'install_path', 'name': 'Path to Indigo installation', 'description': 'Location of Indigo', 'default': find_indigo() }, { # Internal var use for regression testing 'type': 'bool', 'attr': 'wait_for_process', 'default': False }, { # Internal var use for regression testing 'type': 'bool', 'attr': 'use_console', 'default': False }, { # Internal var use for regression testing 'type': 'bool', 'attr': 'skip_version_check', 'default': False }, { 'type': 'bool', 'attr': 'auto_start', 'name': 'Auto Start', 'description': 'Auto start Indigo after export', 'default': efutil.find_config_value('indigo', 'defaults', 'auto_start', True) }, { 'type': 'enum', 'attr': 'render_mode', 'name': 'Rendering Mode', 'description': 'Choose the rendering mode to use', 'items': [('bidir', 'BiDir (CPU)', 'Bidirectional Path Tracing on the CPU'), ('bidir_mlt', 'BiDir MLT (CPU)', 'Bidirectional Path Tracing with Metropolis Light Transport on the CPU' ), ('path_cpu', 'Path (CPU)', 'Path Tracing on the CPU'), ('path_gpu', 'Path (GPU)', 'GPU accelerated Path Tracing'), ('alpha', 'Alpha Mask', 'Render an alpha mask for compositing'), ('material_id', 'Material ID', 'Render materials as unique flat colours for compositing'), ('shadow', 'Shadow Pass', 'Render shadow pass for compositing'), ('custom', 'Custom', 'Choose your own settings')], 'default': 'bidir', 'update': set_render_mode }, { 'type': 'bool', 'attr': 'gpu', 'name': 'GPU rendering', 'description': 'Use the GPU to accelerate rendering', 'default': False }, { 'type': 'bool', 'attr': 'alpha_mask', 'name': 'Alpha Mask', 'description': 'Enable Alpha Mask Rendering', 'default': False, }, { 'type': 'bool', 'attr': 'material_id', 'name': 'Material ID', 'description': 'Enable Material ID Rendering', 'default': False, }, { 'type': 'bool', 'attr': 'metro', 'name': 'Metropolis', 'description': 'Enable Metropolis Light Transport', 'default': False }, { 'type': 'bool', 'attr': 'shadow', 'name': 'Shadow Pass', 'description': 'Enable Shadow Pass Rendering', 'default': False }, { 'type': 'bool', 'attr': 'bidir', 'name': 'Bi-Directional', 'description': 'Enable Bi-Directional Tracing', 'default': True }, { 'type': 'bool', 'attr': 'hybrid', 'name': 'Hybrid', 'description': 'Enable Hybrid Metropolis/Path', 'default': False }, { 'type': 'bool', 'attr': 'motionblur', 'name': 'Motion Blur', 'description': 'Enable Motion Blur', 'default': False }, { 'type': 'bool', 'attr': 'logging', 'name': 'Logging', 'description': 'Enable Logging to Text File', 'default': False }, { 'type': 'bool', 'attr': 'ov_info', 'name': 'Info Overlay', 'description': 'Enable Info Overlay on Render', 'default': False }, { 'type': 'bool', 'attr': 'ov_watermark', 'name': 'Watermark', 'description': 'Enable Indigo watermark on Render', 'default': False }, { 'type': 'bool', 'attr': 'threads_auto', 'name': 'Auto Threads', 'description': 'Let Indigo decide how many threads to use', 'default': True }, { 'type': 'int', 'attr': 'threads', 'name': 'Render Threads', 'description': 'Number of threads to use', 'default': 1, 'min': 1, 'soft_min': 1, 'max': 64, 'soft_max': 64 }, { 'type': 'bool', 'attr': 'save_exr_utm', 'name': 'Save Raw EXR', 'description': 'Save Raw (un-tonemapped) EXR format', 'default': False }, { 'type': 'bool', 'attr': 'save_exr_tm', 'name': 'Save EXR', 'description': 'Save (tonemapped) EXR format', 'default': False }, { 'type': 'bool', 'attr': 'save_igi', 'name': 'Save IGI', 'description': 'Save native IGI format', 'default': False }, { 'type': 'int', 'attr': 'halttime', 'name': 'Halt Time', 'description': 'Number of seconds to run rendering (-1 == disable)', 'default': -1, 'min': -1, 'soft_min': -1, 'max': 86400, 'soft_max': 86400 }, { 'type': 'int', 'attr': 'haltspp', 'name': 'Halt Samples/px', 'description': 'Number of samples/px to run rendering (-1 == disable)', 'default': -1, 'min': -1, 'soft_min': -1, 'max': 64000, 'soft_max': 64000 }, { 'type': 'bool', 'attr': 'skip_existing_meshes', 'name': 'Skip writing existing meshes', 'default': False, }, { 'type': 'int', 'attr': 'period_save', 'name': 'Save interval', 'description': 'Number of seconds to save output', 'default': 60, 'min': 20, 'soft_min': 20, 'max': 86400, 'soft_max': 86400 }, { 'type': 'bool', 'attr': 'foreground_alpha', 'name': 'Foreground Alpha', 'default': False, }, { 'type': 'enum', 'attr': 'filter_preset', 'name': 'Filtering', 'description': 'Filtering methods to use; affects image sharpness', 'items': [('default', 'Default', 'Prevents black edges, good overall performance - Splat: fastbox; Downsize: mn_cubic' ), ('crisp', 'Crisp', 'Splat: fastbox; Downsize: mn_cubic'), ('strong', 'Strong', 'Splat: radial; Downsize: sharp'), ('custom', 'Custom', 'Choose your own settings')], 'default': 'default', 'update': set_filter_preset }, { 'type': 'enum', 'attr': 'splat_filter', 'name': 'Splat', 'description': 'Splat Filter Type', 'default': 'fastbox', 'items': [ ('mitchell', 'Mitchell-Netraveli', 'mitchell'), ('gaussian', 'Gaussian', 'gaussian'), ('box', 'Box', 'box'), ('fastbox', 'Fast Box', 'fastbox'), ('radial', 'Radial', 'radial'), # ('sharp', 'Sharp', 'sharp') ] }, { 'type': 'float', 'attr': 'splat_filter_blur', 'name': 'Splat Blur', 'description': 'Splat Mitchell Filter Blur Amount', 'default': 1.0, 'min': 0, 'soft_min': 0, 'max': 1, 'soft_max': 1, }, { 'type': 'float', 'attr': 'splat_filter_ring', 'name': 'Splat Ring', 'description': 'Splat Mitchell Filter Ring Amount', 'default': 0.0, 'min': 0, 'soft_min': 0, 'max': 1, 'soft_max': 1, }, { 'type': 'enum', 'attr': 'ds_filter', 'name': 'Downsize', 'description': 'Downsize Filter Type', 'default': 'mitchell', 'items': [('mitchell', 'Mitchell-Netraveli', 'mitchell'), ('gaussian', 'Gaussian', 'gaussian'), ('box', 'Box', 'box'), ('radial', 'Radial', 'radial'), ('sharp', 'Sharp', 'sharp')] }, { 'type': 'float', 'attr': 'ds_filter_blur', 'name': 'Downsize Blur', 'description': 'Downsize Mitchell Filter Blur Amount', 'default': 1.0, 'min': 0, 'soft_min': 0, 'max': 1, 'soft_max': 1, }, { 'type': 'float', 'attr': 'ds_filter_ring', 'name': 'Downsize Ring', 'description': 'Downsize Mitchell Filter Ring Amount', 'default': 0.0, 'min': 0, 'soft_min': 0, 'max': 1, 'soft_max': 1, }, { 'type': 'float', 'attr': 'ds_filter_radius', 'name': 'Downsize Radius', 'description': 'Downsize Mitchell Filter Radius Amount', 'default': 1.65, 'min': 1, 'soft_min': 1, 'max': 3, 'soft_max': 3, }, { 'type': 'int', 'attr': 'supersample', 'name': 'Supersamples', 'description': 'x Oversampling', 'default': 2, 'min': 1, 'soft_min': 1, 'max': 4, 'soft_max': 4, }, { 'type': 'int', 'attr': 'bih_tri_threshold', 'name': 'BIH Tri Threshold', 'description': 'BIH Tri Threshold', 'default': 1100000, 'min': 1, 'soft_min': 1, 'max': 10000000, 'soft_max': 10000000, }, { 'type': 'enum', 'attr': 'network_mode', 'name': 'Network mode', 'default': 'off', 'items': [ ('off', 'Off', 'Do not use networking'), ('master', 'Master', 'Start Indigo as a Master node (doesn\'t render)'), ('working_master', 'Working Master', 'Start Indigo as a Working Master node'), # ('manual', 'Manual', 'Connect manually to a running slave') ] }, { 'type': 'string', 'attr': 'network_host', 'name': 'Slave IP/hostname', 'description': 'IP address or hostname of running slave' }, { 'type': 'int', 'attr': 'network_port', 'name': 'Network port', 'description': 'Network render port use', 'default': 7100, 'min': 1025, 'soft_min': 1025, 'max': 32768, 'soft_max': 32768 }, { 'type': 'bool', 'attr': 'console_output', 'name': 'Print export progress to console', 'default': efutil.find_config_value('indigo', 'defaults', 'console_output', False), 'update': set_export_console_output }, ] # xml_builder members def build_xml_element(self, scene): xml = self.Element('scene') xres = scene.render.resolution_x * scene.render.resolution_percentage // 100 yres = scene.render.resolution_y * scene.render.resolution_percentage // 100 xml_format = { 'metadata': { 'created_date': [time.strftime('%Y-%m-%d %H:%M:%S GMT', time.gmtime())], 'exporter': [ 'Blendigo ' + '.'.join(['%i' % v for v in bl_info['version']]) ], 'platform': [ '%s - %s - Python %s' % (PlatformInformation.platform_id, PlatformInformation.uname, PlatformInformation.python) ], 'author': [PlatformInformation.user], }, 'renderer_settings': { 'width': [xres], 'height': [yres], 'bih_tri_threshold': 'bih_tri_threshold', 'metropolis': 'metro', 'logging': 'logging', 'bidirectional': 'bidir', 'save_untonemapped_exr': 'save_exr_utm', 'save_tonemapped_exr': 'save_exr_tm', 'save_igi': 'save_igi', 'image_save_period': 'period_save', 'halt_time': 'halttime', 'halt_samples_per_pixel': 'haltspp', 'hybrid': 'hybrid', 'super_sample_factor': 'supersample', 'watermark': 'ov_watermark', 'info_overlay': 'ov_info', 'aperture_diffraction': [str(scene.camera.data.indigo_camera.ad).lower()], 'vignetting': [str(scene.camera.data.indigo_camera.vignetting).lower()], 'post_process_diffraction': [str(scene.camera.data.indigo_camera.ad_post).lower()], 'render_foreground_alpha': 'alpha_mask', 'material_id_tracer': 'material_id', 'shadow_pass': '******', 'gpu': 'gpu' }, } # Auto threads setting xml_format['renderer_settings'][ 'auto_choose_num_threads'] = 'threads_auto' if not self.threads_auto: xml_format['renderer_settings']['num_threads'] = 'threads' if self.foreground_alpha: xml_format['renderer_settings']['render_foreground_alpha'] = [ 'true' ] # Make splat filter element if self.splat_filter in ['box', 'gaussian', 'fastbox']: xml_format['renderer_settings']['splat_filter'] = { self.splat_filter: '' } # generate an empty element elif self.splat_filter == 'mitchell': xml_format['renderer_settings']['splat_filter'] = { 'mn_cubic': { 'blur': 'splat_filter_blur', 'ring': 'splat_filter_ring' } } # Make downsize filter element if self.ds_filter in ['box', 'gaussian']: xml_format['renderer_settings']['downsize_filter'] = { self.ds_filter: '' } # generate an empty element elif self.ds_filter == 'mitchell': xml_format['renderer_settings']['downsize_filter'] = { 'mn_cubic': { 'blur': 'ds_filter_blur', 'ring': 'ds_filter_ring', 'radius': 'ds_filter_radius' } } # Region rendering if scene.render.use_border: x1 = int(xres * scene.render.border_min_x) y1 = int(yres - (yres * scene.render.border_max_y)) x2 = int(xres * scene.render.border_max_x) y2 = int(yres - (yres * scene.render.border_min_y)) xml_format['renderer_settings']['render_region'] = { 'x1': [x1], 'x2': [x2], 'y1': [y1], 'y2': [y2] } self.build_subelements(scene, xml_format, xml) return xml
'type': 'bool', 'attr': 'use_console', 'default': False }, { # Internal var use for regression testing 'type': 'bool', 'attr': 'skip_version_check', 'default': False }, { 'type': 'bool', 'attr': 'auto_start', 'name': 'Auto Start', 'description': 'Auto start Indigo after export', 'default': find_config_value(getAddonDir(), 'defaults', 'auto_start', True) }, { 'type': 'enum', 'attr': 'render_mode', 'name': 'Rendering Mode', 'description': 'Choose the rendering mode to use', 'items': [('bidir', 'BiDir (CPU)', 'Bidirectional Path Tracing on the CPU'), ('bidir_mlt', 'BiDir MLT (CPU)', 'Bidirectional Path Tracing with Metropolis Light Transport on the CPU' ), ('path_cpu', 'Path (CPU)', 'Path Tracing on the CPU'),
def render(self, scene): if self is None or scene is None: sunflowLog('ERROR: Scene is missing!') return scene.render.use_placeholder = False with self.render_lock: # just render one thing at a time if scene.name == 'preview': self.render_preview(scene) return scene_path = efutil.filesystem_path(scene.render.filepath) if os.path.isdir(scene_path): output_dir = scene_path else: output_dir = os.path.dirname(scene_path) output_dir = os.path.abspath( os.path.join(output_dir, efutil.scene_filename())) if not os.path.exists(output_dir): os.mkdir(output_dir) #----------- sunflowLog('Sunflow: Current directory = "%s"' % output_dir) #--------------------------------------- if DEBUG: pydevd.settrace() if not getExporter(output_dir, scene.name, scene.frame_current): return if self.is_animation: return arguments = self.getCommandLineArgs(scene) jarpath = efutil.find_config_value('sunflow', 'defaults', 'jar_path', '') javapath = efutil.find_config_value('sunflow', 'defaults', 'java_path', '') memory = "-Xmx%sm" % efutil.find_config_value( 'sunflow', 'defaults', 'memoryalloc', '') image_name = "%s.%03d.%s" % (scene.name, scene.frame_current, arguments['format']) if scene.sunflow_performance.useRandom: image_name = self.check_randomname(output_dir, image_name) sunflow_file = "%s.%03d.sc" % (scene.name, scene.frame_current) image_file = os.path.abspath(os.path.join(output_dir, image_name)) sc_file_path = os.path.abspath( os.path.join(output_dir, sunflow_file)) cmd_line = [javapath, memory, '-server', '-jar', jarpath] final_line = ['-o', image_file, sc_file_path] extra = [] for key in arguments: if key == 'format': continue if arguments[key] != '': values = arguments[key].split() extra.extend(values) if arguments['format'] != 'png': extra.append('-nogui') cmd_line.extend(extra) cmd_line.extend(final_line) sunflow_process = subprocess.Popen(cmd_line) refresh_interval = 5 framebuffer_thread = sunflowFilmDisplay() framebuffer_thread.set_kick_period(refresh_interval) framebuffer_thread.begin(self, image_file, resolution(scene)) render_update_timer = None while sunflow_process.poll() == None and not self.test_break(): render_update_timer = threading.Timer(1, self.process_wait_timer) render_update_timer.start() if render_update_timer.isAlive(): render_update_timer.join() # If we exit the wait loop (user cancelled) and sunflow is still running, then send SIGINT if sunflow_process.poll() == None: # Use SIGTERM because that's the only one supported on Windows sunflow_process.send_signal(subprocess.signal.SIGTERM) # Stop updating the render result and load the final image framebuffer_thread.stop() framebuffer_thread.join() if sunflow_process.poll( ) != None and sunflow_process.returncode != 0: sunflowLog("Sunflow: Rendering failed -- check the console") else: framebuffer_thread.kick(render_end=True) framebuffer_thread.shutdown()
def render_preview(self, scene): (width, height) = resolution(scene) if (width < 96 or height < 96): return objects_materials = {} for object_ in [ ob for ob in scene.objects if ob.is_visible(scene) and not ob.hide_render ]: for mat in get_instance_materials(object_): if mat is not None: if not object_.name in objects_materials.keys(): objects_materials[object_] = [] objects_materials[object_].append(mat) # find objects that are likely to be the preview objects preview_objects = [ o for o in objects_materials.keys() if o.name.startswith('preview') ] if len(preview_objects) < 1: return # find the materials attached to the likely preview object likely_materials = objects_materials[preview_objects[0]] if len(likely_materials) < 1: return tempdir = efutil.temp_directory() scenefile = os.path.abspath(os.path.join(tempdir, "Scene.sc")) outfile = os.path.abspath(os.path.join(tempdir, "matpreview.png")) matfile = os.path.abspath( os.path.join(tempdir, "ObjectMaterial.mat.sc")) pm = likely_materials[0] mat_dic = create_shader_block(pm) linenum = 0 found = False if (('Shader' in mat_dic.keys()) and (len(mat_dic['Shader']) > 0)): for eachline in mat_dic['Shader']: if eachline.find(' name "') >= 0: found = True break linenum += 1 if not found: return matgot = mat_dic['Shader'][:] matgot[1] = ' name "ObjectMaterial"' out_write = [] out_write.append('image {') out_write.append('resolution %s %s' % (width, height)) out_write.append( 'aa 0 1 samples 4 filter mitchell jitter False } ' ) out_write.extend(matgot) fi = open(matfile, 'w') [fi.write("\n%s " % line) for line in out_write] fi.close() src = os.path.join(plugin_path(), "preview", 'SceneFloorUVgrid.png') shutil.copy(src, tempdir) src = os.path.join(plugin_path(), "preview", 'Scene.sc') shutil.copy(src, tempdir) jarpath = efutil.find_config_value('sunflow', 'defaults', 'jar_path', '') javapath = efutil.find_config_value('sunflow', 'defaults', 'java_path', '') memory = "-Xmx%sm" % efutil.find_config_value('sunflow', 'defaults', 'memoryalloc', '') cmd_line = [ javapath, memory, '-server', '-jar', jarpath, '-nogui', '-v', '0', '-o', outfile, scenefile ] sunflow_process = subprocess.Popen(cmd_line) framebuffer_thread = sunflowFilmDisplay() framebuffer_thread.set_kick_period(2) framebuffer_thread.begin(self, outfile, resolution(scene)) render_update_timer = None while sunflow_process.poll() == None and not self.test_break(): render_update_timer = threading.Timer(1, self.process_wait_timer) render_update_timer.start() if render_update_timer.isAlive(): render_update_timer.join() # If we exit the wait loop (user cancelled) and sunflow is still running, then send SIGINT if sunflow_process.poll() == None: # Use SIGTERM because that's the only one supported on Windows sunflow_process.send_signal(subprocess.signal.SIGTERM) # Stop updating the render result and load the final image framebuffer_thread.stop() framebuffer_thread.join() if sunflow_process.poll() != None and sunflow_process.returncode != 0: sunflowLog("Sunflow: Rendering failed -- check the console") else: framebuffer_thread.kick(render_end=True) framebuffer_thread.shutdown()
class luxrender_engine(declarative_property_group): ''' Storage class for LuxRender Engine settings. ''' ef_attach_to = ['Scene'] controls = [ # 'export_type', # 'binary_name', # 'write_files', # 'install_path', ['write_lxv', 'embed_filedata'], 'mesh_type', 'partial_ply', ['render', 'monitor_external'], ['threads_auto', 'fixed_seed'], 'threads', 'log_verbosity', ] visibility = { 'write_files': { 'export_type': 'INT' }, #'write_lxv': O([ {'export_type':'EXT'}, A([ {'export_type':'INT'}, {'write_files': True} ]) ]), 'embed_filedata': O([ {'export_type':'EXT'}, A([ {'export_type':'INT'}, {'write_files': True} ]) ]), 'mesh_type': O([ {'export_type':'EXT'}, A([ {'export_type':'INT'}, {'write_files': True} ]) ]), 'binary_name': { 'export_type': 'EXT' }, 'render': O([{'write_files': True}, { 'export_type': 'EXT' }]), #We need run renderer unless we are set for internal-pipe mode, which is the only time both of these are false 'monitor_external': {'export_type': 'EXT', 'binary_name': 'luxrender', 'render': True }, 'partial_ply': O([ {'export_type':'EXT'}, A([ {'export_type':'INT'}, {'write_files': True} ]) ]), 'install_path': { 'export_type': 'EXT' }, 'threads_auto': O([A([{'write_files': False}, { 'export_type': 'INT' }]), A([O([{'write_files': True}, { 'export_type': 'EXT' }]), { 'render': True }])]), #The flag options must be present for any condition where run renderer is present and checked, as well as internal-pipe mode 'threads': O([A([{'write_files': False}, { 'export_type': 'INT' }, {'threads_auto': False}]), A([O([{'write_files': True}, { 'export_type': 'EXT' }]), { 'render': True }, {'threads_auto': False}])]), #Longest logic test in the whole plugin! threads-auto is in both sides, since we must check that it is false for either internal-pipe mode, or when using run-renderer. 'fixed_seed': O([A([{'write_files': False}, { 'export_type': 'INT' }]), A([O([{'write_files': True}, { 'export_type': 'EXT' }]), { 'render': True }])]), 'log_verbosity': O([A([{'write_files': False}, { 'export_type': 'INT' }]), A([O([{'write_files': True}, { 'export_type': 'EXT' }]), { 'render': True }])]), } alert = {} properties = [ { 'type': 'bool', 'attr': 'threads_auto', 'name': 'Auto Threads', 'description': 'Let LuxRender decide how many threads to use', 'default': True }, { 'type': 'int', 'attr': 'threads', 'name': 'Render Threads', 'description': 'Number of threads to use', 'default': 1, 'min': 1, 'soft_min': 1, 'max': 64, 'soft_max': 64 }, { 'type': 'enum', 'attr': 'export_type', 'name': 'Export Type', 'description': 'Run LuxRender inside or outside of Blender', 'default': 'EXT', # if not PYLUX_AVAILABLE else 'INT', 'items': find_apis(), 'save_in_preset': True }, { 'type': 'bool', 'attr': 'integratedimaging', 'name': 'Integrated imaging workflow', 'description': 'Transfer rendered image directly to Blender without saving to disk (adds Z-buffer support and is more stable, but may take longer to refresh)', 'default': True }, { 'type': 'bool', 'attr': 'render', 'name': 'Run Renderer', 'description': 'Run Renderer after export', 'default': efutil.find_config_value('luxrender', 'defaults', 'auto_start', True), }, { 'type': 'bool', 'attr': 'monitor_external', 'name': 'Monitor External', 'description': 'Monitor external GUI rendering; when selected, LuxBlend will copy the render image from the external GUI', 'default': True, 'save_in_preset': True }, { 'type': 'bool', 'attr': 'partial_ply', 'name': 'Use Cached PLY Files', 'description': 'Only export PLY files for new or modified objects', 'default': True, 'save_in_preset': True }, { 'type': 'enum', 'attr': 'binary_name', 'name': 'External Type', 'description': 'Choose full GUI or console renderer', 'default': 'luxrender', 'items': [ ('luxrender', 'LuxRender GUI', 'luxrender'), ('luxconsole', 'LuxConsole', 'luxconsole'), ], 'save_in_preset': True }, { 'type': 'string', 'subtype': 'DIR_PATH', 'attr': 'install_path', 'name': 'Path to LuxRender Installation', 'description': 'Path to LuxRender install directory', 'default': find_luxrender_path() }, { 'type': 'bool', 'attr': 'write_files', 'name': 'Write to Disk', 'description': 'Write scene files to disk (allows use of PLY file cache)', 'default': True, 'save_in_preset': True }, { 'type': 'bool', 'attr': 'write_lxv', 'name': 'Export Smoke', 'description': 'Process and export smoke simulations', 'default': True, 'save_in_preset': True }, { 'type': 'bool', 'attr': 'embed_filedata', 'name': 'Embed File Data', 'description': 'Embed all external files (images etc) inline into the exporter output', 'default': False, 'save_in_preset': True }, { 'type': 'bool', 'attr': 'is_saving_lbm2', 'name': '<for internal use>', 'default': False, 'save_in_preset': False }, { 'type': 'enum', 'attr': 'mesh_type', 'name': 'Default mesh format', 'description': 'Sets whether to export scene geometry as PLY files or directly in the LXO file. PLY is faster and recommended', 'items': [ ('native', 'LuxRender mesh', 'native'), ('binary_ply', 'Binary PLY', 'binary_ply') ], 'default': 'binary_ply', 'save_in_preset': True }, { 'type': 'enum', 'attr': 'log_verbosity', 'name': 'Log verbosity', 'description': 'Logging verbosity', 'default': 'default', 'items': [ ('verbose', 'Verbose', 'verbose'), ('default', 'Default', 'default'), ('quiet', 'Quiet', 'quiet'), ('very-quiet', 'Very quiet', 'very-quiet'), ], 'save_in_preset': True }, { 'type': 'bool', 'attr': 'fixed_seed', 'name': 'Use fixed seeds', 'description': 'Use fixed seeds for threads. Helps with keeping noise even for animations', 'default': False, 'save_in_preset': True }, ] def allow_file_embed(self): saving_files = (self.export_type == 'EXT' or (self.export_type == 'INT' and self.write_files == True)) return self.is_saving_lbm2 or (saving_files and self.embed_filedata)
class mitsuba_engine(declarative_property_group): ef_attach_to = ['Scene'] controls = [ 'binary_path', 'export_mode', 'render_mode', 'mesh_type', 'partial_export', 'refresh_interval' ] visibility = { 'render_mode': { 'export_mode': 'render' }, 'refresh_interval': { 'export_mode': 'render', 'render_mode': 'cli' } } properties = [ { 'type': 'string', 'subtype': 'DIR_PATH', 'attr': 'binary_path', 'name': 'Executable path', 'description': 'Path to the Mitsuba install', 'default': efutil.find_config_value('mitsuba', 'defaults', 'binary_path', '') }, { 'type': 'enum', 'attr': 'export_mode', 'name': 'Export mode', 'description': 'Specifies whether or not to launch the renderer after exporting the scene', 'default': 'render', 'items': [('render', 'Export + Render', 'render'), ('exportonly', 'Only export', 'exportonly')], 'save_in_preset': True }, { 'type': 'enum', 'attr': 'render_mode', 'name': 'Rendering mode', 'description': 'Launch the external GUI or use the command-line renderer?', 'default': 'cli', 'items': [('cli', 'Mitsuba CLI', 'cli'), ('gui', 'Mitsuba GUI', 'gui')], 'save_in_preset': True }, { 'type': 'enum', 'attr': 'mesh_type', 'name': 'Default mesh format', 'description': 'Sets whether to export scene geometry as Serialized or PLY files. Serialized is faster and recommended', 'items': [('native', 'Serialized mesh', 'native'), ('binary_ply', 'Binary PLY', 'binary_ply')], 'default': 'native', 'save_in_preset': True }, { 'type': 'bool', 'attr': 'partial_export', 'name': 'Partial Mesh Export', 'description': 'Skip exporting Mesh files that already exist. Try disabling this if you have geometry issues', 'default': False, 'save_in_preset': True }, { 'type': 'int', 'attr': 'refresh_interval', 'name': 'Refresh interval', 'description': 'Period for updating rendering on screen (in seconds)', 'default': 5, 'min': 1, 'soft_min': 1, 'save_in_preset': True }, { 'type': 'int', 'attr': 'preview_depth', 'name': 'Depth', 'description': 'Max. path depth used when generating the preview (2: direct illumination, 3: one-bounce indirect, etc.)', 'default': int( efutil.find_config_value('mitsuba', 'defaults', 'preview_depth', '2')), 'min': 2, 'max': 10, 'save_in_preset': True }, { 'type': 'int', 'attr': 'preview_spp', 'name': 'SPP', 'description': 'Samples per pixel used to generate the preview', 'default': int( efutil.find_config_value('mitsuba', 'defaults', 'preview_spp', '16')), 'min': 1, 'max': 128, 'save_in_preset': True }, ]
import collections, xml.etree.cElementTree as ET, time, os from extensions_framework import log, util as efutil REPORTER = None PRINT_CONSOLE = efutil.find_config_value('indigo', 'defaults', 'console_output', False) OBJECT_ANALYSIS = os.getenv('B25_OBJECT_ANALYSIS', False) def indigo_log(message, popup=False, message_type='INFO'): global REPORTER, PRINT_CONSOLE if REPORTER == None or PRINT_CONSOLE: log('%s: %s' % (message_type, message), popup, module_name='Indigo') else: REPORTER({message_type}, '[Indigo %s] %s' % (time.strftime('%Y-%b-%d %H:%M:%S'), message)) class xml_cdata(str): pass class xml_multichild(list): pass class xml_builder(object): """Formatting functions for various data types""" format_types = { 'bool': lambda c,x: str(x).lower(), 'collection': lambda c,x: x, 'enum': lambda c,x: x, 'float': lambda c,x: x, 'int': lambda c,x: x, 'pointer': lambda c,x: x, 'string': lambda c,x: x,