Пример #1
0
    def __create_soft_ik(self, ik_control):
        """Create the node network to allow soft ik

        :param ik_control: Name of the ik control
        :return: The attribute containing the percentage length from start joint to handle
        that the ik should be placed
        """
        cmds.addAttr(
            ik_control,
            ln="softIk",
            minValue=0.0,
            maxValue=1.0,
            defaultValue=0.0,
            keyable=True,
        )

        softik = dge("clamp(x, 0.001, 1)", x="{}.softIk".format(ik_control))

        # We need to adjust how far the ik handle is from the start to create the soft
        # effect
        soft_ik_percentage = dge(
            "x > (1.0 - softIk)"
            "? (1.0 - softIk) + softIk * (1.0 - exp(-(x - (1.0 - softIk)) / softIk)) "
            ": x",
            container="{}_softik".format(self.name),
            x=self.percent_rest_distance,
            softIk=softik,
        )
        return soft_ik_percentage
Пример #2
0
 def test_cos(self):
     loc = cmds.spaceLocator(name="cos")[0]
     loc2 = cmds.spaceLocator()[0]
     dge("y=cos(x)", x="{}.tx".format(loc), y="{}.ty".format(loc2))
     for i in range(100):
         v = -10.0 + 0.1 * i
         cmds.setAttr("{}.tx".format(loc), v)
         y = cmds.getAttr("{}.ty".format(loc2))
         self.assertAlmostEquals(y, math.cos(v), places=5)
Пример #3
0
 def test_sin(self):
     loc = cmds.spaceLocator(name="sin")[0]
     loc2 = cmds.spaceLocator()[0]
     dge("y=sin(x)", x="{}.tx".format(loc), y="{}.ty".format(loc2))
     for i in range(100):
         v = -math.pi * 0.5 + 0.1 * i
         cmds.setAttr("{}.tx".format(loc), v)
         y = cmds.getAttr("{}.ty".format(loc2))
         self.assertAlmostEquals(y, math.sin(v), places=5)
Пример #4
0
 def test_acos(self):
     loc = cmds.spaceLocator(name="acos")[0]
     loc2 = cmds.spaceLocator()[0]
     dge("y=acos(x)", x="{}.tx".format(loc), y="{}.ty".format(loc2))
     for i in range(101):
         v = -1.0 + 0.02 * i
         cmds.setAttr("{}.tx".format(loc), v)
         y = cmds.getAttr("{}.ty".format(loc2))
         self.assertAlmostEquals(y, math.degrees(math.acos(v)), places=4)
Пример #5
0
 def test_atan(self):
     loc = cmds.spaceLocator(name="atan")[0]
     loc2 = cmds.spaceLocator()[0]
     dge("y=atan(x)", x="{}.tx".format(loc), y="{}.ty".format(loc2))
     for i in range(100):
         v = -5.0 + 0.1 * i
         cmds.setAttr("{}.tx".format(loc), v)
         y = cmds.getAttr("{}.ty".format(loc2))
         self.assertAlmostEquals(y, math.degrees(math.atan(v)), places=5)
Пример #6
0
 def test_tan(self):
     loc = cmds.spaceLocator(name="tan")[0]
     loc2 = cmds.spaceLocator()[0]
     dge("y=tan(x)", x="{}.tx".format(loc), y="{}.ty".format(loc2))
     v = -math.pi * 0.5 + 0.02
     while v < math.pi * 0.5:
         v += 0.02
         cmds.setAttr("{}.tx".format(loc), v)
         y = cmds.getAttr("{}.ty".format(loc2))
         self.assertAlmostEquals(y, math.tan(v), places=1)
Пример #7
0
    def test_abs(self):
        loc = cmds.spaceLocator()[0]
        dge("y=abs(x)", x="{}.tx".format(loc), y="{}.ty".format(loc))
        cmds.setAttr("{}.tx".format(loc), 0.75)
        y = cmds.getAttr("{}.ty".format(loc))
        self.assertAlmostEquals(y, 0.75)

        cmds.setAttr("{}.tx".format(loc), -0.75)
        y = cmds.getAttr("{}.ty".format(loc))
        self.assertAlmostEquals(y, 0.75)
Пример #8
0
    def test_max(self):
        loc = cmds.spaceLocator()[0]
        dge("y=max(x, 2)", x="{}.tx".format(loc), y="{}.ty".format(loc))
        cmds.setAttr("{}.tx".format(loc), 1)
        y = cmds.getAttr("{}.ty".format(loc))
        self.assertAlmostEquals(y, 2)

        cmds.setAttr("{}.tx".format(loc), 4)
        y = cmds.getAttr("{}.ty".format(loc))
        self.assertAlmostEquals(y, 4)
Пример #9
0
    def test_lerp(self):
        loc = cmds.spaceLocator()[0]
        dge("y=lerp(4, 8, x)", x="{}.tx".format(loc), y="{}.ty".format(loc))
        cmds.setAttr("{}.tx".format(loc), 1)
        y = cmds.getAttr("{}.ty".format(loc))
        self.assertAlmostEquals(y, 8)

        cmds.setAttr("{}.tx".format(loc), 0)
        y = cmds.getAttr("{}.ty".format(loc))
        self.assertAlmostEquals(y, 4)

        cmds.setAttr("{}.tx".format(loc), 0.25)
        y = cmds.getAttr("{}.ty".format(loc))
        self.assertAlmostEquals(y, 5)
Пример #10
0
 def test_add_two_attrs(self):
     loc = cmds.spaceLocator()[0]
     result = dge("x+x", x="{}.tx".format(loc))
     cmds.connectAttr(result, "{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 10.0)
Пример #11
0
 def test_exp(self):
     loc = cmds.spaceLocator()[0]
     result = dge("exp(x)", x="{}.tx".format(loc))
     cmds.connectAttr(result, "{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, math.exp(5), places=3)
Пример #12
0
 def test_pow(self):
     loc = cmds.spaceLocator()[0]
     result = dge("x^2", x="{}.tx".format(loc))
     cmds.connectAttr(result, "{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 25)
Пример #13
0
 def test_distance(self):
     loc = cmds.spaceLocator()[0]
     loc2 = cmds.spaceLocator()[0]
     cmds.setAttr("{}.tx".format(loc), 2.5)
     result = dge("distance(i, j)", container="mydistance", i=loc, j=loc2)
     d = cmds.getAttr(result)
     self.assertAlmostEquals(d, 2.5)
Пример #14
0
 def test_parentheses(self):
     loc = cmds.spaceLocator()[0]
     result = dge("(x+3)*(2+x)", x="{}.tx".format(loc))
     cmds.connectAttr(result, "{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 56.0)
Пример #15
0
 def test_subtract_1_to_3(self):
     loc = cmds.spaceLocator()[0]
     result = dge("3-x", x="{}.t".format(loc))
     cmds.connectAttr(result, "{}.r".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.rx".format(loc))
     self.assertAlmostEquals(y, -2.0, places=6)
Пример #16
0
 def test_add_3_to_1(self):
     loc = cmds.spaceLocator()[0]
     result = dge("x+3", x="{}.t".format(loc))
     cmds.connectAttr(result, "{}.r".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.rx".format(loc))
     self.assertAlmostEquals(y, 8.0, places=6)
Пример #17
0
 def test_two_op_add_subtract(self):
     loc = cmds.spaceLocator()[0]
     result = dge("x+3-y", x="{}.tx".format(loc), y="{}.ty".format(loc))
     cmds.connectAttr(result, "{}.tz".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     cmds.setAttr("{}.ty".format(loc), 2)
     z = cmds.getAttr("{}.tz".format(loc))
     self.assertAlmostEquals(z, 6.0)
Пример #18
0
 def test_ternary_is_equal(self):
     loc = cmds.spaceLocator()[0]
     result = dge("x == 1 ? x : 4", x="{}.tx".format(loc))
     cmds.connectAttr(result, "{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 4)
     cmds.setAttr("{}.tx".format(loc), 1)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 1)
Пример #19
0
 def test_ternary_with_function(self):
     loc = cmds.spaceLocator()[0]
     result = dge("x < 1 ? x : exp(x)", x="{}.tx".format(loc))
     cmds.connectAttr(result, "{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, math.exp(5), places=3)
     cmds.setAttr("{}.tx".format(loc), 0)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 0)
Пример #20
0
 def test_reuse_nodes(self):
     loc = cmds.spaceLocator()[0]
     result = dge("y=(1-x)*(1-x)+(1-x)",
                  x="{}.tx".format(loc),
                  y="{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 12)
     pma = cmds.ls(type="plusMinusAverage")
     self.assertEqual(len(pma), 2)
Пример #21
0
 def test_clamp(self):
     loc = cmds.spaceLocator()[0]
     result = dge("clamp(x, 0, 5)", x="{}.tx".format(loc))
     cmds.connectAttr(result, "{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 6)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 5.0)
     cmds.setAttr("{}.tx".format(loc), -1)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 0.0)
     cmds.setAttr("{}.tx".format(loc), 1)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 1.0)
Пример #22
0
    def __create_ik(self, ik_control, pole_vector, soft_ik_parent,
                    global_scale_attr, scale_stretch):
        self.ik_handle = cmds.ikHandle(
            name="{}_ikh".format(self.name),
            solver="ikRPsolver",
            startJoint=self.start_joint,
            endEffector=self.end_joint,
        )[0]

        cmds.setAttr("{}.v".format(self.ik_handle), 0)

        # Drive visibility
        ik_vis = dge("1.0 - ikFk", ikFk="{}.ikFk".format(self.config_control))
        for node in [ik_control, pole_vector]:
            vis = "{}.v".format(node)
            locked = cmds.getAttr(vis, lock=True)
            cmds.setAttr(vis, lock=False)
            cmds.connectAttr(ik_vis, "{}.v".format(node))
            if locked:
                cmds.setAttr(vis, lock=True)

        dge(
            "ikBlend = 1.0 - ikFk",
            ikBlend="{}.ikBlend".format(self.ik_handle),
            ikFk="{}.ikFk".format(self.config_control),
        )

        self.soft_ik = cmds.createNode("transform",
                                       name="{}_soft_ik".format(self.name))
        common.snap_to_position(self.soft_ik, self.end_joint)
        cmds.parent(self.ik_handle, self.soft_ik)
        cmds.parent(self.soft_ik, soft_ik_parent)

        self.__create_stretch(ik_control, global_scale_attr, scale_stretch)
        cmds.parent(self.end_loc, soft_ik_parent)

        cmds.poleVectorConstraint(pole_vector, self.ik_handle)
Пример #23
0
    def create(self, global_scale_attr=None):
        cmds.addAttr(
            self.end_control,
            ln="stretch",
            minValue=0.0,
            maxValue=1.0,
            defaultValue=0.0,
            keyable=True,
        )

        self.spline_chain, original_chain = common.duplicate_chain(
            self.start_joint, self.end_joint, prefix="ikSpine_")

        # Create the spline ik
        self.ik_handle, self.effector, self.curve = cmds.ikHandle(
            name="{}_ikh".format(self.name),
            solver="ikSplineSolver",
            startJoint=self.spline_chain[0],
            endEffector=self.spline_chain[-1],
            parentCurve=False,
            simplifyCurve=False,
        )
        self.effector = cmds.rename(self.effector, "{}_eff".format(self.name))
        self.curve = cmds.rename(self.curve, "{}_crv".format(self.name))

        # Create the joints to skin the curve
        curve_start_joint = cmds.duplicate(self.start_joint,
                                           parentOnly=True,
                                           name="{}CurveStart_jnt".format(
                                               self.name))[0]
        start_parent = cmds.listRelatives(self.start_control,
                                          parent=True,
                                          path=True)
        if start_parent:
            cmds.parent(curve_start_joint, start_parent[0])
        common.opm_point_constraint(self.start_control, curve_start_joint)

        curve_end_joint = cmds.duplicate(self.end_joint,
                                         parentOnly=True,
                                         name="{}CurveEnd_jnt".format(
                                             self.name))[0]
        cmds.parent(curve_end_joint, self.end_control)
        for node in [curve_start_joint, curve_end_joint]:
            cmds.setAttr("{}.v".format(node), 0)

        # Skin curve
        cmds.skinCluster(
            curve_start_joint,
            curve_end_joint,
            self.curve,
            name="{}_scl".format(self.name),
            tsb=True,
        )

        # Create stretch network
        curve_info = cmds.arclen(self.curve, constructionHistory=True)

        scale = dge(
            "lerp(1, arclength / (restLength * globalScale), stretch)",
            container="{}_stretch_scale".format(self.name),
            arclength="{}.arcLength".format(curve_info),
            restLength=cmds.getAttr("{}.arcLength".format(curve_info)),
            globalScale=global_scale_attr or 1.0,
            stretch="{}.stretch".format(self.end_control),
        )

        # Connect to joints
        for joint in self.spline_chain[1:]:
            tx = cmds.getAttr("{}.translateX".format(joint))
            mdl = cmds.createNode("multDoubleLinear",
                                  name="{}Stretch_mdl".format(joint))
            cmds.setAttr("{}.input1".format(mdl), tx)
            cmds.connectAttr(scale, "{}.input2".format(mdl))
            cmds.connectAttr("{}.output".format(mdl),
                             "{}.translateX".format(joint))

        joint_up = OpenMaya.MVector(0.0, 1.0, 0.0)
        start_joint_path = shortcuts.get_dag_path2(self.start_joint)
        start_control_path = shortcuts.get_dag_path2(self.start_control)
        up_vector_start = (joint_up * start_joint_path.inclusiveMatrix() *
                           start_control_path.inclusiveMatrixInverse())

        end_joint_path = shortcuts.get_dag_path2(self.end_joint)
        end_control_path = shortcuts.get_dag_path2(self.end_control)
        up_vector_end = (joint_up * end_joint_path.inclusiveMatrix() *
                         end_control_path.inclusiveMatrixInverse())

        # Setup advanced twist
        cmds.setAttr("{}.dTwistControlEnable".format(self.ik_handle), True)
        cmds.setAttr("{}.dWorldUpType".format(self.ik_handle), 4)  # Object up
        cmds.setAttr("{}.dWorldUpAxis".format(self.ik_handle),
                     0)  # Positive Y Up
        cmds.setAttr("{}.dWorldUpVectorX".format(self.ik_handle),
                     up_vector_start.x)
        cmds.setAttr("{}.dWorldUpVectorY".format(self.ik_handle),
                     up_vector_start.y)
        cmds.setAttr("{}.dWorldUpVectorZ".format(self.ik_handle),
                     up_vector_start.z)
        cmds.setAttr("{}.dWorldUpVectorEndX".format(self.ik_handle),
                     up_vector_end.x)
        cmds.setAttr("{}.dWorldUpVectorEndY".format(self.ik_handle),
                     up_vector_end.y)
        cmds.setAttr("{}.dWorldUpVectorEndZ".format(self.ik_handle),
                     up_vector_end.z)
        cmds.connectAttr(
            "{}.worldMatrix[0]".format(self.start_control),
            "{}.dWorldUpMatrix".format(self.ik_handle),
        )
        cmds.connectAttr(
            "{}.worldMatrix[0]".format(self.end_control),
            "{}.dWorldUpMatrixEnd".format(self.ik_handle),
        )

        # Constrain original chain back to spline chain
        for ik_joint, joint in zip(self.spline_chain, original_chain):
            if joint == self.end_joint:
                cmds.pointConstraint(ik_joint, joint, mo=True)
                cmds.orientConstraint(self.end_control, joint, mo=True)
            elif joint == self.start_joint:
                cmds.parentConstraint(self.start_control, joint, mo=True)
            else:
                cmds.parentConstraint(ik_joint, joint)
Пример #24
0
    def __create_fk(self, parent):
        for name, joint in [
            ("start_fk_control", self.start_joint),
            ("mid_fk_control", self.mid_joint),
            ("end_fk_control", self.end_joint),
        ]:
            control = cmds.createNode("transform",
                                      name="{}_fk_ctrl".format(joint))
            common.snap_to(control, joint)
            common.lock_and_hide(control, "sv")
            setattr(self, name, control)
            if parent:
                cmds.parent(control, parent)
            common.freeze_to_parent_offset(control)
            parent = control
            ori = cmds.orientConstraint(control, joint)[0]
            cmds.connectAttr("{}.ikFk".format(self.config_control),
                             "{}.{}W0".format(ori, control))

            # Drive visibility
            visibility = "{}.v".format(control)
            locked = cmds.getAttr(visibility, lock=True)
            cmds.setAttr(visibility, lock=False)
            cmds.connectAttr("{}.ikFk".format(self.config_control), visibility)
            if locked:
                cmds.setAttr(visibility, lock=True)

        for joint, node in [
            (self.start_joint, self.start_fk_control),
            (self.mid_joint, self.mid_fk_control),
        ]:
            cmds.addAttr(node,
                         ln="length",
                         minValue=0,
                         defaultValue=1,
                         keyable=True)
            scale = cmds.listConnections("{}.sx".format(joint),
                                         d=False,
                                         plugs=True)[0]
            dge(
                "sx = lerp(scale, length, ikFk)",
                sx="{}.sx".format(joint),
                scale=scale,
                length="{}.length".format(node),
                ikFk="{}.ikFk".format(self.config_control),
            )

        for control in [self.mid_fk_control, self.end_fk_control]:
            parent_control = cmds.listRelatives(control,
                                                parent=True,
                                                path=True)[0]
            compose = cmds.createNode("composeMatrix")
            offset = common.local_offset(control)
            dge(
                "x = (length - 1.0) * tx",
                container="{}_length_offset".format(control),
                x="{}.inputTranslateX".format(compose),
                length="{}.length".format(parent_control),
                tx=offset.getElement(3, 0),
            )

            mult = cmds.createNode("multMatrix")
            cmds.connectAttr("{}.outputMatrix".format(compose),
                             "{}.matrixIn[0]".format(mult))
            cmds.setAttr(
                "{}.matrixIn[1]".format(mult),
                cmds.getAttr("{}.offsetParentMatrix".format(control)),
                type="matrix",
            )
            cmds.connectAttr(
                "{}.matrixSum".format(mult),
                "{}.offsetParentMatrix".format(control),
            )
Пример #25
0
    def __create_stretch(self,
                         ik_control,
                         global_scale_attr=None,
                         scale_stretch=True):
        """Create the stretchy soft ik setup.

        :param ik_control: Name of the node to use as the ik control.
        :param global_scale_attr: Optional attribute containing global scale value.
        :param scale_stretch: True to stretch with scale, False to use translate.
        """
        for attr in ["stretch", "softIk"]:
            cmds.addAttr(
                ik_control,
                ln=attr,
                minValue=0.0,
                maxValue=1.0,
                defaultValue=0.0,
                keyable=True,
            )

        # Locator for start distance measurement
        self.start_loc = cmds.spaceLocator(
            name="{}_stretch_start".format(self.name))[0]
        parent = cmds.listRelatives(self.start_joint, parent=True, path=True)
        if parent:
            cmds.connectAttr(
                "{}.worldMatrix[0]".format(parent[0]),
                "{}.offsetParentMatrix".format(self.start_loc),
            )
        common.snap_to_position(self.start_loc, self.start_joint)

        # Locator for end distance measurement
        self.end_loc = cmds.spaceLocator(
            name="{}_stretch_end".format(self.name))[0]
        cmds.setAttr("{}.v".format(self.end_loc), 0)
        common.snap_to_position(self.end_loc, self.end_joint)

        rest_length = shortcuts.distance(self.start_joint, self.mid_joint)
        rest_length += shortcuts.distance(self.mid_joint, self.end_joint)

        length_ratio = dge(
            "distance(start, end) / (restLength * globalScale)",
            container="{}_percent_from_rest".format(self.name),
            start=self.start_loc,
            end=self.end_loc,
            restLength=rest_length,
            globalScale=global_scale_attr or 1.0,
        )

        # Prevent divide by 0
        softik = dge("max(x, 0.001)", x="{}.softIk".format(ik_control))

        # We need to adjust offset the ik handle and scale the joints to create the soft
        # effect
        # See this graph to see the the softIk and scale values plotted
        # https://www.desmos.com/calculator/csi40rsztl
        # x = length_ratio
        # f(x) = softik_scale
        # c(x) = Scale x of the joints
        # s = softIk attribute
        # t = stretch attribute
        softik_scale = dge(
            "x > (1.0 - softIk)"
            "? (1.0 - softIk) + softIk * (1.0 - exp(-(x - (1.0 - softIk)) / softIk)) "
            ": x",
            container="{}_softik".format(self.name),
            x=length_ratio,
            softIk=softik,
        )

        compose_matrix = cmds.createNode("composeMatrix")

        # Set the effector position
        dge(
            "tx = restLength * lerp(softIk, lengthRatio, stretch)",
            container="{}_effector_position".format(self.name),
            tx="{}.inputTranslate.inputTranslateX".format(compose_matrix),
            restLength=rest_length,
            lengthRatio=length_ratio,
            softIk=softik_scale,
            stretch="{}.stretch".format(ik_control),
        )

        # Drive the joint scale for stretch
        scale = dge(
            "lerp(1, lengthRatio / softIk, stretch)",
            container="{}_stretch_scale".format(self.name),
            lengthRatio=length_ratio,
            softIk=softik_scale,
            stretch="{}.stretch".format(ik_control),
        )
        if scale_stretch:
            for node in [self.start_joint, self.mid_joint]:
                cmds.connectAttr(scale, "{}.sx".format(node))
                inverse_scale = dge("1/sx", sx="{}.sx".format(node))
                cmds.connectAttr(inverse_scale, "{}.sy".format(node))
                cmds.connectAttr(inverse_scale, "{}.sz".format(node))
        else:
            for node in [self.mid_joint, self.end_joint]:
                tx = cmds.getAttr("{}.tx".format(node))
                dge("x = {} * s".format(tx), x="{}.tx".format(node), s=scale)

        # Drive the soft ik transform
        aim = cmds.createNode("aimMatrix")
        cmds.connectAttr("{}.worldMatrix[0]".format(self.start_loc),
                         "{}.inputMatrix".format(aim))
        cmds.connectAttr(
            "{}.worldMatrix[0]".format(self.end_loc),
            "{}.primary.primaryTargetMatrix".format(aim),
        )
        mult = cmds.createNode("multMatrix")
        cmds.connectAttr("{}.outputMatrix".format(compose_matrix),
                         "{}.matrixIn[0]".format(mult))
        cmds.connectAttr("{}.outputMatrix".format(aim),
                         "{}.matrixIn[1]".format(mult))
        parent = cmds.listRelatives(self.soft_ik, parent=True, path=True)[0]
        if parent:
            cmds.connectAttr("{}.worldInverseMatrix[0]".format(parent),
                             "{}.matrixIn[2]".format(mult))
        pick = cmds.createNode("pickMatrix")
        cmds.connectAttr("{}.matrixSum".format(mult),
                         "{}.inputMatrix".format(pick))
        for attr in ["Scale", "Shear", "Rotate"]:
            cmds.setAttr("{}.use{}".format(pick, attr), 0)
        cmds.connectAttr("{}.outputMatrix".format(pick),
                         "{}.offsetParentMatrix".format(self.soft_ik))
        cmds.setAttr("{}.t".format(self.soft_ik), 0, 0, 0)
Пример #26
0
 def test_sqrt(self):
     loc = cmds.spaceLocator()[0]
     dge("y=sqrt(x)", x="{}.tx".format(loc), y="{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 10.2)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, math.sqrt(10.2), places=5)
Пример #27
0
def create_space_switch(node,
                        drivers,
                        switch_attribute=None,
                        use_translate=True,
                        use_rotate=True):
    """Creates a space switch network.

    The network uses the offsetParentMatrix attribute and does not create any
    constraints or new dag nodes.

    :param node: Transform to drive
    :param drivers: List of tuples: [(driver1, "spaceName1"), (driver2, "spaceName2")]
    :param switch_attribute: Name of the switch attribute to create on the target node.
    """
    if switch_attribute is None:
        switch_attribute = "space"

    if cmds.objExists("{}.{}".format(node, switch_attribute)):
        cmds.deleteAttr(node, at=switch_attribute)
    names = [d[1] for d in drivers]
    cmds.addAttr(node,
                 ln=switch_attribute,
                 at="enum",
                 en=":".join(names),
                 keyable=True)

    # Create attribute to toggle translation in the matrices
    enable_translate_attr = _create_bool_attribute(
        node, "{}UseTranslate".format(switch_attribute), use_translate)

    # Create attribute to toggle rotation in the matrices
    enable_rotate_attr = _create_bool_attribute(
        node, "{}UseRotate".format(switch_attribute), use_rotate)

    blend = cmds.createNode("blendMatrix", name="{}_spaceswitch".format(node))

    # Get the current offset parent matrix.  This is used as the starting blend point
    m = OpenMaya.MMatrix(cmds.getAttr("{}.offsetParentMatrix".format(node)))
    cmds.setAttr("{}.inputMatrix".format(blend), list(m), type="matrix")

    parent = cmds.listRelatives(node, parent=True, path=True)
    to_parent_local = "{}.worldInverseMatrix[0]".format(
        parent[0]) if parent else None

    for i, driver in enumerate(drivers):
        driver = driver[0]

        _connect_driver_matrix_network(blend, node, driver, i, to_parent_local)

        target_attr = "{}.target[{}]".format(blend, i)

        # Hook up the weight toggle when switching spaces
        dge(
            "x = switch == {} ? 1 : 0".format(i),
            x="{}.weight".format(target_attr),
            switch="{}.{}".format(node, switch_attribute),
        )

        # Connect the translation, rotation toggles
        cmds.connectAttr(enable_translate_attr,
                         "{}.useTranslate".format(target_attr))
        cmds.connectAttr(enable_rotate_attr,
                         "{}.useRotate".format(target_attr, i))

    cmds.connectAttr("{}.outputMatrix".format(blend),
                     "{}.offsetParentMatrix".format(node))
Пример #28
0
 def test_assignment(self):
     loc = cmds.spaceLocator()[0]
     result = dge("y=x^2", x="{}.tx".format(loc), y="{}.ty".format(loc))
     cmds.setAttr("{}.tx".format(loc), 5)
     y = cmds.getAttr("{}.ty".format(loc))
     self.assertAlmostEquals(y, 25)