Skip to content

lib

get_node_by_name(node_name)

Get instance node/container node by name

Parameters:

Name Type Description Default
node_name str

node name

required
Source code in client/ayon_motionbuilder/api/lib.py
164
165
166
167
168
169
170
171
172
173
def get_node_by_name(node_name: str):
    """Get instance node/container node by name

    Args:
        node_name (str): node name
    """
    matching_sets = [s for s in FBSystem().Scene.Sets
                        if s.Name == node_name]
    node = next(iter(matching_sets), None)
    return node

get_selected_hierarchies(node, selection_data)

Get the hierarchies/children from the top group

Parameters:

Name Type Description Default
node FBObject

FBSystem().Scene.RootModel.Children

required
selection_data dict

data which stores the node selection

required
Source code in client/ayon_motionbuilder/api/lib.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def get_selected_hierarchies(node, selection_data):
    """Get the hierarchies/children from the top group

    Args:
        node (FBObject): FBSystem().Scene.RootModel.Children
        selection_data (dict): data which stores the node selection
    """
    selected = True
    if node.ClassName() in {
        "FBModel", "FBModelSkeleton", "FBModelMarker",
        "FBCamera", "FBModelNull"}:
            if selection_data:
                for name in selection_data.keys():
                    if node.Name == name:
                        selected = selection_data[name]
            node.Selected = selected
    for child in node.Children:
        get_selected_hierarchies(child, selection_data)

load_data_from_parameter(target_param)

Load the ayon data from parameter

Parameters:

Name Type Description Default
target_param FBListPropertyObject

parameter to store ayon data

required

Returns:

Name Type Description
dict

ayon-related data

Source code in client/ayon_motionbuilder/api/lib.py
232
233
234
235
236
237
238
239
240
241
242
243
def load_data_from_parameter(target_param):
    """Load the ayon data from parameter

    Args:
        target_param (FBListPropertyObject): parameter to store ayon data

    Returns:
        dict: ayon-related data
    """
    data = target_param.Data
    data = json.loads(data[len(JSON_PREFIX):])
    return data

lsattr(attr, value=None, root=None)

List nodes having attribute with specified value.

Parameters:

Name Type Description Default
attr str

Attribute name to match.

required
value (str, Optional)

Value to match, of omitted, all nodes with specified attribute are returned no matter of value.

None
root (str, Optional)

Root node name. If omitted, scene root is used.

None

Returns:

Type Description
list

list of nodes.

Source code in client/ayon_motionbuilder/api/lib.py
 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
def lsattr(
        attr: str,
        value: Union[str, None] = None,
        root: Union[str, None] = None) -> list:
    """List nodes having attribute with specified value.

    Args:
        attr (str): Attribute name to match.
        value (str, Optional): Value to match, of omitted, all nodes
            with specified attribute are returned no matter of value.
        root (str, Optional): Root node name. If omitted, scene root is used.

    Returns:
        list of nodes.
    """
    nodes = []
    for obj_sets in FBSystem().Scene.Sets:
        instances_param = obj_sets.PropertyList.Find("instances")
        if not instances_param:
            continue
        parsed_data = load_data_from_parameter(instances_param)
        if value and parsed_data.get(attr) == value:
            nodes.append(obj_sets)
        elif parsed_data.get(attr):
            nodes.append(obj_sets)
    return nodes

maintain_selection(selected_nodes)

Maintain selection during context

Parameters:

Name Type Description Default
selected_nodes FBObject

selected nodes

required
Source code in client/ayon_motionbuilder/api/lib.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
@contextlib.contextmanager
def maintain_selection(selected_nodes):
    """Maintain selection during context

    Args:
        selected_nodes (FBObject): selected nodes
    """
    origin_selection = []
    for node in selected_nodes:
        origin_selection.append((node, node.Selected))
        node.Selected = True

    try:
        yield

    finally:
        for item in origin_selection:
            node, selection = item
            node.Selected = selection

parsed_selected_hierarchies(node)

Parse the data to find the selected hierarchies Args: node (FBObject): FBSystem().Scene.RootModel.Children

Source code in client/ayon_motionbuilder/api/lib.py
196
197
198
199
200
201
202
203
204
205
206
207
208
def parsed_selected_hierarchies(node):
    """Parse the data to find the selected hierarchies
    Args:
        node (FBObject): FBSystem().Scene.RootModel.Children
    """
    selection_data = {}
    if node.ClassName() in {
        "FBModel", "FBModelSkeleton", "FBModelMarker",
        "FBCamera", "FBModelNull"}:
            selection_data[node.Name] = node.Selected
    for child in node.Children:
        parsed_selected_hierarchies(child)
    return selection_data

unique_namespace(namespace, format='%02d', prefix='', suffix='')

Return unique namespace

Parameters:

Name Type Description Default
namespace str

Name of namespace to consider

required
format str

Formatting of the given iteration number

'%02d'
suffix str

Only consider namespaces with this suffix.

''
con_suffix

max only, for finding the name of the master container

required

unique_namespace("bar")

bar01

unique_namespace(":hello")

:hello01

unique_namespace("bar:", suffix="_NS")

bar01_NS:

Source code in client/ayon_motionbuilder/api/lib.py
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
def unique_namespace(namespace, format="%02d",
                     prefix="", suffix=""):
    """Return unique namespace

    Arguments:
        namespace (str): Name of namespace to consider
        format (str, optional): Formatting of the given iteration number
        suffix (str, optional): Only consider namespaces with this suffix.
        con_suffix: max only, for finding the name of the master container

    >>> unique_namespace("bar")
    # bar01
    >>> unique_namespace(":hello")
    # :hello01
    >>> unique_namespace("bar:", suffix="_NS")
    # bar01_NS:

    """

    def current_namespace():
        current = namespace
        # When inside a namespace Max adds no trailing :
        if not current.endswith(":"):
            current += ":"
        return current

    # Always check against the absolute namespace root
    # There's no clash with :x if we're defining namespace :a:x
    ROOT = ":" if namespace.startswith(":") else current_namespace()

    # Strip trailing `:` tokens since we might want to add a suffix
    start = ":" if namespace.startswith(":") else ""
    end = ":" if namespace.endswith(":") else ""
    namespace = namespace.strip(":")
    if ":" in namespace:
        # Split off any nesting that we don't uniqify anyway.
        parents, namespace = namespace.rsplit(":", 1)
        start += parents + ":"
        ROOT += start

    iteration = 1
    increment_version = True
    while increment_version:
        nr_namespace = namespace + format % iteration
        unique = prefix + nr_namespace + suffix
        cl = FBComponentList()
        FBFindObjectsByName((f"{unique}:*"), cl, True, True)
        if not cl:
            name_space = start + unique + end
            increment_version = False
            return name_space
        else:
            increment_version = True
        iteration += 1