Exemple #1
0
def remove_external_axis(*args):
    """
    Removes external axis from the robot it's attached to by deleting all of
    its attributes. The axis controller and models are preserved.
    This function just breaks the connection between the robot and the axis
    :param *args: required by Maya UI
    :return:
    """

    # Get the selected item from the Mimic UI
    selection = pm.textScrollList('tsl_externalAxes',
                                  selectItem=True,
                                  query=True)[0]

    # Split the selection into the robot's name and the external axis name
    robot, axis_name = selection.split(': ')

    target_CTRL = '{}|robot_GRP|target_CTRL'.format(robot)

    parent_attribute = '{}.externalAxis_{}'.format(target_CTRL, axis_name)

    # Remove connections between the axis controller and the robot
    external_axis_attribute_path = target_CTRL + '.' + axis_name
    external_axis_CTRL, driving_attribute = _get_external_axis_connections(
        external_axis_attribute_path)
    driving_axis = driving_attribute[-1]
    # Prep transformation string for Maya's limit attributes
    if 'translate' in driving_attribute:
        driving_attribute_trunc = 'Trans'
    else:
        driving_attribute_trunc = 'Rot'
    _enable_external_axis_limits(external_axis_CTRL,
                                 driving_attribute_trunc,
                                 driving_axis,
                                 enable=False)

    # Delete External Axis attribute on the robot controller
    pm.deleteAttr(parent_attribute)

    # Clear the axis from the Mimic UI selection and reset the UI
    pm.textScrollList('tsl_externalAxes',
                      edit=True,
                      removeItem=selection)
    if not pm.textScrollList('tsl_externalAxes',
                             query=True,
                             numberOfItems=True):
        reset_external_axis_UI()

    '''
    # NEEDS Attention. This deletes parent constraint even if the axis
    # being removed isn't the one the robot is attached to
    if _check_if_robot_is_attached_to_external_axis(robot):
        pm.delete('{}|robot_GRP|local_CTRL|' \
                  'localCTRL_externalAxisCTRL_parentConstraint'
                  .format(robot))
        pm.setAttr('{}|robot_GRP|local_CTRL.visibility'.format(robot), 1)
    '''

    pm.headsUpMessage('External Axis \'{}\' removed successfully from {}'
                      .format(axis_name, robot))
def matchIkToFk(ikControl, ikPole, offset=100.0, msgAttr='fkjoints', autoKey=True):
    """
    Matches ikControl and ikPole Vector control to match the current pose of underlying
    fk duplicate joint chains
    Finds the fk joints using a previously created message connection to the attribute msgAttr
    """

    fkJoints = pmc.listConnections('{0}.{1}'.format(ikControl, msgAttr),
                                   destination=False, source=True)

    attr = pmc.listConnections('{0}.ikfk'.format(ikControl), destination=False,
                               source=True, plugs=True, scn=True)[0]
    switchControl = attr.node()
    switchAttr = attr.name(includeNode=False)

    frameBeforeCurrent = pmc.currentTime(q=True) - 1
    if autoKey:
        pmc.setKeyframe(switchControl, attribute=switchAttr, time=frameBeforeCurrent,
                        value=1, outTangentType='step')
        pmc.setKeyframe([ikControl, ikPole], time=frameBeforeCurrent, outTangentType='step')

        pmc.setKeyframe(switchControl, attribute=switchAttr, value=0, outTangentType='step')

    alignObjects(ikControl, fkJoints[-1])
    loc = getPoleVectorPosition(fkJoints, offset, curveGuide=False)
    alignObjects(ikPole, loc, position=True, rotation=False)
    pmc.delete(loc)

    if autoKey:
        pmc.setKeyframe([ikControl, ikPole], time=frameBeforeCurrent)

    pmc.headsUpMessage('BAMF!')
def ec_zero(attr="all"):
    selection = mc.ls(sl=True, type='transform')
    try:
        if attr == "sx" or attr == "sy" or attr == "sz":
            for i in range(0, len(selection)):
                mc.setAttr(selection[i]+"."+attr, 1.0)
        elif attr == "s":
            for i in range(0, len(selection)):
                mc.setAttr(selection[i]+"."+attr, 1, 1, 1, type="double3")
        elif attr == "all":
            for i in range(0, len(selection)):
                listat = mc.listAttr(selection[i], v=True, k=True)
                print "listat :"
                if listat is None:
                    print "ERROR: listat is None : %s" % selection[i]
                else:
                    for k in range(0, len(listat)):
                        if listat[k] == "scaleX" or listat[k] == "scaleY" or listat[k] == "scaleZ" or listat[k] == "scale" or\
                                        listat[k] == "visibility":
                            mc.setAttr(selection[i]+"."+listat[k], 1.0)
                        else:
                            mc.setAttr(selection[i]+"."+listat[k], 0.0)
        else:
            if attr == "t" or attr == "r":
                for i in range(0, len(selection)):
                    mc.setAttr(selection[i]+"."+attr, 0.0, 0.0, 0.0, type="double3")
            else:
                for i in range(0, len(selection)):
                    mc.setAttr(selection[i]+"."+attr, 0.0)
        py.headsUpMessage("Reset: %s attribute of object %s" % (attr, selection))
    except:
        py.warning("ERROR: %s attribute of %s is locked or otherwise unavailable to reset" % (attr, selection[i]))
def toggleEnvelope():
    ssn = pm.optionMenu("selectedSSNode_menu", q=True, v=True)
    attr = ssn + ".envelope"

    if pm.getAttr(attr) == True:
        pm.setAttr(attr, False)
        pm.headsUpMessage("Shot Sculpt Disabled")

    elif pm.getAttr(attr) == False:
        pm.setAttr(attr, True)
        pm.headsUpMessage("Shot Sculpt Enabled")
Exemple #5
0
    def create_wall(self):
        selection = pm.selected()
        if not selection:
            msg = "Select the root of the base flap hierarchy"
            pm.headsUpMessage(msg)
            raise Exception(msg)

        with undo_chunk(auto_undo=True):
            SplitFlapWall.create(
                SplitFlap(selection[0]), padding=(self.padding.value(), -self.padding.value() * 0.5)
            ).make_dynamic()
Exemple #6
0
    def bake(self):

        minFrame = int(pm.playbackOptions(q=1,min=1))
        maxFrame = int(pm.playbackOptions(q=1,max=1))
        selectSet = pm.ls('*:bake_set*',typ='objectSet')
        if selectSet == []:
            pm.headsUpMessage( '???' )
        else:
            bakeList = []
            for x in selectSet:
                for y in x.flattened():
                    bakeList.append(y)
            pm.bakeResults(bakeList, sm=1, t=(minFrame, maxFrame), sb=1, pok=1, sac=0, bol=0, at=['tx','ty','tz','rx','ry','rz','sx','sy','sz'])
Exemple #7
0
def list_axes(*args):
    """

    :param args:
    :return:
    """
    # Clear previus UI list
    clear_external_axis_list()

    # Check viewport robot selection
    # If robots are selected, list all external axes on selected robots
    selected_robots = mimic_utils.get_robot_roots()
    if selected_robots:
        robots = selected_robots
    # If no robots are selected, list all axes in the scene
    else:
        robots_in_scene = mimic_utils.get_robot_roots(all_robots=True)
        # If there are no robots in the scene, raise an exception
        if not robots_in_scene:
            raise MimicError('No robots in scene')
        else:
            robots = robots_in_scene

    # Keep track of selected robots without axes for a heads-up message
    selected_robots_without_axes = []

    # For each robots, get a list of all its external axes
    for robot in robots:
        robots_external_axes = get_external_axis_names(robot)

        # If we're only looking at selected robots, check if each selected
        # robot has external axes. If not, add it to a list to display in
        # a heads up message
        if selected_robots:
            if not robots_external_axes:
                selected_robots_without_axes.append(robot)

        # Update Mimic UI with list of external axes
        for axis in robots_external_axes:
            append_string = robot + ': ' + axis
            pm.textScrollList('tsl_externalAxes',
                              edit=True,
                              append=append_string)

    if selected_robots_without_axes:
        robot_list_str = ''
        for each in selected_robots_without_axes:
            robot_list_str += each + ', '

        pm.headsUpMessage('{} has no External Axes'
                          .format(robot_list_str))
	def SelectBlueprintJoint_callBack(self):
		
		selection = pm.ls(selection = True)
		self.blueprintJoints = self.FindBlueprintJoints(selection)
		
		
		if self.blueprintJoints == None:
			pm.confirmDialog(title = "Attach Geometry to Blueprint", message = "Blueprint joint selection invalid. \nTerminating tool.", button = ["Accept"], defaultButton = "Accept")
		
		elif self.geometry == None:
			pm.headsUpMessage("Please select the geometry you wish to attach to the specified blueprint joint(s).")
			pm.scriptJob(event = ["SelectionChanged", self.SelectGeometry_callBack], runOnce = True)
		
		else:
			self.AttachGeometryToBlueprint_attachment()
def matchFkToIk(fkControls, msgAttr='ikjoints', autoKey=True):
    """
    Matches fkControls to match the current pose of the underlying ik duplicate joint chains
    Finds the ik joints using a previously created message connection to the attribute msgAttr
    """

    ikJoints = None
    switchControl = None
    switchAttr = None
    for ctl in fkControls:
        if pmc.hasAttr(ctl, msgAttr):
            ikJoints = pmc.listConnections('{0}.{1}'.format(ctl, msgAttr),
                                           destination=False,
                                           source=True)

            attr = pmc.listConnections('{0}.ikfk'.format(ctl),
                                       destination=False,
                                       source=True,
                                       plugs=True,
                                       scn=True)[0]
            switchControl = attr.node()
            switchAttr = attr.name(includeNode=False)
            break

    if autoKey:
        frameBeforeCurrent = pmc.currentTime(q=True) - 1
        pmc.setKeyframe(switchControl,
                        attribute=switchAttr,
                        time=frameBeforeCurrent,
                        value=0,
                        outTangentType='step')
        pmc.setKeyframe(fkControls,
                        attribute='rotate',
                        time=frameBeforeCurrent,
                        outTangentType='step')

        pmc.setKeyframe(switchControl,
                        attribute=switchAttr,
                        value=1,
                        outTangentType='step')

    for ikj, ctl in izip(ikJoints, fkControls):
        alignObjects(ctl, ikj, position=False, rotation=True)

    if autoKey:
        pmc.setKeyframe(fkControls, attribute='rotate')

    pmc.headsUpMessage('BAMF!')
def matchIkToFk(ikControl,
                ikPole,
                offset=100.0,
                msgAttr='fkjoints',
                autoKey=True):
    """
    Matches ikControl and ikPole Vector control to match the current pose of underlying
    fk duplicate joint chains
    Finds the fk joints using a previously created message connection to the attribute msgAttr
    """

    fkJoints = pmc.listConnections('{0}.{1}'.format(ikControl, msgAttr),
                                   destination=False,
                                   source=True)

    attr = pmc.listConnections('{0}.ikfk'.format(ikControl),
                               destination=False,
                               source=True,
                               plugs=True,
                               scn=True)[0]
    switchControl = attr.node()
    switchAttr = attr.name(includeNode=False)

    frameBeforeCurrent = pmc.currentTime(q=True) - 1
    if autoKey:
        pmc.setKeyframe(switchControl,
                        attribute=switchAttr,
                        time=frameBeforeCurrent,
                        value=1,
                        outTangentType='step')
        pmc.setKeyframe([ikControl, ikPole],
                        time=frameBeforeCurrent,
                        outTangentType='step')

        pmc.setKeyframe(switchControl,
                        attribute=switchAttr,
                        value=0,
                        outTangentType='step')

    alignObjects(ikControl, fkJoints[-1])
    loc = getPoleVectorPosition(fkJoints, offset, curveGuide=False)
    alignObjects(ikPole, loc, position=True, rotation=False)
    pmc.delete(loc)

    if autoKey:
        pmc.setKeyframe([ikControl, ikPole], time=frameBeforeCurrent)

    pmc.headsUpMessage('BAMF!')
Exemple #11
0
    def create_base_flaps(self):

        selection = pm.selected()
        if not selection:
            msg = "Select a base mesh to use for the flaps"
            pm.headsUpMessage(msg)
            raise Exception("Select a base mesh to use for the flaps")

        with undo_chunk(auto_undo=True):
            SplitFlap.create(
                base_flaps=selection,
                num_images=self.num_images.value(),
                rows=self.rows.value(),
                columns=self.columns.value(),
                radius=self.radius.value(),
            )
Exemple #12
0
def _add_mFIZ_attrs_as_outputs(robot):
    """
    """
    # First, we get the IO numbers currently assigned to the robot and increment
    # ours by 1 to avoid conflicts
    io_numbers = []
    robots_ios = get_io_names(robot)

    target_ctrl_path = mimic_utils.get_target_ctrl_path(robot)

    for io_name in robots_ios:
        io_numbers.append(
            pm.getAttr('{}.{}_ioNumber'.format(target_ctrl_path, io_name)))

    if io_numbers:
        io_number = max(io_numbers) + 1
    else:
        io_number = 1

    # For each FIZ Attribute, create and add IO to the robot
    postproc_id = 0  # Begin postproc_ID attr increment

    fiz_attrs = FIZ_ATTRS

    for attr in fiz_attrs:

        io_param_dict = {}

        io_param_dict['IO Name'] = attr
        io_param_dict['Postproc ID'] = str(postproc_id)
        io_param_dict['IO Number'] = io_number
        io_param_dict['Type'] = 'digital'
        io_param_dict['Resolution'] = '16-bit'
        io_param_dict['Ignore'] = False

        add_io(io_params=io_param_dict)

        io_number += 1
        postproc_id += 16

    pm.headsUpMessage('FIZ outputs added successfully to {}'.format(robot))
	def ProcessInitialSelection(self):
		
		selection = pm.ls(selection = True)
		
		self.blueprintJoints = []
		self.geometry = []
		
		self.blueprintJoints = self.FindBlueprintJoints(selection)
		self.geometry = self.FindGeometry(selection)
		
		
		if self.blueprintJoints == None:
			pm.headsUpMessage("Please select the blueprint joint(s) you wish to attach geometry to.")
			pm.scriptJob(event = ["SelectionChanged", self.SelectBlueprintJoint_callBack], runOnce = True)
		
		elif self.geometry == None:
			pm.headsUpMessage("Please select the geometry you wish to attach to the specified blueprint joint.")
			pm.scriptJob(event = ["SelectionChanged", self.SelectGeometry_callBack], runOnce = True)
		
		else:
			self.AttachGeometryToBlueprint_attachment()
Exemple #14
0
def mirror_locators(**kwargs):
    file_name = kwargs.setdefault('filename')
    unmirror = kwargs.setdefault('unmirror', False)
    file_list = ['up_eye', 'low_eye', 'cheek', 'up_mouth', 'low_mouth']
    if unmirror is False:
        if file_name == 'all':
            for i in range(0, len(file_list)):
                file_path = get_file_path('expressions/%s' % file_list[i])
                with open(file_path) as myfile:
                    expressionData = myfile.read()
                mc.expression(string=expressionData, name="%s_Expression" % file_list[i], ae=1, uc='all')
            py.headsUpMessage('Mirroring for all enabled. Must unmirror to reset locations')
        else:
            file_path = get_file_path('expressions/%s' % file_name)
            with open(file_path) as myfile:
                expressionData = myfile.read()
            mc.expression(string=expressionData, name="%s_Expression" % file_name, ae=1, uc='all')
            py.headsUpMessage('Mirroring for %s enabled. Must unmirror to reset locations' % file_name)
    else:
        for i in range(0, len(file_list)):
            try:
                mc.delete('%s_Expression' % file_list[i])
            except:
                pass
        py.headsUpMessage('Mirroring disabled')
Exemple #15
0
def replaceController2Cube():

    for origin in pm.ls(sl=1, v=1, ni=1):
        origin_shape = origin.getShape(type="nurbsCurve")
        if not origin_shape:
            pm.warning(u"找不到曲线 %s" % origin)
            pm.headsUpMessage(u"找不到曲线 %s" % origin)
            continue

        jnt_list = []
        for constraint in set(origin.listConnections(type="constraint")):
            if constraint.type() in [
                    "aimConstraint", "tangentConstraint", "normalConstraint"
            ]:
                continue

            for jnt in constraint.listConnections(type='joint'):
                if jnt not in jnt_list:
                    jnt_list.append(jnt)

        if not jnt_list:
            pm.warning(u"找不到骨骼 %s" % origin)
            pm.headsUpMessage(u"找不到骨骼 %s" % origin)
            continue

        start_jnt = jnt_list[0]

        child_list = pm.ls(start_jnt, dag=1, type="joint")

        if len(child_list) >= 2:
            # NOTE 获取层级之下的骨骼(0是自己)
            end_jnt = child_list[1]

            start_pt = dt.Point(*pm.xform(start_jnt, q=1, ws=1, t=1))
            end_pt = dt.Point(*pm.xform(end_jnt, q=1, ws=1, t=1))

            crv = generateCubeFromVector(start_pt, end_pt, origin)

            shape = crv.getShape()
            # NOTE 设置颜色
            if origin_shape.overrideEnabled.get():
                shape.overrideEnabled.set(1)
                if origin_shape.overrideRGBColors.get():
                    color = origin_shape.overrideColorRGB.get()
                    shape.overrideColorRGB.set(color)
                else:
                    color = origin_shape.overrideColor.get()
                    shape.overrideColor.set(color)

            pm.parent(shape, origin, r=1, s=1)
            pm.delete(crv)
            name = origin_shape.name()
            pm.delete(origin_shape)
            shape.rename(name)
        else:
            # NOTE 说明层之下没有骨骼了
            pm.warning(u"找不到下层级骨骼 %s" % origin)
            pm.headsUpMessage(u"找不到下层级骨骼 %s" % origin)
def matchFkToIk(fkControls, msgAttr='ikjoints', autoKey=True):
    """
    Matches fkControls to match the current pose of the underlying ik duplicate joint chains
    Finds the ik joints using a previously created message connection to the attribute msgAttr
    """

    ikJoints = None
    switchControl = None
    switchAttr = None
    for ctl in fkControls:
        if pmc.hasAttr(ctl, msgAttr):
            ikJoints = pmc.listConnections('{0}.{1}'.format(ctl, msgAttr),
                                           destination=False, source=True)

            attr = pmc.listConnections('{0}.ikfk'.format(ctl), destination=False,
                                       source=True, plugs=True, scn=True)[0]
            switchControl = attr.node()
            switchAttr = attr.name(includeNode=False)
            break

    if autoKey:
        frameBeforeCurrent = pmc.currentTime(q=True) - 1
        pmc.setKeyframe(switchControl, attribute=switchAttr, time=frameBeforeCurrent,
                        value=0, outTangentType='step')
        pmc.setKeyframe(fkControls, attribute='rotate', time=frameBeforeCurrent,
                        outTangentType='step')

        pmc.setKeyframe(switchControl, attribute=switchAttr, value=1, outTangentType='step')

    for ikj, ctl in izip(ikJoints, fkControls):
        alignObjects(ctl, ikj, position=False, rotation=True)

    if autoKey:
        pmc.setKeyframe(fkControls, attribute='rotate')

    pmc.headsUpMessage('BAMF!')
Exemple #17
0
def create_facial_panel(offset=6.5):
    rm.create_bs_ctl()
    pm.headsUpMessage("Create Facial BlendShape Control", time=0.2)
    pm.refresh()
    sleep(0.1)
    facial_panelGp = ul.get_node('facial_panelGp')
    panel_pos = facial_panelGp.getTranslation('world')
    headBone = ul.get_node('CH_Head')
    headBone_pos = headBone.getTranslation('world')
    facial_panelGp.setTranslation([panel_pos[0], headBone_pos[1]+offset , panel_pos[2]], 'world')
    pm.headsUpMessage("Snap Control to Head", time=0.2)
    pm.refresh()
    sleep(0.1)
    import_facialtarget()
    pm.headsUpMessage("Import BlendShape and connect to control", time=0.2)
    pm.refresh()
    sleep(0.1)
    pm.parentConstraint('CH_Head', 'facial_panelGp', mo=True)
    pm.headsUpMessage("Parent Constraint facial_panelGp to head bone", time=0.2)
    pm.refresh()
    sleep(0.1)
Exemple #18
0
    def detect_topology(self):
        curr = time.time()

        sellist = [mesh for mesh in pm.ls(pm.pickWalk(d="down"), type="mesh")
                   ]  # pm.ls  返回场景中被选中的对象
        # pickWalk命令允许您相对于当前选定的节点快速更改选择列表

        if len(sellist) != 2:
            pm.headsUpMessage(u"请选中两个对象")
            return 0

        self.lineEdit_pointNum.clear()
        self.lineEdit_edgeNum.clear()
        self.lineEdit_faceNum.clear()
        self.textEdit_transInfor1.clear()
        self.textEdit_transInfor2.clear()

        W = True  # 拓扑是否一致
        numlist = [(sel.numVertices(), sel.numEdges(), sel.numFaces())
                   for sel in sellist]  # num_list是2*3的列表

        # 点、线、面数量不一至,拓扑肯定不一样
        if numlist[0][0] != numlist[1][0]:
            W = False
            x = numlist[0][0] - numlist[1][0]
            self.lineEdit_pointNum.setText(str(x))
        if numlist[0][1] != numlist[1][1]:
            W = False
            x = numlist[0][0] - numlist[1][0]
            self.lineEdit_edgeNum.setText(str(x))
        if numlist[0][2] != numlist[1][2]:
            W = False
            x = numlist[0][0] - numlist[1][0]
            self.lineEdit_faceNum.setText(str(x))

        if numlist[0][1] > numlist[1][1]:
            sellist.reverse()
            edgenum = numlist[1][1]
        else:
            edgenum = numlist[0][1]
        # 把数量小的换到前面

        res_list = []
        dif_list1 = []
        dif_list2 = []
        for i, sel in enumerate(sellist):  # enumerate() 列出数据和数据下标 (0, mesh1)

            edgeLoop_list = []
            edge_list = set(range(edgenum))

            while len(edge_list) > 1:
                idx = next(iter(edge_list),
                           None)  # iter() 函数用来生成迭代器  next()返回迭代器的下一个项目

                if idx is None: break
                edge_loop_1 = pm.polySelect(sel, edgeLoop=idx, ns=1)  #

                edgeLoop_list.append(edge_loop_1)  # 遍历过的边的列表添加进循环边的表
                edge_list -= set(edge_loop_1)  # 遍历过的边删去

                # NOTE 这里先判断一下同一个边序号获取的循环边数组是否一致
                if i != 0: continue

                edge_loop_2 = pm.polySelect(sellist[1].e[edge_loop_1[0]],
                                            edgeLoop=idx,
                                            ns=1)
                # 第二个对象的第idx条循环边

                if edge_loop_2 != edge_loop_1:
                    dif_list1.append(edge_loop_1)
                    dif_list2.append(edge_loop_2)

            res_list.append(edgeLoop_list)

        W = (res_list[0] == res_list[1])

        if not W:

            for edgeloops in dif_list1:
                self.textEdit_transInfor1.append(str(edgeloops))
                self.textEdit_transInfor1.append(u"  ")

            for edgeloops in dif_list2:
                self.textEdit_transInfor2.append(str(edgeloops))
                self.textEdit_transInfor2.append(u"  ")

            pm.select([
                "%s.e[%s]" % (sellist[0], e) for sel in dif_list1 for e in sel
            ],
                      r=1)
            pm.select([
                "%s.e[%s]" % (sellist[1], e) for sel in dif_list2 for e in sel
            ],
                      add=1)
            self.lineEdit_result.setText(u"拓扑不一致")
        else:
            self.lineEdit_result.setText(u"拓扑一致")

        self.lineEdit_time.setText(str(time.time() - curr))
Exemple #19
0
def update_external_axis(*args):
    """
    Update external axis in Mimic.
    :param args:
    :return:
    """
    # Get the selected item from the Mimic UI
    selection = pm.textScrollList('tsl_externalAxes',
                                  selectItem=True,
                                  query=True)[0]

    # Split the selection into the robot's name and the external axis name
    robot, axis_name = selection.split(': ')

    external_axis_params = _get_external_axis_params()

    axis_number = external_axis_params['Axis Number']
    driving_attribute = external_axis_params['Driving Attribute']
    position_limit_min = external_axis_params['Position Limit Min']
    position_limit_max = external_axis_params['Position Limit Max']
    velocity_limit = external_axis_params['Velocity Limit']
    attach_robot_to_external = external_axis_params['Attach']
    ingnore_in_postproc = external_axis_params['Ignore']

    target_CTRL = '{}|robot_GRP|target_CTRL'.format(robot)

    # Set all External Axis attributes accordingly
    axis_parent_attribute = target_CTRL + '.' + axis_name

    # Check that the external axis number is unique
    if axis_number == pm.getAttr(axis_parent_attribute + '_axisNumber'):
        pass
    else:
        _check_external_axis_number(robot, axis_number)

    # If attach to robot is true, parent the robot's local control to the
    # external axis controller
    if attach_robot_to_external:
        # Check if the robot is already attached to an external axis controller
        if _check_if_robot_is_attached_to_external_axis(robot):
            raise MimicError('{} is already attached to an external ' \
                             'axis controller'.format(robot))
        # Get and check the proper controllers from viewport selection
        _, external_axis_CTRL = _get_selection_input()
        _attach_robot_to_external_axis(robot, external_axis_CTRL)

    # Check if our driving attribute needs to be updated. If not, do nothing
    # If so, update the connection
    axis_attribute_name = '{}|robot_GRP|target_CTRL.{}' \
        .format(robot, axis_name)
    external_axis_CTRL, old_driving_attribute = _get_external_axis_connections(axis_attribute_name)
    if old_driving_attribute == driving_attribute:
        pass
    else:
        # Connect position attribute to driving attribute
        old_driving_attribute_path = external_axis_CTRL + '.' + old_driving_attribute
        new_driving_attribute_path = external_axis_CTRL + '.' + driving_attribute
        destination_attribute_name = axis_parent_attribute + '_position'
        pm.disconnectAttr(old_driving_attribute_path, destination_attribute_name)
        pm.connectAttr(new_driving_attribute_path, destination_attribute_name)

        # Update the external axis' position/rotation limits
        # Find the original driving attribute and disable it's axis limits
        _clear_external_axis_CTRL_limits(robot,
                                         external_axis_CTRL,
                                         old_driving_attribute,
                                         axis_name)

        _set_external_axis_CTRL_limits(robot,
                                       external_axis_CTRL,
                                       external_axis_params)

    # If the driving attribute is a translate attribute, we convert the user
    # input from millimeters to Maya's default unit of centimeters
    if 'translate' in driving_attribute:
        position_limit_min = position_limit_min / 10
        position_limit_max = position_limit_max / 10

    # Set all appropriate attributes on the robot
    pm.setAttr(axis_parent_attribute + '_axisNumber', lock=False)
    pm.setAttr(axis_parent_attribute + '_axisNumber', axis_number, lock=True)
    pm.setAttr(axis_parent_attribute + '_axisMin', position_limit_min)
    pm.setAttr(axis_parent_attribute + '_axisMax', position_limit_max)
    pm.setAttr(axis_parent_attribute + '_maxVelocity', velocity_limit)
    pm.setAttr(axis_parent_attribute + '_ignore', ingnore_in_postproc)

    # Select the external axis
    pm.select(external_axis_CTRL)

    pm.headsUpMessage('{}: Axis \'{}\' successfully updated'
                      .format(robot, axis_name))
Exemple #20
0
def add_external_axis(*args):
    """
    Add an external axis to Mimic.
    :param args:
    :return:
    """
    # Get the External Axis' parameters from the Mimic UI
    external_axis_params = _get_external_axis_params()

    axis_name = external_axis_params['Axis Name']
    axis_number = external_axis_params['Axis Number']
    driving_attribute = external_axis_params['Driving Attribute']
    position_limit_min = external_axis_params['Position Limit Min']
    position_limit_max = external_axis_params['Position Limit Max']
    velocity_limit = external_axis_params['Velocity Limit']
    attach_robot_to_external = external_axis_params['Attach']
    ingnore_in_postproc = external_axis_params['Ignore']

    # Get and check the proper controllers from viewport selection
    robot, external_axis_CTRL = _get_selection_input()

    target_CTRL = '{}|robot_GRP|target_CTRL'.format(robot)

    # Ensure axis name is unique
    _check_external_axis_name(robot, axis_name)

    # Check that the external axis number is unique
    _check_external_axis_number(robot, axis_number)

    # If attach to robot is true, parent the robot's local control to the
    # external axis controller
    if attach_robot_to_external:
        if _check_if_robot_is_attached_to_external_axis(robot):
            raise MimicError('{} is already attached to an external ' \
                             'axis controller'.format(robot))
        _attach_robot_to_external_axis(robot, external_axis_CTRL)

    # Add attributes to robots
    # Parent Attrubute
    parent_attribute = 'externalAxis_{}'.format(axis_name)
    pm.addAttr(target_CTRL,
               longName=parent_attribute,
               niceName='External Axis: {}'.format(axis_name),
               numberOfChildren=6,
               category='externalAxis',
               attributeType='compound')
    # Define 6 children of the External Axis parent attribute
    pm.addAttr(target_CTRL,
               longName=axis_name + '_position',
               niceName='Position',
               keyable=False, attributeType='float',
               parent=parent_attribute)
    pm.addAttr(target_CTRL,
               longName=axis_name + '_axisNumber',
               niceName='Axis Number',
               keyable=False,
               attributeType='long',
               minValue=1,
               maxValue=6,
               defaultValue=1,
               parent=parent_attribute)
    pm.addAttr(target_CTRL,
               longName=axis_name + '_axisMin',
               niceName='Min',
               keyable=False,
               attributeType='float',
               parent=parent_attribute)
    pm.addAttr(target_CTRL,
               longName=axis_name + '_axisMax',
               niceName='Max',
               keyable=False,
               attributeType='float',
               parent=parent_attribute)
    pm.addAttr(target_CTRL,
               longName=axis_name + '_maxVelocity',
               niceName='Max Velocity',
               keyable=False,
               attributeType='float',
               parent=parent_attribute)
    pm.addAttr(target_CTRL,
               longName=axis_name + '_ignore',
               niceName='Ignore',
               keyable=False,
               attributeType='bool',
               parent=parent_attribute)

    # If the driving attribute is a translate attribute, we convert the user
    # input from millimeters to Maya's default unit of centimeters
    if 'translate' in driving_attribute:
        position_limit_min = position_limit_min / 10
        position_limit_max = position_limit_max / 10

    # Set all External Axis attributes accordingly
    axis_parent_attribute = target_CTRL + '.' + axis_name
    pm.setAttr(axis_parent_attribute + '_axisNumber', axis_number, lock=True)
    pm.setAttr(axis_parent_attribute + '_axisMin', position_limit_min)
    pm.setAttr(axis_parent_attribute + '_axisMax', position_limit_max)
    pm.setAttr(axis_parent_attribute + '_maxVelocity', velocity_limit)
    pm.setAttr(axis_parent_attribute + '_ignore', ingnore_in_postproc)

    # Connect position attribute to driving attribute
    driving_attribute_name = external_axis_CTRL + '.' + driving_attribute
    destination_attribute_name = axis_parent_attribute + '_position'
    pm.connectAttr(driving_attribute_name,
                   destination_attribute_name)

    # Set the External Axis control limits
    _set_external_axis_CTRL_limits(robot,
                                   external_axis_CTRL,
                                   external_axis_params)

    # Select the robot's target/tool controller
    tool_CTRL = robot + '|robot_GRP|tool_CTRL'
    if pm.objExists(tool_CTRL):
        pm.select(tool_CTRL)
    else:
        pm.select(target_CTRL)

    list_axes()
    pm.headsUpMessage('External axis \'{}\' added successfully to {}'
                      .format(axis_name, robot))