Merge pull request #5424 from ynput/enhancement/OP-6191_3dsmax-switching-versions-of-maxScene-maintain-parentagelinks

Max: switching versions of maxScene maintain parentage/links with the loaders
This commit is contained in:
Kayla Man 2023-09-14 17:34:41 +08:00 committed by GitHub
commit 257374f90e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 190 additions and 194 deletions

View file

@ -407,3 +407,19 @@ def object_transform_set(container_children):
name = f"{node.name}.scale"
transform_set[name] = node.scale
return transform_set
def get_plugins() -> list:
"""Get all loaded plugins in 3dsMax
Returns:
plugin_info_list: a list of loaded plugins
"""
manager = rt.PluginManager
count = manager.pluginDllCount
plugin_info_list = []
for p in range(1, count + 1):
plugin_info = manager.pluginDllName(p)
plugin_info_list.append(plugin_info)
return plugin_info_list

View file

@ -164,12 +164,9 @@ def containerise(name: str, nodes: list, context,
"loader": loader,
"representation": context["representation"]["_id"],
}
container_name = f"{namespace}:{name}{suffix}"
container = rt.container(name=container_name)
for node in nodes:
node.Parent = container
import_custom_attribute_data(container, nodes)
if not lib.imprint(container_name, data):
print(f"imprinting of {container_name} failed.")
return container
@ -212,6 +209,7 @@ def import_custom_attribute_data(container: str, selections: list):
container.modifiers[0].openPypeData,
"sel_list", sel_list)
def update_custom_attribute_data(container: str, selections: list):
"""Updating the Openpype/AYON custom parameter built by the creator
@ -223,3 +221,20 @@ def update_custom_attribute_data(container: str, selections: list):
if container.modifiers[0].name == "OP Data":
rt.deleteModifier(container, container.modifiers[0])
import_custom_attribute_data(container, selections)
def get_previous_loaded_object(container: str):
"""Get previous loaded_object through the OP data
Args:
container (str): the container which stores the OP data
Returns:
node_list(list): list of nodes which are previously loaded
"""
node_list = []
sel_list = rt.getProperty(container.modifiers[0].openPypeData, "sel_list")
for obj in rt.Objects:
if str(obj) in sel_list:
node_list.append(obj)
return node_list

View file

@ -8,7 +8,7 @@ from openpype.hosts.max.api.lib import (
)
from openpype.hosts.max.api.pipeline import (
containerise,
import_custom_attribute_data,
get_previous_loaded_object,
update_custom_attribute_data
)
from openpype.pipeline import get_representation_path, load
@ -22,7 +22,6 @@ class FbxLoader(load.LoaderPlugin):
order = -9
icon = "code-fork"
color = "white"
postfix = "param"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
@ -42,17 +41,13 @@ class FbxLoader(load.LoaderPlugin):
name + "_",
suffix="_",
)
container = rt.container(
name=f"{namespace}:{name}_{self.postfix}")
selections = rt.GetCurrentSelection()
import_custom_attribute_data(container, selections)
for selection in selections:
selection.Parent = container
selection.name = f"{namespace}:{selection.name}"
return containerise(
name, [container], context,
name, selections, context,
namespace, loader=self.__class__.__name__)
def update(self, container, representation):
@ -61,12 +56,13 @@ class FbxLoader(load.LoaderPlugin):
path = get_representation_path(representation)
node_name = container["instance_node"]
node = rt.getNodeByName(node_name)
namespace, name = get_namespace(node_name)
sub_node_name = f"{namespace}:{name}_{self.postfix}"
inst_container = rt.getNodeByName(sub_node_name)
rt.Select(inst_container.Children)
transform_data = object_transform_set(inst_container.Children)
for prev_fbx_obj in rt.selection:
namespace, _ = get_namespace(node_name)
node_list = get_previous_loaded_object(node)
rt.Select(node_list)
prev_fbx_objects = rt.GetCurrentSelection()
transform_data = object_transform_set(prev_fbx_objects)
for prev_fbx_obj in prev_fbx_objects:
if rt.isValidNode(prev_fbx_obj):
rt.Delete(prev_fbx_obj)
@ -78,24 +74,17 @@ class FbxLoader(load.LoaderPlugin):
rt.ImportFile(
path, rt.name("noPrompt"), using=rt.FBXIMP)
current_fbx_objects = rt.GetCurrentSelection()
fbx_objects = []
for fbx_object in current_fbx_objects:
if fbx_object.Parent != inst_container:
fbx_object.Parent = inst_container
fbx_object.name = f"{namespace}:{fbx_object.name}"
fbx_object.pos = transform_data[
f"{fbx_object.name}.transform"]
fbx_object.name = f"{namespace}:{fbx_object.name}"
fbx_objects.append(fbx_object)
fbx_transform = f"{fbx_object.name}.transform"
if fbx_transform in transform_data.keys():
fbx_object.pos = transform_data[fbx_transform] or 0
fbx_object.scale = transform_data[
f"{fbx_object.name}.scale"]
for children in node.Children:
if rt.classOf(children) == rt.Container:
if children.name == sub_node_name:
update_custom_attribute_data(
children, current_fbx_objects)
with maintained_selection():
rt.Select(node)
f"{fbx_object.name}.scale"] or 0
update_custom_attribute_data(node, fbx_objects)
lib.imprint(container["instance_node"], {
"representation": str(representation["_id"])
})

View file

@ -7,7 +7,7 @@ from openpype.hosts.max.api.lib import (
object_transform_set
)
from openpype.hosts.max.api.pipeline import (
containerise, import_custom_attribute_data,
containerise, get_previous_loaded_object,
update_custom_attribute_data
)
from openpype.pipeline import get_representation_path, load
@ -24,7 +24,6 @@ class MaxSceneLoader(load.LoaderPlugin):
order = -8
icon = "code-fork"
color = "green"
postfix = "param"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
@ -37,18 +36,13 @@ class MaxSceneLoader(load.LoaderPlugin):
max_object_names = [obj.name for obj in max_objects]
# implement the OP/AYON custom attributes before load
max_container = []
namespace = unique_namespace(
name + "_",
suffix="_",
)
container_name = f"{namespace}:{name}_{self.postfix}"
container = rt.Container(name=container_name)
import_custom_attribute_data(container, max_objects)
max_container.append(container)
max_container.extend(max_objects)
for max_obj, obj_name in zip(max_objects, max_object_names):
max_obj.name = f"{namespace}:{obj_name}"
max_container.append(rt.getNodeByName(max_obj.name))
return containerise(
name, max_container, context,
namespace, loader=self.__class__.__name__)
@ -58,34 +52,38 @@ class MaxSceneLoader(load.LoaderPlugin):
path = get_representation_path(representation)
node_name = container["instance_node"]
node = rt.getNodeByName(node_name)
namespace, name = get_namespace(node_name)
sub_container_name = f"{namespace}:{name}_{self.postfix}"
namespace, _ = get_namespace(node_name)
# delete the old container with attribute
# delete old duplicate
rt.Select(node.Children)
transform_data = object_transform_set(node.Children)
for prev_max_obj in rt.GetCurrentSelection():
if rt.isValidNode(prev_max_obj) and prev_max_obj.name != sub_container_name: # noqa
# use the modifier OP data to delete the data
node_list = get_previous_loaded_object(node)
rt.select(node_list)
prev_max_objects = rt.GetCurrentSelection()
transform_data = object_transform_set(prev_max_objects)
for prev_max_obj in prev_max_objects:
if rt.isValidNode(prev_max_obj): # noqa
rt.Delete(prev_max_obj)
rt.MergeMaxFile(path, rt.Name("deleteOldDups"))
rt.MergeMaxFile(path, quiet=True)
current_max_objects = rt.getLastMergedNodes()
current_max_object_names = [obj.name for obj
in current_max_objects]
sub_container = rt.getNodeByName(sub_container_name)
update_custom_attribute_data(sub_container, current_max_objects)
for max_object in current_max_objects:
max_object.Parent = node
max_objects = []
for max_obj, obj_name in zip(current_max_objects,
current_max_object_names):
max_obj.name = f"{namespace}:{obj_name}"
max_obj.pos = transform_data[
f"{max_obj.name}.transform"]
max_obj.scale = transform_data[
f"{max_obj.name}.scale"]
max_objects.append(max_obj)
max_transform = f"{max_obj.name}.transform"
if max_transform in transform_data.keys():
max_obj.pos = transform_data[max_transform] or 0
max_obj.scale = transform_data[
f"{max_obj.name}.scale"] or 0
update_custom_attribute_data(node, max_objects)
lib.imprint(container["instance_node"], {
"representation": str(representation["_id"])
})

View file

@ -2,8 +2,7 @@ import os
from openpype.pipeline import load, get_representation_path
from openpype.hosts.max.api.pipeline import (
containerise,
import_custom_attribute_data,
update_custom_attribute_data
get_previous_loaded_object
)
from openpype.hosts.max.api import lib
from openpype.hosts.max.api.lib import (
@ -20,7 +19,6 @@ class ModelAbcLoader(load.LoaderPlugin):
order = -10
icon = "code-fork"
color = "orange"
postfix = "param"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
@ -52,21 +50,22 @@ class ModelAbcLoader(load.LoaderPlugin):
self.log.error("Something failed when loading.")
abc_container = abc_containers.pop()
import_custom_attribute_data(
abc_container, abc_container.Children)
namespace = unique_namespace(
name + "_",
suffix="_",
)
abc_objects = []
for abc_object in abc_container.Children:
abc_object.name = f"{namespace}:{abc_object.name}"
abc_objects.append(abc_object)
# rename the abc container with namespace
abc_container_name = f"{namespace}:{name}_{self.postfix}"
abc_container_name = f"{namespace}:{name}"
abc_container.name = abc_container_name
abc_objects.append(abc_container)
return containerise(
name, [abc_container], context,
name, abc_objects, context,
namespace, loader=self.__class__.__name__
)
@ -75,20 +74,19 @@ class ModelAbcLoader(load.LoaderPlugin):
path = get_representation_path(representation)
node = rt.GetNodeByName(container["instance_node"])
node_list = [n for n in get_previous_loaded_object(node)
if rt.ClassOf(n) == rt.AlembicContainer]
with maintained_selection():
rt.Select(node.Children)
rt.Select(node_list)
for alembic in rt.Selection:
abc = rt.GetNodeByName(alembic.name)
update_custom_attribute_data(abc, abc.Children)
rt.Select(abc.Children)
for abc_con in abc.Children:
abc_con.source = path
rt.Select(abc_con.Children)
for abc_obj in abc_con.Children:
abc_obj.source = path
lib.imprint(
container["instance_node"],
{"representation": str(representation["_id"])},

View file

@ -1,7 +1,7 @@
import os
from openpype.pipeline import load, get_representation_path
from openpype.hosts.max.api.pipeline import (
containerise, import_custom_attribute_data,
containerise, get_previous_loaded_object,
update_custom_attribute_data
)
from openpype.hosts.max.api import lib
@ -21,79 +21,71 @@ class FbxModelLoader(load.LoaderPlugin):
order = -9
icon = "code-fork"
color = "white"
postfix = "param"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
filepath = os.path.normpath(self.filepath_from_context(context))
filepath = self.filepath_from_context(context)
filepath = os.path.normpath(filepath)
rt.FBXImporterSetParam("Animation", False)
rt.FBXImporterSetParam("Cameras", False)
rt.FBXImporterSetParam("Mode", rt.Name("create"))
rt.FBXImporterSetParam("Preserveinstances", True)
rt.importFile(filepath, rt.name("noPrompt"), using=rt.FBXIMP)
rt.importFile(
filepath, rt.name("noPrompt"), using=rt.FBXIMP)
namespace = unique_namespace(
name + "_",
suffix="_",
)
container = rt.container(
name=f"{namespace}:{name}_{self.postfix}")
selections = rt.GetCurrentSelection()
import_custom_attribute_data(container, selections)
for selection in selections:
selection.Parent = container
selection.name = f"{namespace}:{selection.name}"
return containerise(
name, [container], context,
namespace, loader=self.__class__.__name__
)
name, selections, context,
namespace, loader=self.__class__.__name__)
def update(self, container, representation):
from pymxs import runtime as rt
path = get_representation_path(representation)
node_name = container["instance_node"]
node = rt.getNodeByName(node_name)
namespace, name = get_namespace(node_name)
sub_node_name = f"{namespace}:{name}_{self.postfix}"
inst_container = rt.getNodeByName(sub_node_name)
rt.Select(inst_container.Children)
transform_data = object_transform_set(inst_container.Children)
for prev_fbx_obj in rt.selection:
if not node:
rt.Container(name=node_name)
namespace, _ = get_namespace(node_name)
node_list = get_previous_loaded_object(node)
rt.Select(node_list)
prev_fbx_objects = rt.GetCurrentSelection()
transform_data = object_transform_set(prev_fbx_objects)
for prev_fbx_obj in prev_fbx_objects:
if rt.isValidNode(prev_fbx_obj):
rt.Delete(prev_fbx_obj)
rt.FBXImporterSetParam("Animation", False)
rt.FBXImporterSetParam("Cameras", False)
rt.FBXImporterSetParam("Mode", rt.Name("merge"))
rt.FBXImporterSetParam("AxisConversionMethod", True)
rt.FBXImporterSetParam("Mode", rt.Name("create"))
rt.FBXImporterSetParam("Preserveinstances", True)
rt.importFile(path, rt.name("noPrompt"), using=rt.FBXIMP)
current_fbx_objects = rt.GetCurrentSelection()
fbx_objects = []
for fbx_object in current_fbx_objects:
if fbx_object.Parent != inst_container:
fbx_object.Parent = inst_container
fbx_object.name = f"{namespace}:{fbx_object.name}"
fbx_object.pos = transform_data[
f"{fbx_object.name}.transform"]
fbx_object.name = f"{namespace}:{fbx_object.name}"
fbx_objects.append(fbx_object)
fbx_transform = f"{fbx_object.name}.transform"
if fbx_transform in transform_data.keys():
fbx_object.pos = transform_data[fbx_transform] or 0
fbx_object.scale = transform_data[
f"{fbx_object.name}.scale"]
for children in node.Children:
if rt.classOf(children) == rt.Container:
if children.name == sub_node_name:
update_custom_attribute_data(
children, current_fbx_objects)
f"{fbx_object.name}.scale"] or 0
with maintained_selection():
rt.Select(node)
lib.imprint(
node_name,
{"representation": str(representation["_id"])},
)
update_custom_attribute_data(node, fbx_objects)
lib.imprint(container["instance_node"], {
"representation": str(representation["_id"])
})
def switch(self, container, representation):
self.update(container, representation)

View file

@ -10,7 +10,7 @@ from openpype.hosts.max.api.lib import (
from openpype.hosts.max.api.lib import maintained_selection
from openpype.hosts.max.api.pipeline import (
containerise,
import_custom_attribute_data,
get_previous_loaded_object,
update_custom_attribute_data
)
from openpype.pipeline import get_representation_path, load
@ -24,7 +24,6 @@ class ObjLoader(load.LoaderPlugin):
order = -9
icon = "code-fork"
color = "white"
postfix = "param"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
@ -39,15 +38,12 @@ class ObjLoader(load.LoaderPlugin):
suffix="_",
)
# create "missing" container for obj import
container = rt.Container(name=f"{namespace}:{name}_{self.postfix}")
selections = rt.GetCurrentSelection()
import_custom_attribute_data(container, selections)
# get current selection
for selection in selections:
selection.Parent = container
selection.name = f"{namespace}:{selection.name}"
return containerise(
name, [container], context,
name, selections, context,
namespace, loader=self.__class__.__name__)
def update(self, container, representation):
@ -56,26 +52,26 @@ class ObjLoader(load.LoaderPlugin):
path = get_representation_path(representation)
node_name = container["instance_node"]
node = rt.getNodeByName(node_name)
namespace, name = get_namespace(node_name)
sub_node_name = f"{namespace}:{name}_{self.postfix}"
inst_container = rt.getNodeByName(sub_node_name)
rt.Select(inst_container.Children)
transform_data = object_transform_set(inst_container.Children)
for prev_obj in rt.selection:
namespace, _ = get_namespace(node_name)
node_list = get_previous_loaded_object(node)
rt.Select(node_list)
previous_objects = rt.GetCurrentSelection()
transform_data = object_transform_set(previous_objects)
for prev_obj in previous_objects:
if rt.isValidNode(prev_obj):
rt.Delete(prev_obj)
rt.Execute(f'importFile @"{path}" #noPrompt using:ObjImp')
# get current selection
selections = rt.GetCurrentSelection()
update_custom_attribute_data(inst_container, selections)
for selection in selections:
selection.Parent = inst_container
selection.name = f"{namespace}:{selection.name}"
selection.pos = transform_data[
f"{selection.name}.transform"]
selection.scale = transform_data[
f"{selection.name}.scale"]
selection_transform = f"{selection.name}.transform"
if selection_transform in transform_data.keys():
selection.pos = transform_data[selection_transform] or 0
selection.scale = transform_data[
f"{selection.name}.scale"] or 0
update_custom_attribute_data(node, selections)
with maintained_selection():
rt.Select(node)

View file

@ -1,15 +1,19 @@
import os
from pymxs import runtime as rt
from openpype.pipeline.load import LoadError
from openpype.hosts.max.api import lib
from openpype.hosts.max.api.lib import (
unique_namespace,
get_namespace,
object_transform_set
object_transform_set,
get_plugins
)
from openpype.hosts.max.api.lib import maintained_selection
from openpype.hosts.max.api.pipeline import (
containerise,
import_custom_attribute_data
get_previous_loaded_object,
update_custom_attribute_data
)
from openpype.pipeline import get_representation_path, load
@ -23,16 +27,16 @@ class ModelUSDLoader(load.LoaderPlugin):
order = -10
icon = "code-fork"
color = "orange"
postfix = "param"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
# asset_filepath
plugin_info = get_plugins()
if "usdimport.dli" not in plugin_info:
raise LoadError("No USDImporter loaded/installed in Max..")
filepath = os.path.normpath(self.filepath_from_context(context))
import_options = rt.USDImporter.CreateOptions()
base_filename = os.path.basename(filepath)
filename, ext = os.path.splitext(base_filename)
_, ext = os.path.splitext(base_filename)
log_filepath = filepath.replace(ext, "txt")
rt.LogPath = log_filepath
@ -44,35 +48,34 @@ class ModelUSDLoader(load.LoaderPlugin):
suffix="_",
)
asset = rt.GetNodeByName(name)
import_custom_attribute_data(asset, asset.Children)
usd_objects = []
for usd_asset in asset.Children:
usd_asset.name = f"{namespace}:{usd_asset.name}"
usd_objects.append(usd_asset)
asset_name = f"{namespace}:{name}_{self.postfix}"
asset_name = f"{namespace}:{name}"
asset.name = asset_name
# need to get the correct container after renamed
asset = rt.GetNodeByName(asset_name)
usd_objects.append(asset)
return containerise(
name, [asset], context,
name, usd_objects, context,
namespace, loader=self.__class__.__name__)
def update(self, container, representation):
from pymxs import runtime as rt
path = get_representation_path(representation)
node_name = container["instance_node"]
node = rt.GetNodeByName(node_name)
namespace, name = get_namespace(node_name)
sub_node_name = f"{namespace}:{name}_{self.postfix}"
transform_data = None
for n in node.Children:
rt.Select(n.Children)
transform_data = object_transform_set(n.Children)
for prev_usd_asset in rt.selection:
if rt.isValidNode(prev_usd_asset):
rt.Delete(prev_usd_asset)
node_list = get_previous_loaded_object(node)
rt.Select(node_list)
prev_objects = [sel for sel in rt.GetCurrentSelection()
if sel != rt.Container
and sel.name != node_name]
transform_data = object_transform_set(prev_objects)
for n in prev_objects:
rt.Delete(n)
import_options = rt.USDImporter.CreateOptions()
@ -86,17 +89,19 @@ class ModelUSDLoader(load.LoaderPlugin):
path, importOptions=import_options)
asset = rt.GetNodeByName(name)
asset.Parent = node
import_custom_attribute_data(asset, asset.Children)
usd_objects = []
for children in asset.Children:
children.name = f"{namespace}:{children.name}"
children.pos = transform_data[
f"{children.name}.transform"]
children.scale = transform_data[
f"{children.name}.scale"]
asset.name = sub_node_name
usd_objects.append(children)
children_transform = f"{children.name}.transform"
if children_transform in transform_data.keys():
children.pos = transform_data[children_transform] or 0
children.scale = transform_data[
f"{children.name}.scale"] or 0
asset.name = f"{namespace}:{asset.name}"
usd_objects.append(asset)
update_custom_attribute_data(node, usd_objects)
with maintained_selection():
rt.Select(node)
@ -108,7 +113,5 @@ class ModelUSDLoader(load.LoaderPlugin):
self.update(container, representation)
def remove(self, container):
from pymxs import runtime as rt
node = rt.GetNodeByName(container["instance_node"])
rt.Delete(node)

View file

@ -10,8 +10,7 @@ from openpype.hosts.max.api import lib, maintained_selection
from openpype.hosts.max.api.lib import unique_namespace
from openpype.hosts.max.api.pipeline import (
containerise,
import_custom_attribute_data,
update_custom_attribute_data
get_previous_loaded_object
)
@ -24,7 +23,6 @@ class AbcLoader(load.LoaderPlugin):
order = -10
icon = "code-fork"
color = "orange"
postfix = "param"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
@ -55,8 +53,6 @@ class AbcLoader(load.LoaderPlugin):
abc_container = abc_containers.pop()
selections = rt.GetCurrentSelection()
import_custom_attribute_data(
abc_container, abc_container.Children)
for abc in selections:
for cam_shape in abc.Children:
cam_shape.playbackType = 2
@ -65,15 +61,17 @@ class AbcLoader(load.LoaderPlugin):
name + "_",
suffix="_",
)
abc_objects = []
for abc_object in abc_container.Children:
abc_object.name = f"{namespace}:{abc_object.name}"
abc_objects.append(abc_object)
# rename the abc container with namespace
abc_container_name = f"{namespace}:{name}_{self.postfix}"
abc_container_name = f"{namespace}:{name}"
abc_container.name = abc_container_name
abc_objects.append(abc_container)
return containerise(
name, [abc_container], context,
name, abc_objects, context,
namespace, loader=self.__class__.__name__
)
@ -82,20 +80,19 @@ class AbcLoader(load.LoaderPlugin):
path = get_representation_path(representation)
node = rt.GetNodeByName(container["instance_node"])
abc_container = [n for n in get_previous_loaded_object(node)
if rt.ClassOf(n) == rt.AlembicContainer]
with maintained_selection():
rt.Select(node.Children)
rt.Select(abc_container)
for alembic in rt.Selection:
abc = rt.GetNodeByName(alembic.name)
update_custom_attribute_data(abc, abc.Children)
rt.Select(abc.Children)
for abc_con in abc.Children:
abc_con.source = path
rt.Select(abc_con.Children)
for abc_obj in abc_con.Children:
abc_obj.source = path
lib.imprint(
container["instance_node"],
{"representation": str(representation["_id"])},

View file

@ -2,11 +2,12 @@ import os
from openpype.hosts.max.api import lib, maintained_selection
from openpype.hosts.max.api.lib import (
unique_namespace, get_namespace
unique_namespace,
)
from openpype.hosts.max.api.pipeline import (
containerise,
import_custom_attribute_data,
get_previous_loaded_object,
update_custom_attribute_data
)
from openpype.pipeline import get_representation_path, load
@ -25,7 +26,6 @@ class PointCloudLoader(load.LoaderPlugin):
def load(self, context, name=None, namespace=None, data=None):
"""load point cloud by tyCache"""
from pymxs import runtime as rt
filepath = os.path.normpath(self.filepath_from_context(context))
obj = rt.tyCache()
obj.filename = filepath
@ -34,14 +34,10 @@ class PointCloudLoader(load.LoaderPlugin):
name + "_",
suffix="_",
)
prt_container = rt.Container(
name=f"{namespace}:{name}_{self.postfix}")
import_custom_attribute_data(prt_container, [obj])
obj.Parent = prt_container
obj.name = f"{namespace}:{obj.name}"
return containerise(
name, [prt_container], context,
name, [obj], context,
namespace, loader=self.__class__.__name__)
def update(self, container, representation):
@ -50,14 +46,12 @@ class PointCloudLoader(load.LoaderPlugin):
path = get_representation_path(representation)
node = rt.GetNodeByName(container["instance_node"])
namespace, name = get_namespace(container["instance_node"])
sub_node_name = f"{namespace}:{name}_{self.postfix}"
inst_container = rt.getNodeByName(sub_node_name)
node_list = get_previous_loaded_object(node)
update_custom_attribute_data(
inst_container, inst_container.Children)
node, node_list)
with maintained_selection():
rt.Select(node.Children)
for prt in inst_container.Children:
rt.Select(node_list)
for prt in rt.Selection:
prt.filename = path
lib.imprint(container["instance_node"], {
"representation": str(representation["_id"])

View file

@ -5,14 +5,16 @@ from openpype.pipeline import (
load,
get_representation_path
)
from openpype.pipeline.load import LoadError
from openpype.hosts.max.api.pipeline import (
containerise,
import_custom_attribute_data,
update_custom_attribute_data
update_custom_attribute_data,
get_previous_loaded_object
)
from openpype.hosts.max.api import lib
from openpype.hosts.max.api.lib import (
unique_namespace, get_namespace
unique_namespace,
get_plugins
)
@ -25,11 +27,12 @@ class RedshiftProxyLoader(load.LoaderPlugin):
order = -9
icon = "code-fork"
color = "white"
postfix = "param"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
plugin_info = get_plugins()
if "redshift4max.dlr" not in plugin_info:
raise LoadError("Redshift not loaded/installed in Max..")
filepath = self.filepath_from_context(context)
rs_proxy = rt.RedshiftProxy()
rs_proxy.file = filepath
@ -42,27 +45,22 @@ class RedshiftProxyLoader(load.LoaderPlugin):
name + "_",
suffix="_",
)
container = rt.Container(
name=f"{namespace}:{name}_{self.postfix}")
rs_proxy.Parent = container
rs_proxy.name = f"{namespace}:{rs_proxy.name}"
import_custom_attribute_data(container, [rs_proxy])
return containerise(
name, [container], context,
name, [rs_proxy], context,
namespace, loader=self.__class__.__name__)
def update(self, container, representation):
from pymxs import runtime as rt
path = get_representation_path(representation)
namespace, name = get_namespace(container["instance_node"])
sub_node_name = f"{namespace}:{name}_{self.postfix}"
inst_container = rt.getNodeByName(sub_node_name)
node = rt.getNodeByName(container["instance_node"])
node_list = get_previous_loaded_object(node)
rt.Select(node_list)
update_custom_attribute_data(
inst_container, inst_container.Children)
for proxy in inst_container.Children:
node, rt.Selection)
for proxy in rt.Selection:
proxy.file = path
lib.imprint(container["instance_node"], {