Beispiel #1
0
    def remove_selected_transforms_from_curve(self):
        if not self.current_node:
            return

        with maya_helpers.undo():
            selected_rows = set(
                idx.row() for idx in self.ui.transformList.selectedIndexes())
            if not selected_rows:
                return

            # Remember the first selection, so we can reselect it below.
            first_selected_dropdown_idx = min(selected_rows)

            curve = CreateCurve(self.current_node)
            transforms = curve.get_transforms()
            new_transforms = []
            for idx, transform in enumerate(transforms):
                if idx not in selected_rows:
                    new_transforms.append(transform)

            curve.set_transforms(new_transforms)

            # Refresh the list, and select the first index that was selected.  This way, if you delete
            # the first entry, we leave the new first entry selected instead of deselecting.
            self.refresh_all()
            self.select_transform_rows([first_selected_dropdown_idx])
Beispiel #2
0
    def create_and_select_node(self):
        """
        Create a new zCreateCurve node and an output curve.  Select the curve.
        
        If transforms are selected in the scene, add them to it.
        """
        with maya_helpers.undo():
            nodes = pm.ls(sl=True)
            attrs = self.get_matrix_from_nodes(nodes)

            # Create the curve.
            curve = CreateCurve.create()
            self.refresh_all()
            self.current_node = curve.node

            # Create a curve node.
            output_curve = curve.add_curve_output()

            # Add the transforms to it.
            curve = CreateCurve(self.current_node)
            curve.set_transforms(attrs)

            # Refresh and select the new curve.
            self.refresh_all()

            pm.select(output_curve.getTransform())
    def create_controller_for_selected_object(self):
        nodes = pm.ls(sl=True, type='transform')
        if not nodes:
            log.info('Select one or more objects to create a controller for')
            return

        with maya_helpers.undo():
            self.create_controller_for_objects(nodes)
Beispiel #4
0
    def frame_name_edited(self, widget):
        # How do you find out which item was edited?  QT's documentation is useless.
        items = self._ui.frameList.selectedItems()
        if not items:
            return
        item = items[0]

        with maya_helpers.undo():
            set_name_at_frame(item.frame, item.text())
Beispiel #5
0
def set_keyframe_with_time_editor(attr, inTangentType=None, outTangentType=None):
    """
    Set a keyframe, working around problems with the time editor.
    """
    def set_to_time_editor():
        keying_target = pm.timeEditorPanel('timeEditorPanel1TimeEd', q=True, keyingTarget=True)
        if not keying_target:
            return False

        # The time editor has weird native hooks for applying keyframes, which calls
        # teSetKeyFrameOnActiveLayerOrClip in teKeyingFunctions.mel.  It's very broken:
        # it looks at the channel box to see what to key, which causes it to key the wrong
        # attributes.  We can't just set what's shown in the channel box: that requires
        # changing the selection (which will screw with the graph editor), and we can't change
        # the selection and the channel box at the same time since the CB update is async.
        #
        # Instead, bypass all of that and set the key on the time editor layer directly.
        #
        # This means we can't control tangents on time editor clips, which sucks.
        keying_target = pm.ls(keying_target)[0]
        clip_id = keying_target.node().attr('clip[0].clipid').get()
        layer_id = keying_target.attr('layerId').get()
        is_layer = isinstance(keying_target.node(), pm.nodetypes.TimeEditorClip) and keying_target.attr('layerName').get() != ''
        if not is_layer:
            return False

        # timeEditorClipLayer doesn't take tangentType arguments like pm.setKeyframe, so we have
        # to work around this the long way by temporarily changing the default.
        old_in_tangent_type = pm.keyTangent(q=True, g=True, inTangentType=True)[0]
        old_out_tangent_type = pm.keyTangent(q=True, g=True, outTangentType=True)[0]
        if inTangentType is not None:
            pm.keyTangent(g=True, inTangentType=inTangentType)
        if outTangentType is not None:
            pm.keyTangent(g=True, outTangentType=outTangentType)

        try:
            # Set the key.
            pm.timeEditorClipLayer(e=True, clipId=clip_id, layerId=layer_id, setKeyframe=True, attribute=attr)
        finally:
            # Restore the tangent type.
            pm.keyTangent(g=True, inTangentType=old_in_tangent_type)
            pm.keyTangent(g=True, outTangentType=old_out_tangent_type)

        return True

    with maya_helpers.undo():
        if set_to_time_editor():
            return

        kwargs = {}
        if inTangentType is not None:
            kwargs['inTangentType'] = inTangentType
        if outTangentType is not None:
            kwargs['outTangentType'] = outTangentType
        pm.setKeyframe(attr, **kwargs)
Beispiel #6
0
    def delete_selected_frame(self):
        """
        Delete the frame that's selected in the list, if any.
        """
        item = self.get_selected_frame_item()
        if item is None:
            return

        self.cancel_rename()
        with maya_helpers.undo():
            delete_key_at_frame(item.frame)
    def dragged_from_maya(self, nodes, target, indicator_position):
        with maya_helpers.undo():
            # Create controllers for the nodes if they don't exist.
            self.create_controller_for_objects(nodes)

            for node in nodes:
                # See if there's a controller for this node.
                controller = get_controller_for_object(node)
                if not controller:
                    continue

                self.dragged_controller(controller, target, indicator_position)
Beispiel #8
0
    def dragged_internally(self, target, event, indicator_position):
        # We shouldn't get an internal drag with no selection (there's nothing to drag).
        if not self.current_node:
            return

        with maya_helpers.undo():
            # The position we're moving the selection to:
            pos = self.get_drag_target_idx(target, indicator_position)

            curve = CreateCurve(self.current_node)
            orig_transforms = curve.get_transforms()

            # The selected rows, and associated transforms:
            selected_rows = [
                idx.row() for idx in self.ui.transformList.selectedIndexes()
            ]
            selected_transforms = [
                orig_transforms[row] for row in selected_rows
            ]

            new_transforms = []
            output_idx = None
            for idx, transform in enumerate(orig_transforms):
                # If this is the position we're moving the selection to, add them.
                if idx == pos:
                    output_idx = len(new_transforms)
                    new_transforms.extend(selected_transforms)

                # If this transform isn't one of the ones we're moving, add it.
                if idx not in selected_rows:
                    new_transforms.append(transform)

            # If pos is at the end, we didn't add selected_transforms above, so do it now.
            if pos == len(orig_transforms):
                output_idx = len(new_transforms)
                new_transforms.extend(selected_transforms)

            curve.set_transforms(new_transforms)

            # Update the list so we can update the selection.
            self.populate_transform_list()

            # Reselect the items that we added.
            self.select_transform_rows(
                range(output_idx, output_idx + len(selected_transforms)))
Beispiel #9
0
    def add_transforms_to_curve(self, nodes, pos=0):
        """
        Insert nodes into the transform list at the given position.

        If pos is None, add at the end.
        """
        with maya_helpers.undo():
            curve = CreateCurve(self.current_node)
            attrs = self.get_matrix_from_nodes(nodes)

            # Add the attributes to the transform list.  We don't prevent adding duplicates.
            transforms = curve.get_transforms()
            if pos is None:
                pos = len(transforms)
            transforms[pos:pos] = attrs
            curve.set_transforms(transforms)

            # Refresh now, so we can select the new items.
            self.refresh_all()

            # Select the items that we added.
            self.select_transform_rows(range(pos, pos + len(nodes)))
Beispiel #10
0
    def add_new_frame(self):
        """
        Create a key if one doesn't exist already, and begin editing its name.
        """
        with maya_helpers.undo():
            # If we're editing, cancel editing before adding the new frame, or the
            # new frame won't be visible.  This can happen if you select a frame,
            # click Add, then select another frame and click Add without first
            # pressing enter for the first rename.  This usually only happens if
            # the window is docked into the main Maya window.
            self.cancel_rename()

            if not key_exists_at_frame(pm.currentTime(q=True)):
                frame = pm.currentTime(q=True)
                create_key_at_time(frame)
                set_name_at_frame(frame, 'Frame %i' % frame)

            # Our listeners will refresh automatically, but that won't happen until later.  Refresh
            # immediately, so we can initiate editing on the new item.
            self.refresh()

            # Find the new item and edit it to let the user set its name.
            self.rename_selected_frame()
 def create_controller_group(self):
     with maya_helpers.undo():
         self.create_controller_for_objects([None])
def set_controller_parent(controller, parent, after=None):
    """
    Set controller's parent to parent.

    If after is None, the node becomes the first child.  Otherwise, the node is placed
    after the given node.  If after is at_end, the node is placed at the end.

    controller -p should do this, but the docs don't really describe how it works and
    there doesn't seem to be any way to change the parent of a controller to be a root.
    """
    assert controller != parent

    if after is at_end:
        if parent is None:
            raise Exception('parent must be specified if after is at_end')

        # If there are any children, place controller after the last one.
        children = get_controller_children(parent)
        if children:
            after = children[-1]
        else:
            after = None

    with maya_helpers.undo():
        old_parent_plug = get_controller_parent(controller, get_plug=True)
        if old_parent_plug is None and parent is None:
            return

        if old_parent_plug is not None:
            # Unparent the controller from its old parent.
            if old_parent_plug.node().prepopulate.isConnectedTo(
                    controller.prepopulate):
                old_parent_plug.node().prepopulate.disconnect(
                    controller.prepopulate)

            # We need to reconnect all children and not just disconnect the child, since the
            # child list needs to remain contiguous.
            all_children = get_controller_children(old_parent_plug.node(),
                                                   disconnect_from_parent=True)
            all_children.remove(controller.node())
            assign_controller_children(old_parent_plug.node(), all_children)

        # If we're unparenting, we're done.
        if parent is None:
            return

        # Connect prepopulate.
        parent.prepopulate.connect(controller.prepopulate)

        # Get a list of all children of the parent, and disconnect them.
        all_children = get_controller_children(parent,
                                               disconnect_from_parent=True)

        # Insert our new child.  If we've been given a position to add it, use it.  Otherwise,
        # add to the beginning.
        if after is None or after not in all_children:
            all_children = [controller] + all_children
        else:
            idx = all_children.index(after) + 1
            all_children[idx:idx] = [controller]

        # Reconnect the children.
        assign_controller_children(parent, all_children)