Example #1
0
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")
Example #2
0
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
Example #3
0
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)
Example #4
0
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
Example #5
0
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( " ", "" ),
			}
		)
Example #6
0
    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'}