Simple alembic loader for 3dsmax.
Because of limited api, alembics can be only loaded, but not easily updated.
AbcLoader
Bases: LoaderPlugin
Alembic loader.
Source code in client/ayon_max/plugins/load/load_pointcache.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 | class AbcLoader(load.LoaderPlugin):
"""Alembic loader."""
product_types = {"camera", "animation", "pointcache"}
label = "Load Alembic"
representations = {"abc"}
order = -10
icon = "code-fork"
color = "orange"
def load(self, context, name=None, namespace=None, data=None):
from pymxs import runtime as rt
file_path = self.filepath_from_context(context)
file_path = os.path.normpath(file_path)
abc_before = {
c
for c in rt.rootNode.Children
if rt.classOf(c) == rt.AlembicContainer
}
rt.AlembicImport.ImportToRoot = False
# TODO: it will be removed after the improvement
# on the post-system setup
reset_frame_range()
rt.importFile(file_path, rt.name("noPrompt"), using=rt.AlembicImport)
abc_after = {
c
for c in rt.rootNode.Children
if rt.classOf(c) == rt.AlembicContainer
}
# This should yield new AlembicContainer node
abc_containers = abc_after.difference(abc_before)
if len(abc_containers) != 1:
self.log.error("Something failed when loading.")
abc_container = abc_containers.pop()
selections = rt.GetCurrentSelection()
for abc in selections:
for cam_shape in abc.Children:
cam_shape.playbackType = 0
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}"
abc_container.name = abc_container_name
abc_objects.append(abc_container)
return containerise(
name, abc_objects, context,
namespace, loader=self.__class__.__name__
)
def update(self, container, context):
from pymxs import runtime as rt
repre_entity = context["representation"]
path = os.path.normpath(self.filepath_from_context(context))
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(abc_container)
for alembic in rt.Selection:
abc = rt.GetNodeByName(alembic.name)
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": repre_entity["id"],
"project_name": context["project"]["name"]
})
def switch(self, container, context):
self.update(container, context)
def remove(self, container):
from pymxs import runtime as rt
node = rt.GetNodeByName(container["instance_node"])
remove_container_data(node)
@staticmethod
def get_container_children(parent, type_name):
from pymxs import runtime as rt
def list_children(node):
children = []
for c in node.Children:
children.append(c)
children += list_children(c)
return children
filtered = []
for child in list_children(parent):
class_type = str(rt.classOf(child.baseObject))
if class_type == type_name:
filtered.append(child)
return filtered
|