Skip to content

Instantly share code, notes, and snippets.

@paulwinex
Last active May 10, 2024 12:50
Show Gist options
  • Save paulwinex/c3eebeb11f1bbe2a55110fcbfe3c8ab5 to your computer and use it in GitHub Desktop.
Save paulwinex/c3eebeb11f1bbe2a55110fcbfe3c8ab5 to your computer and use it in GitHub Desktop.
import hou
class Connector:
container_node_type = ""
input_node_type = ""
input_connector_name = ""
def __init__(self, out_node):
self.out_node = out_node
def get_input_node(self):
container = self.out_node.parent()
input_node = next((n for n in container.allSubChildren() if n.type().name() == self.input_node_type), None)
if not input_node:
raise Exception("Output node not Found")
return input_node
def get_input_index(self):
output_node_input_index = self.get_input_node().inputIndex(self.input_connector_name)
if output_node_input_index < 0:
output_node_input_index = 0
print(f'Wrong input name "{self.input_node_type}": {self.input_connector_name}')
return output_node_input_index
def is_already_connected(self, input_node):
if input_node in self.out_node.outputs():
return input_node
def get_output_index(self):
input_node = self.get_input_node()
next_index = 0
connected_input_node = self.is_already_connected(input_node)
if connected_input_node:
for con in self.out_node.outputConnectors():
if con and any([c.outputNode() == connected_input_node for c in con]):
next_index = con[0].outputIndex() + 1
break
if next_index is None:
raise Exception("Index error")
else:
if next_index >= len(self.out_node.outputNames()):
next_index = 0
return next_index
def output_data_type(self, index=None):
index = index or self.get_output_index()
return self.out_node.outputDataTypes()[index]
def get_indexes_and_input_node(self):
input_node = self.get_input_node()
input_index = self.get_input_index()
output_index = self.get_output_index()
return input_node, input_index, output_index
def connect(self):
input_node, input_index, output_index = self.get_indexes_and_input_node()
# print(f"{self.out_node.name()}.{output_index} -> {input_node.name()}.{input_index}")
input_node.setInput(input_index, self.out_node, output_index)
@classmethod
def from_node(cls, hou_node):
current_container_type = hou_node.parent().type().name()
for engine in cls.__subclasses__():
if engine.container_node_type == current_container_type:
return engine(hou_node)
@classmethod
def connect_selected(cls):
sel = hou.selectedNodes()
if sel:
connector = Connector.from_node(sel[0])
connector.connect()
class KarmaConnector(Connector):
container_node_type = "subnet"
input_node_type = "suboutput"
input_connector_name = "surface"
preview_node_name = "shader_preview"
def is_already_connected(self, input_node):
node = super().is_already_connected(input_node)
if not node:
prev_node = self.out_node.parent().node(self.preview_node_name)
if prev_node in self.out_node.outputs():
return prev_node
def get_indexes_and_input_node(self):
input_node, input_index, output_index = super().get_indexes_and_input_node()
data_type = self.output_data_type(output_index)
if data_type == "surface":
return input_node, input_index, output_index
else:
input_node, input_index = self.create_intermediate_node(input_node, input_index)
return input_node, input_index, output_index
def create_intermediate_node(self, input_node, input_index):
node = input_node.parent().node(self.preview_node_name)
if not node:
node = self.out_node.parent().createNode("usdpreviewsurface")
node.setName(self.preview_node_name)
node.setParms({"diffuseColor": (0, 0, 0), "roughness": 1})
for name in node.inputNames():
node.setIsInputVisible(name, 0)
node.setPosition(input_node.position() - hou.Vector2(0, 2))
input_node.setInput(input_index, node, 0)
return node, 1
class HtoaConnector(Connector):
container_node_type = "arnold_materialbuilder"
input_node_type = "arnold_material"
input_connector_name = "surface"
def main():
Connector.connect_selected()
if __name__ == "builtins":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment