def update_project(_): """ This function automatically runs when a .blend file is opened. :param _: :return: """ # Compile all OSL Script nodes stdosl_path = path_util.get_stdosl_paths() compiler = asr.ShaderCompiler(stdosl_path) q = asr.ShaderQuery() for script in bpy.data.texts: osl_bytecode = osl_utils.compile_osl_bytecode(compiler, script) if osl_bytecode is not None: q.open_bytecode(osl_bytecode) node_data = osl_utils.parse_shader(q) node_name, node_category, node_classes = osl_utils.generate_node(node_data, AppleseedOSLScriptNode) for cls in node_classes: safe_register_class(cls) else: logger.debug(f"appleseed: Shader {script.name} did not compile")
def read_osl_shaders(): """ Reads parameters from OSL .oso files using the ShaderQuery function that is built into the Python bindings for appleseed. These parameters are used to create a dictionary of the shader parameters that is then added to a list. This shader list is passed on to the oslnode.generate_node function. :return: List of parsed nodes """ nodes = list() shader_directories = path_util.get_osl_search_paths() q = asr.ShaderQuery() logger.debug("[appleseed] Parsing OSL shaders...") for shader_dir in shader_directories: if os.path.isdir(shader_dir): logger.debug("[appleseed] Searching {0} for OSO files...".format( shader_dir)) for file in os.listdir(shader_dir): if file.endswith(".oso"): logger.debug("[appleseed] Reading {0}...".format(file)) filename = os.path.join(shader_dir, file) q.open(filename) nodes.append(parse_shader(q, filename=filename)) logger.debug("[appleseed] OSL parsing complete.") return nodes
def generate_appleseed_nodedefs(): doc = mx.createDocument() # Add library includes q = asr.ShaderQuery() for root, dir, files in os.walk(oso_shaders_dir): for file in files: if file.endswith('.oso'): filename = os.path.join(root, file) q.open(filename) name = q.get_shader_name() # Create a nodedef taking three color3 and producing another color3 nodeType = 'multioutput' if check_multioutput( q) else 'surfaceshader' nodeDef = doc.addNodeDef( 'ND_%s' % name, nodeType, name) # type to be determined from shader type add_ports(nodeDef, q) outfile = 'appleseed_auto_defs.mtlx' mx.writeToXmlFile(doc, outfile)
def read_osl_shaders(): ''' Reads parameters from OSL .oso files using the ShaderQuery function that is built into the Python bindings for appleseed. These parameters are used to create a dictionary of the shader parameters that is then added to a list. This shader list is passed on to the oslnode.generate_node function. ''' nodes = [] if not path_util.get_appleseed_bin_dir_path(): logger.warning("[appleseed] WARNING: Path to appleseed's binary directory not set: rendering and OSL features will not be available.") return nodes shader_directories = path_util.get_osl_search_paths() import appleseed as asr q = asr.ShaderQuery() logger.debug("[appleseed] Parsing OSL shaders...") for shader_dir in shader_directories: if os.path.isdir(shader_dir): logger.debug("[appleseed] Searching {0} for OSO files...".format(shader_dir)) for file in os.listdir(shader_dir): if file.endswith(".oso"): logger.debug("[appleseed] Reading {0}...".format(file)) d = {} filename = os.path.join(shader_dir, file) q.open(filename) d['inputs'] = [] d['outputs'] = [] shader_meta = q.get_metadata() if 'as_node_name' in shader_meta: d['name'] = shader_meta['as_node_name']['value'] else: d['name'] = q.get_shader_name() d['filename'] = filename if 'URL' in shader_meta: d['url'] = shader_meta['URL']['value'] else: d['url'] = '' if 'as_category' in shader_meta: d['category'] = shader_meta['as_category']['value'] else: d['category'] = 'other' num_of_params = q.get_num_params() for x in range(0, num_of_params): metadata = {} param = q.get_param_info(x) if 'metadata' in param: metadata = param['metadata'] param_data = {} param_data['name'] = param['name'] param_data['type'] = param['type'] param_data['connectable'] = True param_data['hide_ui'] = param['validdefault'] is False if 'default' in param: param_data['default'] = param['default'] if 'label' in metadata: param_data['label'] = metadata['label']['value'] if 'widget' in metadata: param_data['widget'] = metadata['widget']['value'] if param_data['widget'] == 'null': param_data['hide_ui'] = True if 'page' in metadata: param_data['section'] = metadata['page']['value'] if 'min' in metadata: param_data['min'] = metadata['min']['value'] if 'max' in metadata: param_data['max'] = metadata['max']['value'] if 'softmin' in metadata: param_data['softmin'] = metadata['softmin']['value'] if 'softmax' in metadata: param_data['softmax'] = metadata['softmax']['value'] if 'help' in metadata: param_data['help'] = metadata['help']['value'] if 'options' in metadata: param_data['options'] = metadata['options']['value'].split(" = ")[-1].replace("\"", "").split("|") if 'as_blender_input_socket' in metadata: param_data['connectable'] = False if metadata['as_blender_input_socket']['value'] == 0.0 else True if param['isoutput'] is True: d['outputs'].append(param_data) else: d['inputs'].append(param_data) nodes.append(d) logger.debug("[appleseed] OSL parsing complete.") return nodes
def appendShaders( menuDefinition ) : # Collect all OSL shaders. categorisedMenuItems = {} uncategorisedMenuItems = [] q = asr.ShaderQuery() for path in os.environ["APPLESEED_SEARCHPATH"].split( ":" ) : for shader in glob.glob( os.path.join( path, "*.oso" ) ) : shaderFilename = os.path.basename( shader ) if shaderFilename.startswith( "as_" ) : shaderName = shaderFilename.replace( ".oso", "" ) category = None menuPath = "/Appleseed/Shader" q.open( shader ) shaderMetadata = q.get_metadata() if 'as_node_name' in shaderMetadata : displayName = shaderMetadata['as_node_name']['value'] else: displayName = " ".join( [ IECore.CamelCase.toSpaced( x ) for x in shaderName.split( "_" ) ] ) if 'as_category' in shaderMetadata : category = shaderMetadata['as_category']['value'] menuPath += "/" + category.capitalize() if not category in categorisedMenuItems : categorisedMenuItems[category] = [] else : menuPath += "/Other" menuPath += "/" + displayName nodeCreator = functools.partial( __shaderNodeCreator, shaderName ) if category : categorisedMenuItems[category].append( ( displayName, menuPath, nodeCreator ) ) else : uncategorisedMenuItems.append( ( displayName, menuPath, nodeCreator ) ) # Create menu entries. for category in categorisedMenuItems : shaders = categorisedMenuItems[category] shaders.sort() for shader in shaders : name, menuPath , nodeCreator = shader menuDefinition.append( menuPath, { "command" : GafferUI.NodeMenu.nodeCreatorWrapper( nodeCreator ), "searchText" : menuPath.rpartition( "/" )[2].replace( " ", "" ), } ) uncategorisedMenuItems.sort() for shader in uncategorisedMenuItems : name, menuPath , nodeCreator = shader menuDefinition.append( menuPath, { "command" : GafferUI.NodeMenu.nodeCreatorWrapper( nodeCreator ), "searchText" : "as" + menuPath.rpartition( "/" )[2].replace( " ", "" ), } )
def execute(self, context): temp_values = dict() input_connections = dict() output_connections = dict() material = context.object.active_material node_tree = material.node_tree node = node_tree.nodes.active location = node.location width = node.width script = node.script # Save existing connections and parameters for key, value in node.items(): temp_values[key] = value for input_iter in node.inputs: if input_iter.is_linked: input_connections[ input_iter.bl_idname] = input_iter.links[0].from_socket for output in node.outputs: if output.is_linked: outputs = [] for link in output.links: outputs.append(link.to_socket) output_connections[output.bl_idname] = outputs stdosl_path = path_util.get_stdosl_paths() compiler = asr.ShaderCompiler(stdosl_path) osl_bytecode = osl_utils.compile_osl_bytecode(compiler, script) if osl_bytecode is not None: q = asr.ShaderQuery() q.open_bytecode(osl_bytecode) node_data = osl_utils.parse_shader(q) node_name, node_category, node_classes = osl_utils.generate_node( node_data, AppleseedOSLScriptNode) for cls in reversed(node.classes): util.safe_unregister_class(cls) for cls in node_classes: util.safe_register_class(cls) node_tree.nodes.remove(node) new_node = node_tree.nodes.new(node_name) new_node.location = location new_node.width = width new_node.classes.extend(node_classes) setattr(new_node, "node_type", "osl_script") # Copy variables to new node for variable, value in temp_values.items(): if variable in dir(new_node): setattr(new_node, variable, value) # Recreate node connections for connection, sockets in output_connections.items(): for output in new_node.outputs: if output.bl_idname == connection: output_socket_class = output if output_socket_class: for output_connection in sockets: node_tree.links.new(output_socket_class, output_connection) for connection, sockets in input_connections.items(): for in_socket in new_node.inputs: if in_socket.bl_idname == connection: input_socket_class = in_socket if input_socket_class: for input_connection in sockets: node_tree.links.new(input_socket_class, input_connection) else: self.report({'ERROR'}, "OSL script did not compile!") return {'FINISHED'}