Ejemplo n.º 1
0
    def setUp(self):
        ''' Called initially to set up the maya test environment '''
        # Load plugins
        self.assertTrue(self.pluginsLoaded)

        # These tests requires no additional setup.
        if self._testMethodName in [
                'testAddNewPrim', 'testAddNewPrimWithDelete'
        ]:
            return

        # Open top_layer.ma scene in testSamples
        mayaUtils.openTopLayerScene()

        # Clear selection to start off.
        ufe.GlobalSelection.get().clear()

        # Select Ball_35.
        ball35Path = ufe.Path([
            mayaUtils.createUfePathSegment("|transform1|proxyShape1"),
            usdUtils.createUfePathSegment("/Room_set/Props/Ball_35")
        ])
        self.ball35Item = ufe.Hierarchy.createItem(ball35Path)
        self.ball35Prim = usdUtils.getPrimFromSceneItem(self.ball35Item)

        ufe.GlobalSelection.get().append(self.ball35Item)

        # Create a ContextOps interface for it.
        self.contextOps = ufe.ContextOps.contextOps(self.ball35Item)
    def testStaticUsdCamera(self):
        self._StartTest('TranslateRotate_vs_xform')

        mayaPathSegment = mayaUtils.createUfePathSegment('|stage|stageShape')
        #camera1 doesn't work correctly right now because of an xformOp:transform issue MAYA-110515
        #cam1UsdPathSegment = usdUtils.createUfePathSegment('cameras/cam1/camera1')
        #cmds.lookThru('|stage|stageShape,/cameras/cam1/camera1')
        #self.assertSnapshotClose('%s_cam1_unselected.png' % self._testName)

        cmds.lookThru('|stage|stageShape,/cameras/cam2/camera2')
        self.assertSnapshotClose('%s_cam2_unselected.png' % self._testName)

        # create a Ufe transform3d and move cam2 somewhere else and do a snapshot
        cam2UsdPathSegment = usdUtils.createUfePathSegment(
            '/cameras/cam2/camera2')
        cam2Path = ufe.Path([mayaPathSegment, cam2UsdPathSegment])
        cam2Item = ufe.Hierarchy.createItem(cam2Path)
        cam2Transform3d = ufe.Transform3d.transform3d(cam2Item)
        cam2Transform3d.translate(-1, 0, 0)
        self.assertSnapshotClose('%s_cam2_translated.png' % self._testName)

        # create a Ufe Camera and modify the near clip plane and do a snapshot
        # ufe.Camera is not in Ufe 2.0.0 MAYA-110675
        # set the clipping range using the USD API instead
        usdCamera = usdUtils.getPrimFromSceneItem(cam2Item)
        clippingAttr = usdCamera.GetAttribute('clippingRange')
        clippingRange = clippingAttr.Get()
        clippingAttr.Set(Gf.Vec2f(10, 5000))
        self.assertSnapshotClose('%s_cam2_insideNearClipPlane.png' %
                                 self._testName)
Ejemplo n.º 3
0
 def usdSceneItemScale(item):
     prim = usdUtils.getPrimFromSceneItem(item)
     if not prim.HasAttribute('xformOp:scale'):
         return proxyShapeXformFn.scale()
     else:
         return combineScales(proxyShapeXformFn.scale(),
                              prim.GetAttribute('xformOp:scale').Get())
    def testDrawModes(self):
        self._StartTest('DrawModes')
        cmds.modelEditor('modelPanel4', edit=True, grid=False)

        cmds.move(2, 2, 2, 'persp')
        cmds.rotate(-33, 45, 0, 'persp')
        self.assertSnapshotClose('%s_cross_all_positive.png' % self._testName)

        cmds.move(-2, -2, -2, 'persp')
        cmds.rotate(145, 45, 0, 'persp')
        self.assertSnapshotClose('%s_cross_all_negative.png' % self._testName)

        mayaPathSegment = mayaUtils.createUfePathSegment('|stage|stageShape')
        usdPathSegment = usdUtils.createUfePathSegment('/DrawModes')
        drawModesPath = ufe.Path([mayaPathSegment, usdPathSegment])
        drawModesItem = ufe.Hierarchy.createItem(drawModesPath)
        drawModesPrim = usdUtils.getPrimFromSceneItem(drawModesItem)
        cardGeomAttr = drawModesPrim.GetAttribute('model:cardGeometry')
        cardGeomAttr.Set('box')

        cmds.move(2, 2, 2, 'persp')
        cmds.rotate(-33, 45, 0, 'persp')
        self.assertSnapshotClose('%s_box_all_positive.png' % self._testName)

        cmds.move(-2, -2, -2, 'persp')
        cmds.rotate(145, 45, 0, 'persp')
        self.assertSnapshotClose('%s_box_all_negative.png' % self._testName)
Ejemplo n.º 5
0
 def ball35Rotation():
     ball35Prim = usdUtils.getPrimFromSceneItem(ball35Item)
     if not ball35Prim.HasAttribute('xformOp:rotateXYZ'):
         return proxyShapeXformFn.rotation(om.MSpace.kTransform)
     else:
         x,y,z = ball35Prim.GetAttribute('xformOp:rotateXYZ').Get()
         return proxyShapeXformFn.rotation(om.MSpace.kTransform) + om.MEulerRotation(radians(x), radians(y), radians(z))
Ejemplo n.º 6
0
 def ball35Scale():
     ball35Prim = usdUtils.getPrimFromSceneItem(ball35Item)
     if not ball35Prim.HasAttribute('xformOp:scale'):
         return proxyShapeXformFn.scale()
     else:
         return combineScales(
             proxyShapeXformFn.scale(),
             ball35Prim.GetAttribute('xformOp:scale').Get())
Ejemplo n.º 7
0
 def usdSceneItemTranslation(item):
     prim = usdUtils.getPrimFromSceneItem(item)
     if not prim.HasAttribute('xformOp:translate'):
         return proxyShapeXformFn.translation(om.MSpace.kTransform)
     else:
         return addVec(
             proxyShapeXformFn.translation(om.MSpace.kTransform),
             prim.GetAttribute('xformOp:translate').Get())
Ejemplo n.º 8
0
    def testUsdCamera(self):
        self._StartTest('TranslateRotate_vs_xform')
        mayaPathSegment = mayaUtils.createUfePathSegment('|stage|stageShape')
        cam2UsdPathSegment = usdUtils.createUfePathSegment(
            '/cameras/cam2/camera2')
        cam2Path = ufe.Path([mayaPathSegment, cam2UsdPathSegment])
        cam2Item = ufe.Hierarchy.createItem(cam2Path)

        cam2Camera = ufe.Camera.camera(cam2Item)
        cameraPrim = usdUtils.getPrimFromSceneItem(cam2Item)
        self._TestCameraAttributes(cam2Camera, cameraPrim)
Ejemplo n.º 9
0
    def testObservation(self):
        '''Test Transform3d observation interface.

        As of 11-Apr-2018 only implemented for USD objects.
        '''

        # Select Ball_35 to move it.
        ball35Path = ufe.Path([
            mayaUtils.createUfePathSegment("|transform1|proxyShape1"), 
            usdUtils.createUfePathSegment("/Room_set/Props/Ball_35")])
        ball35Item = ufe.Hierarchy.createItem(ball35Path)

        # Create a Transform3d interface for it.
        transform3d = ufe.Transform3d.transform3d(ball35Item)

        t3dObs = TestObserver()

        # We start off with no observers for Ball_35.
        self.assertFalse(ufe.Transform3d.hasObservers(ball35Path))
        self.assertFalse(ufe.Transform3d.hasObserver(ball35Item, t3dObs))
        self.assertEqual(ufe.Transform3d.nbObservers(ball35Item), 0)

        # Set the observer to observe Ball_35.
        ufe.Transform3d.addObserver(ball35Item, t3dObs)

        self.assertTrue(ufe.Transform3d.hasObservers(ball35Path))
        self.assertTrue(ufe.Transform3d.hasObserver(ball35Item, t3dObs))
        self.assertEqual(ufe.Transform3d.nbObservers(ball35Item), 1)

        # No notifications yet.
        self.assertEqual(t3dObs.notifications(), 0)

        # We only select the ball AFTER doing our initial tests because
        # the MayaUSD plugin creates a transform3d observer on selection
        # change to update the bounding box.
        ufe.GlobalSelection.get().append(ball35Item)

        # Move the prim.  Use a change block to condense USD notifications into
        # one.  Otherwise, as of 15-Jul-2021, the implementation of
        # UsdStage::_SetValue() notifies once for creation of the 
        # 'xformOp:translate' attrSpec, at the end of an SdfChangeBlock, and
        # once for setting the 'xformOp:translate' field (in Sdf terminology),
        # again at the end of a separate SdfChangeBlock.
        ball35Prim = usdUtils.getPrimFromSceneItem(ball35Item)
        with Sdf.ChangeBlock():
            ball35Prim.GetAttribute('xformOp:translate').Set(
                Gf.Vec3d(10, 20, 30))

        # Notified.
        self.assertEqual(t3dObs.notifications(), 1)
Ejemplo n.º 10
0
    def runTestAttribute(self, path, attrName, ufeAttrClass, ufeAttrType):
        '''Engine method to run attribute test.'''

        # Create the UFE/USD attribute for this test from the input path.

        # Get a UFE scene item the input path in the scene.
        itemPath = ufe.Path([
            mayaUtils.createUfePathSegment("|transform1|proxyShape1"),
            usdUtils.createUfePathSegment(path)
        ])
        ufeItem = ufe.Hierarchy.createItem(itemPath)

        # Get the USD prim for this item.
        usdPrim = usdUtils.getPrimFromSceneItem(ufeItem)

        # Create the attributes interface for the item.
        ufeAttrs = ufe.Attributes.attributes(ufeItem)
        self.assertIsNotNone(ufeAttrs)

        # Get the USDAttribute for the input attribute name so we can use it to
        # compare to UFE.
        usdAttr = usdPrim.GetAttribute(attrName)
        self.assertIsNotNone(usdAttr)

        # Get the attribute that matches the input name and make sure it matches
        # the class type of UFE attribute class passed in.
        self.assertTrue(ufeAttrs.hasAttribute(attrName))
        ufeAttr = ufeAttrs.attribute(attrName)
        self.assertIsInstance(ufeAttr, ufeAttrClass)

        # Verify that the attribute type matches the input UFE type.
        self.assertEqual(ufeAttr.type, ufeAttrType)

        # Verify that the scene item the attribute was created with matches
        # what is stored in the UFE attribute.
        self.assertEqual(ufeAttr.sceneItem(), ufeItem)

        # Verify that this attribute has a value. Note: all the attributes that
        # are tested by this method are assumed to have a value.
        self.assertTrue(ufeAttr.hasValue())

        # Verify that the name matched what we created the attribute from.
        self.assertEqual(ufeAttr.name, attrName)

        # Test that the string representation of the value is not empty.
        self.assertTrue(str(ufeAttr))

        return ufeAttr, usdAttr
Ejemplo n.º 11
0
    def testObservation(self):
        '''Test Transform3d observation interface.

        As of 11-Apr-2018 only implemented for USD objects.
        '''

        # Select Ball_35 to move it.
        ball35Path = ufe.Path([
            mayaUtils.createUfePathSegment("|transform1|proxyShape1"),
            usdUtils.createUfePathSegment("/Room_set/Props/Ball_35")
        ])
        ball35Item = ufe.Hierarchy.createItem(ball35Path)

        # Create a Transform3d interface for it.
        transform3d = ufe.Transform3d.transform3d(ball35Item)

        t3dObs = TestObserver()

        # We start off with no observers for Ball_35.
        self.assertFalse(ufe.Transform3d.hasObservers(ball35Path))
        self.assertFalse(ufe.Transform3d.hasObserver(ball35Item, t3dObs))
        self.assertEqual(ufe.Transform3d.nbObservers(ball35Item), 0)

        # Set the observer to observe Ball_35.
        ufe.Transform3d.addObserver(ball35Item, t3dObs)

        self.assertTrue(ufe.Transform3d.hasObservers(ball35Path))
        self.assertTrue(ufe.Transform3d.hasObserver(ball35Item, t3dObs))
        self.assertEqual(ufe.Transform3d.nbObservers(ball35Item), 1)

        # No notifications yet.
        self.assertEqual(t3dObs.notifications(), 0)

        # We only select the ball AFTER doing our initial tests because
        # the MayaUSD plugin creates a transform3d observer on selection
        # change to update the bounding box.
        ufe.GlobalSelection.get().append(ball35Item)

        # Move the prim.
        ball35Prim = usdUtils.getPrimFromSceneItem(ball35Item)
        ball35Prim.GetAttribute('xformOp:translate').Set(Gf.Vec3d(10, 20, 30))

        # Notified.
        self.assertEqual(t3dObs.notifications(), 1)
Ejemplo n.º 12
0
        def duplicate(ufeItem):
            '''Duplicate a scene item and return the UFE scene item of the new item.'''
            # Set the edit target to the layer in which Ball_35 is defined (has a
            # primSpec, in USD terminology).  Otherwise, duplication will not find
            # a source primSpec to copy.  Layers are the (anonymous) session layer,
            # the root layer, then the Assembly_room_set sublayer.  Trying to find
            # the layer by name is not practical, as it requires the full path
            # name, which potentially differs per run-time environment.
            prim = usdUtils.getPrimFromSceneItem(ufeItem)
            stage = prim.GetStage()

            layer = stage.GetLayerStack()[2]
            stage.SetEditTarget(layer)

            ufe.GlobalSelection.get().clear()
            ufe.GlobalSelection.get().append(ufeItem)
            cmds.duplicate()

            # The duplicate command doesn't return duplicated non-Maya UFE objects.
            # They are in the selection, in the same order as the sources.
            sel = ufe.GlobalSelection.get()
            self.assertEqual(1, len(sel))
            return sel.front()
Ejemplo n.º 13
0
 def ball35Translation():
     ball35Prim = usdUtils.getPrimFromSceneItem(ball35Item)
     return addVec(proxyShapeXformFn.translation(om.MSpace.kTransform),
                   ball35Prim.GetAttribute('xformOp:translate').Get())
Ejemplo n.º 14
0
    def testUsdGroup(self):
        '''Creation of USD group objects.'''

        mayaPathSegment = mayaUtils.createUfePathSegment(
            "|transform1|proxyShape1")

        usdSegmentBall5 = usdUtils.createUfePathSegment(
            "/Ball_set/Props/Ball_5")
        ball5Path = ufe.Path([mayaPathSegment, usdSegmentBall5])
        ball5Item = ufe.Hierarchy.createItem(ball5Path)

        usdSegmentBall3 = usdUtils.createUfePathSegment(
            "/Ball_set/Props/Ball_3")
        ball3Path = ufe.Path([mayaPathSegment, usdSegmentBall3])
        ball3Item = ufe.Hierarchy.createItem(ball3Path)

        usdSegmentProps = usdUtils.createUfePathSegment("/Ball_set/Props")
        parentPath = ufe.Path([mayaPathSegment, usdSegmentProps])
        parentItem = ufe.Hierarchy.createItem(parentPath)

        parentHierarchy = ufe.Hierarchy.hierarchy(parentItem)
        parentChildrenPre = parentHierarchy.children()
        self.assertEqual(len(parentChildrenPre), 6)

        newGroupName = ufe.PathComponent("newGroup")

        # get the USD stage
        stage = mayaUsd.ufe.getStage(str(mayaPathSegment))

        # set the edit target to balls.usda
        layer = stage.GetLayerStack()[1]
        self.assertEqual("ballset.usda", layer.GetDisplayName())
        stage.SetEditTarget(layer)

        ufeSelectionList = ufe.Selection()
        ufeSelectionList.append(ball5Item)
        ufeSelectionList.append(ball3Item)

        groupCmd = parentHierarchy.createGroupCmd(ufeSelectionList,
                                                  newGroupName)
        groupCmd.execute()

        parentChildrenPost = parentHierarchy.children()
        self.assertEqual(len(parentChildrenPost), 5)

        # The command will now append a number 1 at the end to match the naming
        # convention in Maya.
        newGroupPath = parentPath + ufe.PathComponent("newGroup1")

        # Make sure the new group item has the correct Usd type
        newGroupItem = ufe.Hierarchy.createItem(newGroupPath)
        newGroupPrim = usdUtils.getPrimFromSceneItem(newGroupItem)
        newGroupType = newGroupPrim.GetTypeName()
        self.assertEqual(newGroupType, 'Xform')

        childPaths = set([child.path() for child in parentChildrenPost])

        self.assertTrue(newGroupPath in childPaths)
        self.assertTrue(ball5Path not in childPaths)
        self.assertTrue(ball3Path not in childPaths)

        groupCmd.undo()

        parentChildrenUndo = parentHierarchy.children()
        self.assertEqual(len(parentChildrenUndo), 6)

        childPathsUndo = set([child.path() for child in parentChildrenUndo])
        self.assertTrue(newGroupPath not in childPathsUndo)
        self.assertTrue(ball5Path in childPathsUndo)
        self.assertTrue(ball3Path in childPathsUndo)

        groupCmd.redo()

        parentChildrenRedo = parentHierarchy.children()
        self.assertEqual(len(parentChildrenRedo), 5)

        childPathsRedo = set([child.path() for child in parentChildrenRedo])
        self.assertTrue(newGroupPath in childPathsRedo)
        self.assertTrue(ball5Path not in childPathsRedo)
        self.assertTrue(ball3Path not in childPathsRedo)
Ejemplo n.º 15
0
    def testDuplicate(self):
        '''Duplicate Maya and USD objects.'''

        # Select two objects, one Maya, one USD.
        spherePath = ufe.Path(mayaUtils.createUfePathSegment("|pSphere1"))
        sphereItem = ufe.Hierarchy.createItem(spherePath)
        sphereHierarchy = ufe.Hierarchy.hierarchy(sphereItem)
        worldItem = sphereHierarchy.parent()

        ball35Path = ufe.Path([
            mayaUtils.createUfePathSegment(
                "|transform1|proxyShape1"),
            usdUtils.createUfePathSegment("/Room_set/Props/Ball_35")])
        ball35Item = ufe.Hierarchy.createItem(ball35Path)
        ball35Hierarchy = ufe.Hierarchy.hierarchy(ball35Item)
        propsItem = ball35Hierarchy.parent()

        worldHierarchy = ufe.Hierarchy.hierarchy(worldItem)
        worldChildrenPre = worldHierarchy.children()
        propsHierarchy = ufe.Hierarchy.hierarchy(propsItem)
        propsChildrenPre = propsHierarchy.children()

        ufe.GlobalSelection.get().append(sphereItem)
        ufe.GlobalSelection.get().append(ball35Item)

        # Set the edit target to the layer in which Ball_35 is defined (has a
        # primSpec, in USD terminology).  Otherwise, duplication will not find
        # a source primSpec to copy.  Layers are the (anonymous) session layer,
        # the root layer, then the Assembly_room_set sublayer.  Trying to find
        # the layer by name is not practical, as it requires the full path
        # name, which potentially differs per run-time environment.
        ball35Prim = usdUtils.getPrimFromSceneItem(ball35Item)
        stage = ball35Prim.GetStage()

        layer = stage.GetLayerStack()[2]
        stage.SetEditTarget(layer)

        cmds.duplicate()

        # The duplicate command doesn't return duplicated non-Maya UFE objects.
        # They are in the selection, in the same order as the sources.
        snIter = iter(ufe.GlobalSelection.get())
        sphereDupItem = next(snIter)
        sphereDupName = str(sphereDupItem.path().back())
        ball35DupItem = next(snIter)
        ball35DupName = str(ball35DupItem.path().back())

        worldChildren = worldHierarchy.children()
        propsChildren = propsHierarchy.children()

        self.assertEqual(len(worldChildren)-len(worldChildrenPre), 1)
        self.assertEqual(len(propsChildren)-len(propsChildrenPre), 1)

        self.assertIn(sphereDupItem, worldChildren)
        self.assertIn(ball35DupItem, propsChildren)

        cmds.undo()

        # The duplicated items should no longer appear in the child list of
        # their parents.

        def childrenNames(children):
            return [str(child.path().back()) for child in children]

        worldHierarchy = ufe.Hierarchy.hierarchy(worldItem)
        worldChildren = worldHierarchy.children()
        propsHierarchy = ufe.Hierarchy.hierarchy(propsItem)
        propsChildren = propsHierarchy.children()

        worldChildrenNames = childrenNames(worldChildren)
        propsChildrenNames = childrenNames(propsChildren)

        self.assertNotIn(sphereDupName, worldChildrenNames)
        self.assertNotIn(ball35DupName, propsChildrenNames)

        # The duplicated items shoudl reappear after a redo
        cmds.redo()

        snIter = iter(ufe.GlobalSelection.get())
        sphereDupItem = next(snIter)
        ball35DupItem = next(snIter)

        worldChildren = worldHierarchy.children()
        propsChildren = propsHierarchy.children()

        self.assertEqual(len(worldChildren)-len(worldChildrenPre), 1)
        self.assertEqual(len(propsChildren)-len(propsChildrenPre), 1)

        self.assertIn(sphereDupItem, worldChildren)
        self.assertIn(ball35DupItem, propsChildren)

        cmds.undo()

        # The duplicated items should not be assigned to the name of a
        # deactivated USD item.

        cmds.select(clear=True)

        # Delete the even numbered props:
        evenPropsChildrenPre = propsChildrenPre[0:35:2]
        for propChild in evenPropsChildrenPre:
            ufe.GlobalSelection.get().append(propChild)
        cmds.delete()

        worldHierarchy = ufe.Hierarchy.hierarchy(worldItem)
        worldChildren = worldHierarchy.children()
        propsHierarchy = ufe.Hierarchy.hierarchy(propsItem)
        propsChildren = propsHierarchy.children()
        propsChildrenPostDel = propsHierarchy.children()

        # Duplicate Ball_1
        ufe.GlobalSelection.get().append(propsChildrenPostDel[0])

        cmds.duplicate()

        snIter = iter(ufe.GlobalSelection.get())
        ballDupItem = next(snIter)
        ballDupName = str(ballDupItem.path().back())

        self.assertNotIn(ballDupItem, propsChildrenPostDel)
        self.assertNotIn(ballDupName, propsChildrenNames)
        self.assertEqual(ballDupName, "Ball_36")

        cmds.undo()  # undo duplication
        cmds.undo()  # undo deletion
Ejemplo n.º 16
0
 def ball35SetTranslation(xlation):
     ball35Prim = usdUtils.getPrimFromSceneItem(ball35Item)
     ball35Prim.GetAttribute('xformOp:translate').Set(
         Gf.Vec3d(*xlation))
Ejemplo n.º 17
0
    def testUsdGroup(self):
        '''Creation of USD group objects.'''

        mayaPathSegment = mayaUtils.createUfePathSegment(
            "|transform1|proxyShape1")

        usdSegmentBall5 = usdUtils.createUfePathSegment(
            "/Ball_set/Props/Ball_5")
        ball5Path = ufe.Path([mayaPathSegment, usdSegmentBall5])
        ball5Item = ufe.Hierarchy.createItem(ball5Path)

        usdSegmentBall3 = usdUtils.createUfePathSegment(
            "/Ball_set/Props/Ball_3")
        ball3Path = ufe.Path([mayaPathSegment, usdSegmentBall3])
        ball3Item = ufe.Hierarchy.createItem(ball3Path)

        usdSegmentProps = usdUtils.createUfePathSegment("/Ball_set/Props")
        parentPath = ufe.Path([mayaPathSegment, usdSegmentProps])
        parentItem = ufe.Hierarchy.createItem(parentPath)

        parentHierarchy = ufe.Hierarchy.hierarchy(parentItem)
        parentChildrenPre = parentHierarchy.children()
        self.assertEqual(len(parentChildrenPre), 6)

        # get the USD stage
        stage = mayaUsd.ufe.getStage(str(mayaPathSegment))

        # set the edit target to balls.usda
        layer = stage.GetLayerStack()[1]
        self.assertEqual("ballset.usda", layer.GetDisplayName())
        stage.SetEditTarget(layer)

        if (os.getenv('UFE_PREVIEW_VERSION_NUM', '0000') > '3000'):

            globalSn = ufe.GlobalSelection.get()
            globalSn.append(ball5Item)
            globalSn.append(ball3Item)

            # group
            groupName = cmds.group(ufe.PathString.string(ball5Path),
                                   ufe.PathString.string(ball3Path),
                                   n="newGroup")
        else:
            newGroupName = ufe.PathComponent("newGroup")

            ufeSelectionList = ufe.Selection()
            ufeSelectionList.append(ball5Item)
            ufeSelectionList.append(ball3Item)

            groupCmd = parentHierarchy.createGroupCmd(ufeSelectionList,
                                                      newGroupName)
            groupCmd.execute()

        # Group object (a.k.a parent) will be added to selection list. This behavior matches the native Maya group command.
        globalSelection = ufe.GlobalSelection.get()

        groupPath = ufe.Path([
            mayaPathSegment,
            usdUtils.createUfePathSegment("/Ball_set/Props/newGroup1")
        ])
        self.assertEqual(globalSelection.front(),
                         ufe.Hierarchy.createItem(groupPath))

        # Group object (a.k.a parent) will be added to selection list. This behavior matches the native Maya group command.
        globalSelection = ufe.GlobalSelection.get()

        groupPath = ufe.Path([
            mayaPathSegment,
            usdUtils.createUfePathSegment("/Ball_set/Props/newGroup1")
        ])
        self.assertEqual(globalSelection.front(),
                         ufe.Hierarchy.createItem(groupPath))

        parentChildrenPost = parentHierarchy.children()
        self.assertEqual(len(parentChildrenPost), 5)

        # The command will now append a number 1 at the end to match the naming
        # convention in Maya.
        if (os.getenv('UFE_PREVIEW_VERSION_NUM', '0000') > '3000'):
            newGroupPath = parentPath + ufe.PathComponent(groupName)
        else:
            newGroupPath = parentPath + ufe.PathComponent("newGroup1")

        # Make sure the new group item has the correct Usd type
        newGroupItem = ufe.Hierarchy.createItem(newGroupPath)
        newGroupPrim = usdUtils.getPrimFromSceneItem(newGroupItem)
        newGroupType = newGroupPrim.GetTypeName()
        self.assertEqual(newGroupType, 'Xform')

        childPaths = set([child.path() for child in parentChildrenPost])

        self.assertTrue(newGroupPath in childPaths)
        self.assertTrue(ball5Path not in childPaths)
        self.assertTrue(ball3Path not in childPaths)

        if (os.getenv('UFE_PREVIEW_VERSION_NUM', '0000') > '3000'):
            cmds.undo()
        else:
            groupCmd.undo()

        # global selection should not be empty after undo.
        if (os.getenv('UFE_PREVIEW_VERSION_NUM', '0000') > '3004'):
            self.assertEqual(len(globalSelection), 2)
        else:
            self.assertEqual(len(globalSelection), 1)

        parentChildrenUndo = parentHierarchy.children()
        self.assertEqual(len(parentChildrenUndo), 6)

        childPathsUndo = set([child.path() for child in parentChildrenUndo])
        self.assertTrue(newGroupPath not in childPathsUndo)
        self.assertTrue(ball5Path in childPathsUndo)
        self.assertTrue(ball3Path in childPathsUndo)

        if (os.getenv('UFE_PREVIEW_VERSION_NUM', '0000') > '3000'):
            cmds.redo()
        else:
            groupCmd.redo()

        # global selection should still have the group path.
        self.assertEqual(globalSelection.front(),
                         ufe.Hierarchy.createItem(groupPath))

        parentChildrenRedo = parentHierarchy.children()
        self.assertEqual(len(parentChildrenRedo), 5)

        childPathsRedo = set([child.path() for child in parentChildrenRedo])
        self.assertTrue(newGroupPath in childPathsRedo)
        self.assertTrue(ball5Path not in childPathsRedo)
        self.assertTrue(ball3Path not in childPathsRedo)
Ejemplo n.º 18
0
    def testGroupKind(self):
        """
        Tests that grouping maintains a contiguous model hierarchy when the
        parent of the group is in the model hierarchy.
        """
        mayaPathSegment = mayaUtils.createUfePathSegment(
            "|transform1|proxyShape1")

        usdSegmentBall3 = usdUtils.createUfePathSegment(
            "/Ball_set/Props/Ball_3")
        ball3Path = ufe.Path([mayaPathSegment, usdSegmentBall3])
        ball3Item = ufe.Hierarchy.createItem(ball3Path)

        usdSegmentBall5 = usdUtils.createUfePathSegment(
            "/Ball_set/Props/Ball_5")
        ball5Path = ufe.Path([mayaPathSegment, usdSegmentBall5])
        ball5Item = ufe.Hierarchy.createItem(ball5Path)

        usdSegmentProps = usdUtils.createUfePathSegment("/Ball_set/Props")
        propsPath = ufe.Path([mayaPathSegment, usdSegmentProps])
        propsItem = ufe.Hierarchy.createItem(propsPath)

        ufeSelection = ufe.GlobalSelection.get()
        ufeSelection.append(ball3Item)
        ufeSelection.append(ball5Item)

        groupName = "newGroup"
        cmds.group(name=groupName)

        newGroupPath = propsPath + ufe.PathComponent("%s1" % groupName)
        newGroupItem = ufe.Hierarchy.createItem(newGroupPath)
        newGroupPrim = usdUtils.getPrimFromSceneItem(newGroupItem)

        # The "Props" prim that was the parent of both "Ball" prims has
        # kind=group and is part of the model hierarchy, so the new group prim
        # should also have kind=group and be included in the model hierarchy.
        self.assertEqual(
            Usd.ModelAPI(newGroupPrim).GetKind(), Kind.Tokens.group)
        self.assertTrue(newGroupPrim.IsModel())

        cmds.undo()

        # Clear the kind metadata on the "Props" prim before testing again.
        propsPrim = usdUtils.getPrimFromSceneItem(propsItem)
        Usd.ModelAPI(propsPrim).SetKind("")
        self.assertFalse(propsPrim.IsModel())

        # Freshen the UFE scene items so they have valid handles to their
        # UsdPrims.
        ball3Item = ufe.Hierarchy.createItem(ball3Path)
        ball5Item = ufe.Hierarchy.createItem(ball5Path)

        ufeSelection.clear()
        ufeSelection.append(ball3Item)
        ufeSelection.append(ball5Item)

        cmds.group(name=groupName)

        newGroupItem = ufe.Hierarchy.createItem(newGroupPath)
        newGroupPrim = usdUtils.getPrimFromSceneItem(newGroupItem)

        # When the "Props" prim does not have an authored kind and is not part
        # of the model hierarchy, the new group prim should not have any kind
        # authored either.
        self.assertEqual(Usd.ModelAPI(newGroupPrim).GetKind(), "")
        self.assertFalse(newGroupPrim.IsModel())