make loader look prettier

This commit is contained in:
Mustafa-Zarkash 2023-08-03 23:34:32 +03:00
parent a1b0c409ac
commit 08fdbf1283

View file

@ -23,71 +23,25 @@ class FbxLoader(load.LoaderPlugin):
label = "Load FBX"
families = ["filmboxfbx", "fbx"]
representations = ["fbx"]
order = -10
icon = "code-fork"
color = "orange"
order = -10 # you can use this by default.
icon = "code-fork" # you can use this by default.
color = "orange" # you can use this by default.
def load(self, context, name=None, namespace=None, data=None):
import hou
file_path = self.get_file_path(context)
# Get the root node
obj = hou.node("/obj")
namespace, node_name = self.get_node_name(context, name, namespace)
# Define node name
namespace = namespace if namespace else context["asset"]["name"]
node_name = "{}_{}".format(namespace, name) if namespace else name
nodes = self.create_load_node_tree(file_path, node_name, name)
# Create a new geo node
container = obj.createNode("geo", node_name=node_name)
is_sequence = bool(context["representation"]["context"].get("frame"))
# Remove the file node, it only loads static meshes
# Houdini 17 has removed the file node from the geo node
file_node = container.node("file1")
if file_node:
file_node.destroy()
# Explicitly create a file node
path = self.filepath_from_context(context)
file_node = container.createNode("file", node_name=node_name)
file_node.setParms(
{"file": self.format_path(path, context["representation"])})
# Set display on last node
file_node.setDisplayFlag(True)
nodes = [container, file_node]
self[:] = nodes
return pipeline.containerise(
node_name,
namespace,
nodes,
context,
self.__class__.__name__,
suffix="",
containerised_nodes = self.get_containerised_nodes(
nodes, context, node_name, namespace
)
@staticmethod
def format_path(path, representation):
"""Format file path correctly for single bgeo or bgeo sequence."""
if not os.path.exists(path):
raise RuntimeError("Path does not exist: %s" % path)
is_sequence = bool(representation["context"].get("frame"))
# The path is either a single file or sequence in a folder.
if not is_sequence:
filename = path
else:
filename = re.sub(r"(.*)\.(\d+)\.(bgeo.*)", "\\1.$F4.\\3", path)
filename = os.path.join(path, filename)
filename = os.path.normpath(filename)
filename = filename.replace("\\", "/")
return filename
return containerised_nodes
def update(self, container, representation):
@ -116,3 +70,90 @@ class FbxLoader(load.LoaderPlugin):
def switch(self, container, representation):
self.update(container, representation)
def get_file_path(self, context):
"""Return formatted file path."""
# Format file name, Houdini only wants forward slashes
file_path = self.filepath_from_context(context)
file_path = os.path.normpath(file_path)
file_path = file_path.replace("\\", "/")
return file_path
def get_node_name(self, context, name=None, namespace=None):
"""Define node name."""
if not namespace:
namespace = context["asset"]["name"]
if namespace:
node_name = "{}_{}".format(namespace, name)
else:
node_name = name
return namespace, node_name
def create_load_node_tree(self, file_path, node_name, subset_name):
"""Create Load node network.
you can start building your tree at any obj level.
it'll be much easier to build it in the root obj level.
Afterwards, your tree will be automatically moved to
'/obj/AVALON_CONTAINERS' subnetwork.
"""
import hou
# Get the root obj level
obj = hou.node("/obj")
# Create a new obj geo node
parent_node = obj.createNode("geo", node_name=node_name)
# In older houdini,
# when reating a new obj geo node, a default file node will be
# automatically created.
# so, we will delete it if exists.
file_node = parent_node.node("file1")
if file_node:
file_node.destroy()
# Create a new file node
file_node = parent_node.createNode("file", node_name= node_name)
file_node.setParms({"file":file_path})
# Create attribute delete
attribdelete_name = "attribdelete_{}".format(subset_name)
attribdelete = parent_node.createNode("attribdelete",
node_name= attribdelete_name)
attribdelete.setParms({"ptdel":"fbx_*"})
attribdelete.setInput(0, file_node)
# Create a Null node
null_name = "OUT_{}".format(subset_name)
null = parent_node.createNode("null", node_name= null_name)
null.setInput(0, attribdelete)
# Ensure display flag is on the file_node input node and not on the OUT
# node to optimize "debug" displaying in the viewport.
file_node.setDisplayFlag(True)
# Set new position for unpack node else it gets cluttered
nodes = [parent_node, file_node, attribdelete, null]
for nr, node in enumerate(nodes):
node.setPosition([0, (0 - nr)])
return nodes
def get_containerised_nodes(self, nodes, context, node_name, namespace):
containerised_nodes = pipeline.containerise(
node_name,
namespace,
nodes,
context,
self.__class__.__name__,
suffix="",
)
return containerised_nodes