Ejemplo n.º 1
0
def quick_pivot_align(source_node, target_node):
    """
    Aligns pivot in position and orientation
    :param source_node: str
    :param target_node: str
    """

    source_node = node_utils.get_pymxs_node(source_node)
    target_node = node_utils.get_pymxs_node(target_node)

    source_node.pivot = target_node.pivot
Ejemplo n.º 2
0
def parent_node(max_child_node, max_parent_node):
    """
    Parents child node into parent node hierarchy
    :param max_child_node: MaxPlus.INode
    :param max_parent_node: MaxPlus.INode
    """

    max_child_node = node.get_pymxs_node(max_child_node)
    max_parent_node = node.get_pymxs_node(max_parent_node)

    max_child_node.parent = max_parent_node

    return max_child_node
Ejemplo n.º 3
0
def quick_align(source_node, target_node, freeze=False):
    """
    Aligns to objects in position
    :param source_node: str
    :param target_node: str
    :param freeze: bool
    """

    source_node = node_utils.get_pymxs_node(source_node)
    target_node = node_utils.get_pymxs_node(target_node)

    source_node.position = target_node.position
    if freeze:
        freeze_transform(source_node)
Ejemplo n.º 4
0
def match_transforms(source_node, target_node, freeze=False):
    """
    Matches the transform of the source node to the transform of the target node
    :param source_node: str
    :param target_node: str
    :param freeze: bool
    """

    source_node = node_utils.get_pymxs_node(source_node)
    target_node = node_utils.get_pymxs_node(target_node)

    orig_xform = target_node.transform
    source_node.transform = orig_xform
    if freeze:
        freeze_transform(source_node)
Ejemplo n.º 5
0
def is_attribute_locked(node, attribute_name):
    """
    Returns whether given attribute is locked or not
    :param node: str
    :param attribute_name: str
    :return: bool
    """

    node = node_utils.get_pymxs_node(node)
    lock_flags = list(rt.getTransformLockFlags(node))

    xform_attrs = [
        max_constants.TRANSLATION_ATTR_NAME, max_constants.ROTATION_ATTR_NAME,
        max_constants.SCALE_ATTR_NAME
    ]
    for name, flags_list in zip(xform_attrs,
                                [[0, 1, 2], [3, 4, 5], [6, 7, 8]]):
        if name in attribute_name:
            if attribute_name == name:
                for flag_index in flags_list:
                    if not lock_flags[flag_index]:
                        return False
                return True
            else:
                for i, (axis, flag_value) in enumerate(zip('XYZ', flags_list)):
                    flag_index = flags_list[i]
                    if attribute_name == '{}{}'.format(
                            name, axis) and lock_flags[flag_index]:
                        return True

    return False
Ejemplo n.º 6
0
def set_bone_weight(skin_node, bone_id, vertex_id, weight):
    """
    Sets bone weights for skin modifier
    :param skin_node: str
    :param bone_id: int
    :param vertex_id: int
    :param weight: float
    """

    rt.subobjectLevel = 1
    skin_node = node_utils.get_pymxs_node(skin_node)
    if not skin_node:
        return
    skin_modifier = skin_node.modifiers[rt.Name('Skin')]
    if not skin_modifier:
        return
    vertex_bitarray = rt.BitArray()
    vertex_indices = [vertex_id]
    vertex_bitarray.count = len(vertex_indices)
    for i, index in enumerate(vertex_indices):
        vertex_bitarray[i] = index

    skin_modifier.filter_vertices = True
    rt.skinOps.SelectBone(skin_modifier, bone_id)
    rt.skinOps.SelectVertices(skin_modifier, vertex_bitarray)
    rt.skinOps.setWeight(skin_modifier, weight)
Ejemplo n.º 7
0
def freeze_transform(node_name):
    """
    Freezes the transform for the given node
    :param node_name: str
    """

    node = node_utils.get_pymxs_node(node_name)

    rotation_controller = rt.getPropertyController(node.controller, 'Rotation')
    position_controller = rt.getPropertyController(node.controller, 'Position')

    if rt.classOf(rotation_controller) != rt.Rotation_Layer:
        rotation_list_controller = rt.Rotation_List()
        rt.setPropertyController(node.controller, 'Rotation',
                                 rotation_list_controller)
        rt.setPropertyController(rotation_list_controller, 'Available',
                                 rt.Euler_Xyz())
        rotation_list_controller.setName(1, 'Frozen Rotation')
        rotation_list_controller.setName(2, 'Zero Euler XYZ')
        rotation_list_controller.setActive(2)

    if rt.classOf(position_controller) != rt.Position_Layer:
        position_list_controller = rt.Position_List()
        rt.setPropertyController(node.controller, 'Position',
                                 position_list_controller)
        pos_xyz_controller = rt.Position_XYZ()
        rt.setPropertyController(position_list_controller, 'Available',
                                 pos_xyz_controller)
        position_list_controller.setName(1, 'Frozen Position')
        position_list_controller.setName(2, 'Zero Pos XYZ')
        position_list_controller.setActive(2)
        pos_xyz_controller.x_Position = 0
        pos_xyz_controller.y_Position = 0
        pos_xyz_controller.z_Position = 0
Ejemplo n.º 8
0
def node_exists(node):
    """
    Returns whether given object exists or not
    :return: bool
    """

    node = node_utils.get_pymxs_node(node)
    return rt.isValidNode(node)
Ejemplo n.º 9
0
def match_position(source_node, target_node, freeze=False):
    """
    Matches the position of the source node to the position of the target node
    :param source_node: str
    :param target_node: str
    :param freeze: bool
    :return:
    """

    source_node = node_utils.get_pymxs_node(source_node)
    target_node = node_utils.get_pymxs_node(target_node)

    orig_xform = source_node.transform
    orig_xform.pos = target_node.transform.translationPart
    source_node.transform = orig_xform
    if freeze:
        freeze_transform(source_node)
Ejemplo n.º 10
0
def deselect_node(node):
    """
    Deselects given node from current selection
    :param node: str
    """

    node = node_utils.get_pymxs_node(node)
    return rt.deselect(node)
Ejemplo n.º 11
0
def link_object(source_node, parent_node, freeze=True, hierarchy=False):
    """
    Links an object and freezes it transforms (optional)
    :param source_node: str
    :param parent_node: str
    :param freeze: bool
    :param hierarchy:  bool
    """

    source_node = node_utils.get_pymxs_node(source_node)
    parent_node = node_utils.get_pymxs_node(parent_node)

    source_node.parent = parent_node
    if freeze:
        freeze_transform(source_node)
    if hierarchy:
        # TODO: Freeze character
        pass
Ejemplo n.º 12
0
    def _get_scope_list(self):
        """
        Internal function used to get the scope list for the increment string
        :return: list<str>
        """

        if node_utils.get_pymxs_node(self.increment_string):
            return [self.increment_string]

        return list()
Ejemplo n.º 13
0
def add_shape(curve_spline1, curve_spline2):
    """
    Combines given two curve splines
    :param curve_spline1:
    :param curve_spline2:
    :return:
    """

    curve_spline1 = node_utils.get_pymxs_node(curve_spline1)
    curve_spline2 = node_utils.get_pymxs_node(curve_spline2)

    if not curve_spline1 or not curve_spline2:
        return
    if not rt.isKindOf(curve_spline1, rt.SplineShape) or not rt.isKindOf(curve_spline2, rt.SplineShape):
        return
    rt.convertToSplineShape(curve_spline1)
    rt.convertToSplineShape(curve_spline2)
    rt.addAndWeld(curve_spline1, curve_spline2, -1)

    return curve_spline1
Ejemplo n.º 14
0
def reset_pivot_to_origin(node_name, align_to_world=False):
    """
    Resets the pivot of the given node to the origin of the world
    :param node_name:
    :param align_to_world:
    """

    node = node_utils.get_pymxs_node(node_name)
    node.pivot = rt.Point3(0, 0, 0)
    if align_to_world:
        rt.WorldAlignPivot(node)
Ejemplo n.º 15
0
def unparent_node(max_node):
    """
    Unparents given Max node
    :param max_node: MaxPlus.INode
    """

    max_node = node.get_pymxs_node(max_node)

    max_node.parent = None

    return max_node
Ejemplo n.º 16
0
def reset_xform_and_collapse(node_name, freeze=False):
    """
    Resets the xform and collapse the stack of the given node
    :param node_name: str
    :param freeze: bool
    """

    node = node_utils.get_pymxs_node(node_name)
    rt.ResetXForm(node)
    rt.CollapseStack(node)
    if freeze:
        freeze_transform(node)
Ejemplo n.º 17
0
def rename_node(node, new_name, **kwargs):
    """
    Renames given node with new given name
    :param node: str
    :param new_name: str
    :return: str
    """

    pymxs_node = node_utils.get_pymxs_node(node)
    pymxs_node.name = new_name

    return pymxs_node.name
Ejemplo n.º 18
0
def select_node(node, replace_selection=True, **kwargs):
    """
    Selects given object in the current scene
    :param replace_selection: bool
    :param node: str
    """

    node = node_utils.get_pymxs_node(node)

    if replace_selection:
        return rt.select(node)
    else:
        return rt.selectMore(node)
Ejemplo n.º 19
0
 def _find_unique_name(obj_name):
     node = node_utils.get_pymxs_node(obj_name)
     if not node:
         return obj_name
     unique = FindUniqueName(obj_name)
     unique.get_last_number(include_last_number)
     unique_name = unique.get()
     unique_name = rt.uniquename(unique_name)
     if do_rename:
         node.name = unique_name
         return node.name
     else:
         return unique_name
Ejemplo n.º 20
0
def get_attribute_value(node, attribute_name):
    """
    Returns the value of the given attribute in the given node
    :param node: str
    :param attribute_name: str
    :return: variant
    """

    node = node_utils.get_pymxs_node(node)

    try:
        return rt.getProperty(node, attribute_name)
    except Exception:
        return None
Ejemplo n.º 21
0
def select_nodes(max_nodes, add=False):
    """
    Select given Max nodes
    :param max_nodes: list<MaxPlus.INode>
    :param add: bool, Whether to add given node names to an existing selection or not
    """

    max_nodes = python.force_list(max_nodes)

    sel = list() if not add else list(rt.selection)
    for max_node in max_nodes:
        max_node = node.get_pymxs_node(max_node)
        sel.append(max_node)
    if not sel:
        return

    rt.select(sel)
Ejemplo n.º 22
0
def set_float_attribute_value(node,
                              attribute_name,
                              attribute_value,
                              clamp=False):
    """
    Sets the integer value of the given attribute in the given node
    :param node: str
    :param attribute_name: str
    :param attribute_value: int
    :param clamp: bool
    :return:
    """

    node = node_utils.get_pymxs_node(node)
    xform_attrs = [
        max_constants.TRANSLATION_ATTR_NAME, max_constants.ROTATION_ATTR_NAME,
        max_constants.SCALE_ATTR_NAME
    ]

    for xform_attr in xform_attrs:
        if xform_attr in attribute_name:
            xform = attribute_name[:-1]
            axis = attribute_name[-1]
            if axis.lower() not in max_constants.AXES:
                continue
            axis_index = max_constants.AXES.index(axis.lower())
            xform_controller = rt.getPropertyController(node.controller, xform)
            # TODO: For now we only support default transform controllers (Bezier Float for translation,
            # TODO: Euler_XYZ for rotation and Bezier Scale for scale). Support other controller types.

            if xform == max_constants.TRANSLATION_ATTR_NAME or xform == max_constants.ROTATION_ATTR_NAME:
                xform_channel = rt.getPropertyController(
                    xform_controller, '{} {}'.format(axis.lower(), xform))
                xform_channel.value = attribute_value
                return
            elif xform == max_constants.SCALE_ATTR_NAME:
                current_scale = xform_controller.value
                current_scale[axis_index] = attribute_value
                xform_controller.value = current_scale
                return

    try:
        return rt.setProperty(node, attribute_name, attribute_value)
    except Exception:
        pass
Ejemplo n.º 23
0
def unlock_scale_attributes(node):
    """
    Unlocks all scale transform attributes of the given node
    :param node: str
    """

    node = node_utils.get_pymxs_node(node)
    lock_flags = list(rt.getTransformLockFlags(node))
    lock_flags[6] = False
    lock_flags[7] = False
    lock_flags[8] = False
    to_bit_array = list()
    for i, elem in enumerate(lock_flags):
        if elem:
            to_bit_array.append(i + 1)
    ms_array = helpers.convert_python_list_to_maxscript_bit_array(to_bit_array)

    return rt.setTransformLockFlags(node, ms_array)
Ejemplo n.º 24
0
def move_node(node_name,
              amount=None,
              move_vertices=False,
              use_local_axis=True):
    """
    Moves given node
    :param node_name:
    :param amount:
    :param move_vertices:
    :param use_local_axis:
    :return:
    """

    node_to_move = node_utils.get_pymxs_node(node_name)
    if not node_to_move:
        return

    amount = amount or [0, 0, 0]
    if rt.classOf(amount) != rt.Point3:
        amount = rt.Point3(*amount)

    if move_vertices:
        xform_mod = rt.xform()
        rt.addModifier(node_to_move, xform_mod)
        rt.setProperty(xform_mod.gizmo, 'position', amount)
        rt.CollapseStack(node_to_move)
    else:
        if use_local_axis:
            coordsys = getattr(rt, '%coordsys_context')
            local_coordsys = rt.Name('local')
            prev_coordsys = coordsys(local_coordsys,
                                     None)  # store current coordsys
            rt.move(node_to_move, amount)  # this is done in local axis
            coordsys(prev_coordsys, None)  # restore previous coordsys
        else:
            rt.move(node_to_move, amount)
Ejemplo n.º 25
0
def create_bone(root_node,
                name='new_bone',
                target_node=None,
                parent=None,
                **kwargs):

    length = kwargs.pop('length', 10)
    width = kwargs.pop('width', 10)
    height = kwargs.pop('height', 10)
    color = kwargs.pop('color', [7, 7, 11])
    main_axis = kwargs.pop('main_axis', 'z')
    flip_main_axis = kwargs.pop('flip_main_axis', False)
    main_rot_axis = kwargs.pop('main_rot_axis', 'y')
    flip_main_rot_axis = kwargs.pop('flip_main_rot_axis', False)
    freeze = kwargs.pop('freeze', False)

    root_node = node_utils.get_pymxs_node(root_node)
    target_node = node_utils.get_pymxs_node(target_node)
    parent = node_utils.get_pymxs_node(parent)

    if not root_node or not node_utils.node_exists(root_node.name):
        logger.error('Bone could not be created!')
        return False

    if color and rt.classOf(color) != rt.color:
        color = rt.color(*color)
    if not color:
        color = rt.color(7, 7, 11)

    bone_name = rt.uniquename(name)
    bone_box = rt.box(name=bone_name,
                      lengthsegs=1,
                      widthsegs=1,
                      heightsegs=1,
                      length=length,
                      width=width,
                      height=height,
                      mapcoords=True,
                      isSelected=True)
    bone_box.wirecolor = color
    bone_box.boneEnable = True
    bone_box.boneAxis = rt.Name(main_axis.lower())

    main_axis_index = 0
    main_rot_index = 0
    if main_axis.lower() == 'y':
        main_axis_index = 1
    elif main_axis.lower() == 'z':
        main_axis_index = 2
    if main_rot_axis.lower() == 'y':
        main_rot_index = 1
    elif main_rot_axis.lower() == 'z':
        main_rot_index = 2

    xform_utils.match_transforms(bone_box, root_node)
    if target_node and node_utils.node_exists(target_node.name):
        temp_helper = rt.Point(pos=rt.Point3(0, 0, 0))
        xform_utils.match_position(temp_helper, bone_box)
        look_at_controller = rt.LookAt_Constraint()
        rt.setPropertyController(temp_helper.controller, 'Rotation',
                                 look_at_controller)
        look_at_controller.appendTarget(target_node, 1)
        look_at_controller.target_axis = main_axis_index
        look_at_controller.upnode_axis = 1
        look_at_controller.StoUP_axis = main_rot_index
        look_at_controller.target_axisFlip = flip_main_axis
        look_at_controller.StoUP_axisFlip = flip_main_rot_axis
        xform_utils.match_transforms(bone_box, temp_helper)
        rt.delete(temp_helper)
        bone_box.height = rt.distance(root_node, target_node)

    if parent:
        bone_box.parent = parent

    if freeze:
        xform_utils.freeze_transform(bone_box)

    return bone_box
Ejemplo n.º 26
0
def create_end_bone(parent_bone,
                    name='newBone',
                    snap_to=None,
                    match_to=None,
                    parent=None,
                    **kwargs):
    """
    Creates and end bone
    :param parent_bone:
    :param snap_to:
    :param match_to:
    :param name:
    :param parent:
    :return:
    """

    length = kwargs.pop('length', 10)
    width = kwargs.pop('width', 10)
    height = kwargs.pop('height', 5)
    color = kwargs.pop('color', [7, 7, 11])
    main_axis = kwargs.pop('main_axis', 'z')
    extrude = kwargs.pop('extrude', True)
    freeze = kwargs.pop('freeze', False)

    parent_bone = node_utils.get_pymxs_node(parent_bone)
    snap_to = node_utils.get_pymxs_node(snap_to)
    match_to = node_utils.get_pymxs_node(match_to)
    parent = node_utils.get_pymxs_node(parent)

    if not parent_bone or not node_utils.node_exists(parent_bone.name):
        logger.error('Bone could not be created!')
        return False

    if color and rt.classOf(color) != rt.color:
        color = rt.color(*color)
    if not color:
        color = rt.color(7, 7, 11)

    bone_name = rt.uniquename(name)
    bone_box = rt.box(name=bone_name,
                      lengthsegs=1,
                      widthsegs=1,
                      heightsegs=1,
                      length=length,
                      width=width,
                      height=height,
                      mapcoords=True,
                      isSelected=True)
    bone_box.wirecolor = color
    bone_box.boneEnable = True
    bone_box.boneAxis = rt.Name(main_axis.lower())
    xform_utils.match_transforms(bone_box, parent_bone)

    rt.SetCommandPanelTaskMode(rt.Name('modify'))
    rt.convertTo(bone_box, rt.PolyMeshObject)
    rt.subobjectLevel = 1
    vertex_bitarray = rt.BitArray()
    vertex_indices = [1, 2, 3, 4]
    vertex_bitarray.count = len(vertex_indices)
    for i, index in enumerate(vertex_indices):
        vertex_bitarray[i] = index
    bone_box.EditablePoly.SetSelection(rt.Name('Vertex'), vertex_bitarray)
    bone_box.EditablePoly.collapse(rt.Name('Vertex'))
    bone_box.EditablePoly.SetSelection(rt.Name('Vertex'), rt.BitArray())
    if extrude:
        rt.subobjectLevel = 4
        vertex_bitarray = rt.BitArray()
        vertex_indices = [1]
        vertex_bitarray.count = len(vertex_indices)
        for i, index in enumerate(vertex_indices):
            vertex_bitarray[i] = index
        bone_box.EditablePoly.SetSelection(rt.Name('Face'), vertex_bitarray)
        bone_box.EditablePoly.extrudeFaces(height)
        bone_box.EditablePoly.SetSelection(rt.Name('Vertex'), rt.BitArray())
    rt.subobjectLevel = 0

    if snap_to:
        xform_utils.match_position(bone_box, snap_to)
    if match_to:
        xform_utils.match_transforms(bone_box, match_to)

    if parent:
        bone_box.parent = parent

    if freeze:
        xform_utils.freeze_transform(bone_box)

    return bone_box