예제 #1
0
def deserialize_from_dict(
    nodes_data: List[Dict[str, Any]], parent: hou.Node
) -> List[hou.Node]:
    nodes = []

    for node_data in nodes_data:
        node_instance = node.deserialize_from_dict(node_data, parent)

        nodes.append(node_instance)

    # create connections
    for node_data in nodes_data:
        node_instance: hou.Node = parent.node(node_data["name"])

        if node_instance:
            for connection_data in node_data["inputConnections"]:
                input_node = parent.node(connection_data["inputNode"])

                if input_node:
                    node_instance.setInput(
                        input_index=connection_data["inputIndex"],
                        item_to_become_input=input_node,
                        output_index=connection_data["outputIndex"],
                    )

    return nodes
예제 #2
0
def get_parms_commandline(node: hou.Node) -> list[str]:
    parms_multiparm: hou.Parm = node.parm("params")

    start_index = parms_multiparm.multiParmStartOffset()
    num_parms = parms_multiparm.evalAsInt()

    value_command = []

    for i in range(start_index, start_index + num_parms):
        parm_type = node.parm(f"graph_parm_type{i}").evalAsString()
        parm_name = node.parm(f"graph_parm_name{i}").evalAsString()
        parm_value_name = value_map[parm_type].format(i)
        use_color = node.parm(f"use_color_editor{i}").evalAsInt()

        if parm_type == "FLOAT3" and use_color:
            parm_value_name = f"rgb_value{i}"

        if parm_type == "FLOAT4" and use_color:
            parm_value_name = f"rgba_value{i}"

        value_parm: hou.ParmTuple = node.parmTuple(parm_value_name)

        value = value_parm.eval()
        value_command += [
            "--set-value", f"{parm_name}@{','.join((str(v) for v in value))}"
        ]

    return value_command
예제 #3
0
def get_time_commandline(node: hou.Node):
    time_type = node.parm("time_type").evalAsString()

    time = 0.0
    (frame_start, frame_end, _) = node.parmTuple("f").eval()
    frame = hou.frame()

    if time_type == "range":
        time = (frame - frame_start) / (frame_end - frame_start)
    elif time_type == "range_loop":
        time = (frame - frame_start) / (frame_end - frame_start + 1.0)
    elif time_type == "custom":
        time = node.evalParm("time")

    return ["--set-value", f"$time@{time}"]
예제 #4
0
def get_matched_graphs(node: hou.Node, sbsar_json: dict) -> list[str]:
    graphs = sbsar_json["graphs"]
    pattern = node.parm("output_graphs").evalAsString()
    pattern = pattern.strip()
    if not pattern or pattern == "*":
        return sbsar_json["graphs"].keys()

    return [graph for graph in graphs if hou.text.patternMatch(pattern, graph)]
예제 #5
0
def fill_outputs_from_json(node: hou.Node):
    sbsar_json = load_sbsar_json(node)
    sbs_graphs = sbsar_json["graphs"]

    graphs = get_matched_graphs(node, sbsar_json)
    outputs_multiparm: hou.Parm = node.parm("graph_outputs")
    output_names = get_multiparm_tuples(outputs_multiparm,
                                        ("output_name{}", "output_type{}"))

    outputs = list(
        set(
            it.chain.from_iterable(sbs_graphs[graph]["outputs"]
                                   for graph in graphs)))

    for outp in outputs:
        if (outp, 0) not in output_names:
            last_index = outputs_multiparm.eval()
            outputs_multiparm.insertMultiParmInstance(last_index)
            node.parm(f"output_name{last_index + 1}").set(outp)
예제 #6
0
def fill_inputs_from_json(node: hou.Node):
    sbsar_json = load_sbsar_json(node)
    sbs_graphs = sbsar_json["graphs"]

    graphs = get_matched_graphs(node, sbsar_json)
    inputs_multiparm: hou.Parm = node.parm("inputs")
    input_names = get_multiparm_tuples(inputs_multiparm,
                                       ("input_name{}", "input_type{}"))

    inputs = list(
        set(
            it.chain.from_iterable(sbs_graphs[graph]["inputs"]
                                   for graph in graphs)))

    for entry in inputs:
        if (entry, 0) not in input_names:
            last_index = inputs_multiparm.eval()
            inputs_multiparm.insertMultiParmInstance(last_index)
            node.parm(f"input_name{last_index + 1}").set(entry)
예제 #7
0
def deserialize_from_dict(
    node_data: Dict[str, Any], parent: hou.Node
) -> hou.Node:
    node_instance: hou.Node = parent.node(node_data["name"])

    if not node_instance:
        node_instance = parent.createNode(
            node_type_name=node_data["type"]["name"],
            node_name=node_data["name"],
        )

    node_instance.setPosition(
        vector2.deserialize_from_dict(node_data["position"])
    )

    # apply parameter changes
    exceptions: List[str] = []

    for parm_name, parm_data in node_data["parms"].items():
        parm: hou.Parm = node_instance.parm(parm_name)

        try:
            if parm:
                node_instance.parm(parm_name).set(parm_data["rawValue"])
        except TypeError:
            exceptions.append(parm_data)

    if exceptions:
        print(
            "Unable to set the following parameters on '{}': {}".format(
                node_instance.name(), ", ".join(exceptions)
            )
        )

    # deserialize children
    children = nodes.deserialize_from_dict(
        node_data["children"].values(), node_instance
    )

    return node_instance
예제 #8
0
def get_inputs_commandline(node: hou.Node) -> list[str]:
    inputs_multiparm: hou.Parm = node.parm("inputs")

    inputs: list[SBSARInput] = get_multiparm_namedtuples(
        inputs_multiparm, SBSARInput)
    result = []

    for i in inputs:
        if i.input_type == 0:
            result += ["--set-entry", f"{i.name}@{i.path}"]
        else:
            result += ["--set-entry-usage", f"{i.usage}@{i.path}"]

    return result
예제 #9
0
def fill_parms_from_json(node: hou.Node):
    sbsar_json = load_sbsar_json(node)
    sbs_graphs = sbsar_json["graphs"]

    graphs = get_matched_graphs(node, sbsar_json)
    parms = list(
        set(
            it.chain.from_iterable(sbs_graphs[graph]["parms"].items()
                                   for graph in graphs)))

    parms_multiparm: hou.Parm = node.parm("params")
    names = get_multiparm_instances(parms_multiparm, "graph_parm_name{}")

    for parm in parms:
        if parm[0] not in names and parm[0] not in ("$outputsize",
                                                    "$randomseed"):
            last_index = parms_multiparm.eval()
            parms_multiparm.insertMultiParmInstance(last_index)
            parm_name: str = parm[0]
            if parm_name.startswith("$"):
                parm_name = "\\" + parm_name
            node.parm(f"graph_parm_name{last_index + 1}").set(parm_name)
            node.parm(f"graph_parm_type{last_index + 1}").set(parm[1])
예제 #10
0
def serialize_as_dict(node_instance: hou.Node) -> Dict[str, Any]:
    return {
        "class_name": node_instance.__class__.__name__,
        "name": node_instance.name(),
        "type": nodetype.serialize_as_dict(node_instance.type()),
        "color": color.serialize_as_dict(node_instance.color()),
        "position": vector2.serialize_as_dict(node_instance.position()),
        "parms": {
            x.name(): parm.serialize_as_dict(x)
            for x in list(node_instance.parms())
            if not x.isAtDefault(
                compare_temporary_defaults=True, compare_expressions=False
            )
        },
        "inputConnections": [
            nodeconnection.serialize_as_dict(x)
            for x in list(node_instance.inputConnections())
        ],
        "isNetwork": node_instance.isNetwork(),
        "children": nodes.serialize_as_dict(list(node_instance.children()))
        if node_instance.isNetwork()
        else {},
    }
예제 #11
0
def get_outputs_commandline(node: hou.Node) -> list[str]:
    inputs_multiparm: hou.Parm = node.parm("graph_outputs")

    outputs: list[SBSAROutput] = get_multiparm_namedtuples(
        inputs_multiparm, SBSAROutput)
    result = []

    for o in outputs:
        if o.output_type == 0:
            result += ["--input-graph-output", o.name]
            if o.out_format != "default":
                result += ["--set-output-format", f"{o.name}@{o.out_format}"]
            if o.bitdepth != "default":
                result += ["--set-output-bit-depth", f"{o.name}@{o.bitdepth}"]
            if o.colorspace.strip():
                result += ["--set-output-colorspace", o.colorspace]
        else:
            result += ["--input-graph-output-usage", o.usage]

    return result
예제 #12
0
def run_sbsrender(node: hou.Node):
    sbsar_json = load_sbsar_json(node)

    cl = [node.evalParm("sbsrender_path")]
    cl += ["render"]
    cl += [node.parm("sbsar").evalAsString()]

    output_path: str = node.evalParm("output_path")
    if output_path.strip():
        cl += ["--output-path", output_path]

    output_name: str = node.evalParm("output_name")
    if output_name.strip():
        cl += ["--output-name", output_name]

    if node.evalParm("engine_override"):
        cl += ["--engine", node.parm("engine").evalAsString()]

    cl += get_settings_commandline(node)

    pattern = node.parm("output_graphs").evalAsString()
    pattern = pattern.strip()
    if pattern and pattern != "*":
        cl += get_output_graphs_commandline(node, sbsar_json)

    cl += get_time_commandline(node)

    cl += get_inputs_commandline(node)
    if node.evalParm("use_graph_outputs"):
        cl += get_outputs_commandline(node)

    size_type = node.evalParm("size_type")
    size_x = node.parm("size_x").evalAsString()
    size_y = node.parm("size_y").evalAsString()

    if size_type == 0:
        cl += ["--set-value", f"$outputsize@{size_x},{size_x}"]
    else:
        cl += ["--set-value", f"$outputsize@{size_x},{size_y}"]

    if node.evalParm("use_randomseed"):
        cl += ["--set-value", f"$randomseed@{node.evalParm('random_seed')}"]

    cl += get_parms_commandline(node)

    if node.parm("use_preset").eval():
        cl += ["--use-preset", node.parm("preset").evalAsString()]

    #print(cl)

#    with hou.InterruptableOperation(f"Rendering SBSAR: {node.parm('sbsar').evalAsString()}", open_interrupt_dialog=True):

    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    result = subprocess.run(cl,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            startupinfo=startupinfo)

    if (result.returncode != 0):
        message = result.stderr.decode("utf-8")
        _error(message, hou.NodeError)
    elif node.evalParm("pdg_logoutput"):
        result_json = result.stdout.decode("utf-8")
        result = json.loads(result_json)

        for graph in result:
            if "outputs" not in graph:
                continue

            for output in graph["outputs"]:
                if "value" not in output:
                    continue

                print(f"OUTPUT_FILE:{output['value']};")
예제 #13
0
def get_settings_commandline(node: hou.Node):
    result = []

    if node.evalParm("settings_format"):
        result += [
            "--output-format",
            node.parm("output_format").evalAsString()
        ]

    if node.evalParm("settings_compression"):
        result += [
            "--png-format-compression",
            node.parm("png_compression").evalAsString()
        ]

    if node.evalParm("settings_colorspace"):
        result += [
            "--output-colorspace",
            node.parm("color_space").evalAsString()
        ]

    if node.evalParm("settings_cachedir"):
        result += ["--cache-dir", node.parm("cache_dir").evalAsString()]

    if node.evalParm("settings_cpucount"):
        result += ["--cpu-count", str(node.parm("cpu_count").eval())]

    if node.evalParm("settings_memorybudget"):
        result += ["--memory-budget", str(node.parm("memory_budget").eval())]

    if node.evalParm("settings_ocioconfig"):
        result += ["--ocio", node.parm("ocio_config").evalAsString()]

    if node.evalParm("use_ace"):
        result += ["--ace"]
        result += [
            "--ace-render-intent",
            node.parm("ace_render_intent").evalAsString()
        ]
        result += [
            "--ace-working-space",
            node.parm("ace_working_space").evalAsString()
        ]

        icc_path = node.evalParm("icc_profiles_path")
        if icc_path.strip():
            result += ["--icc-profiles-dir", icc_path]

    return result
예제 #14
0
def refresh_sbsar_cache(node: hou.Node):
    sbsar_path = node.parm("sbsar").evalAsString()
    sbsar_info = get_sbsar_info(node.evalParm("sbsrender_path"), sbsar_path)
    sbsar_json = get_sbsar_json(sbsar_info)
    cache_sbsar_json(node, sbsar_json)
예제 #15
0
def cache_sbsar_json(node: hou.Node, sbsar_json: str):
    node.setUserData(SBSAR_USERDATA_KEY, sbsar_json)
예제 #16
0
def load_sbsar_json(node: hou.Node) -> dict:
    sbsar_json = node.userData(SBSAR_USERDATA_KEY)
    if sbsar_json is not None:
        return json.loads(sbsar_json)
    return {"graphs": {}, "metadata": {}}