diff --git a/openpype/hosts/max/api/pipeline.py b/openpype/hosts/max/api/pipeline.py index 86a0a99ca9..bd680a3d84 100644 --- a/openpype/hosts/max/api/pipeline.py +++ b/openpype/hosts/max/api/pipeline.py @@ -18,7 +18,6 @@ from openpype.hosts.max.api import lib from openpype.hosts.max.api.plugin import MS_CUSTOM_ATTRIB from openpype.hosts.max import MAX_HOST_DIR - from pymxs import runtime as rt # noqa log = logging.getLogger("openpype.hosts.max") diff --git a/openpype/hosts/max/plugins/load/load_model.py b/openpype/hosts/max/plugins/load/load_model.py index 5acb57b923..c41608c860 100644 --- a/openpype/hosts/max/plugins/load/load_model.py +++ b/openpype/hosts/max/plugins/load/load_model.py @@ -14,7 +14,7 @@ class ModelAbcLoader(load.LoaderPlugin): """Loading model with the Alembic loader.""" families = ["model"] - label = "Load Model(Alembic)" + label = "Load Model with Alembic" representations = ["abc"] order = -10 icon = "code-fork" diff --git a/openpype/hosts/max/plugins/load/load_pointcache.py b/openpype/hosts/max/plugins/load/load_pointcache.py index 995e56ca37..3c2dfe8c25 100644 --- a/openpype/hosts/max/plugins/load/load_pointcache.py +++ b/openpype/hosts/max/plugins/load/load_pointcache.py @@ -55,7 +55,7 @@ class AbcLoader(load.LoaderPlugin): selections = rt.GetCurrentSelection() for abc in selections: for cam_shape in abc.Children: - cam_shape.playbackType = 2 + cam_shape.playbackType = 0 namespace = unique_namespace( name + "_", diff --git a/openpype/hosts/max/plugins/load/load_pointcache_ornatrix.py b/openpype/hosts/max/plugins/load/load_pointcache_ornatrix.py new file mode 100644 index 0000000000..96060a6a6f --- /dev/null +++ b/openpype/hosts/max/plugins/load/load_pointcache_ornatrix.py @@ -0,0 +1,108 @@ +import os +from openpype.pipeline import load, get_representation_path +from openpype.pipeline.load import LoadError +from openpype.hosts.max.api.pipeline import ( + containerise, + get_previous_loaded_object, + update_custom_attribute_data +) + +from openpype.hosts.max.api.lib import ( + unique_namespace, + get_namespace, + object_transform_set, + get_plugins +) +from openpype.hosts.max.api import lib +from pymxs import runtime as rt + + +class OxAbcLoader(load.LoaderPlugin): + """Ornatrix Alembic loader.""" + + families = ["camera", "animation", "pointcache"] + label = "Load Alembic with Ornatrix" + representations = ["abc"] + order = -10 + icon = "code-fork" + color = "orange" + postfix = "param" + + def load(self, context, name=None, namespace=None, data=None): + plugin_list = get_plugins() + if "ephere.plugins.autodesk.max.ornatrix.dlo" not in plugin_list: + raise LoadError("Ornatrix plugin not " + "found/installed in Max yet..") + + file_path = os.path.normpath(self.filepath_from_context(context)) + rt.AlembicImport.ImportToRoot = True + rt.AlembicImport.CustomAttributes = True + rt.importFile( + file_path, rt.name("noPrompt"), + using=rt.Ornatrix_Alembic_Importer) + + scene_object = [] + for obj in rt.rootNode.Children: + obj_type = rt.ClassOf(obj) + if str(obj_type).startswith("Ox_"): + scene_object.append(obj) + + namespace = unique_namespace( + name + "_", + suffix="_", + ) + abc_container = [] + for abc in scene_object: + abc.name = f"{namespace}:{abc.name}" + abc_container.append(abc) + + return containerise( + name, abc_container, context, + namespace, loader=self.__class__.__name__ + ) + + def update(self, container, representation): + path = get_representation_path(representation) + node_name = container["instance_node"] + namespace, name = get_namespace(node_name) + node = rt.getNodeByName(node_name) + node_list = get_previous_loaded_object(node) + rt.Select(node_list) + selections = rt.getCurrentSelection() + transform_data = object_transform_set(selections) + for prev_obj in selections: + if rt.isValidNode(prev_obj): + rt.Delete(prev_obj) + + rt.AlembicImport.ImportToRoot = False + rt.AlembicImport.CustomAttributes = True + rt.importFile( + path, rt.name("noPrompt"), + using=rt.Ornatrix_Alembic_Importer) + + scene_object = [] + for obj in rt.rootNode.Children: + obj_type = rt.ClassOf(obj) + if str(obj_type).startswith("Ox_"): + scene_object.append(obj) + ox_abc_objects = [] + for abc in scene_object: + abc.Parent = container + abc.name = f"{namespace}:{abc.name}" + ox_abc_objects.append(abc) + ox_transform = f"{abc.name}.transform" + if ox_transform in transform_data.keys(): + abc.pos = transform_data[ox_transform] or 0 + abc.scale = transform_data[f"{abc.name}.scale"] or 0 + update_custom_attribute_data(node, ox_abc_objects) + lib.imprint( + container["instance_node"], + {"representation": str(representation["_id"])}, + ) + + def switch(self, container, representation): + self.update(container, representation) + + def remove(self, container): + node = rt.GetNodeByName(container["instance_node"]) + rt.Delete(node)