Ejemplo n.º 1
0
    def _modifyPrimItems(self, methodName, refresh=True):
        '''
        Perform the same modification action on an iterable of primItems
        as a single stage transaction.

        Parameters
        ----------
        methodName : str
            modifying method of VariablePrimHelper

        Returns
        -------
        List[VariablePrimHelper]
            modified items
        '''
        # TODO: include, exclude
        updatedItems = []
        with Sdf.ChangeBlock():
            for item in self.primHelpers:
                if getattr(item, methodName)(refresh=False):
                    updatedItems.append(item)
        if refresh:
            for item in updatedItems:
                item.refresh()

        return updatedItems
Ejemplo n.º 2
0
    def commitData(self, editor):
        # TODO: Add an UndoBlock

        editor_index = None
        if self.indexWidget(self.currentIndex()) == editor:
            editor_index = self.currentIndex()

        if not editor_index:
            super(SelectionEditTreeView, self).commitData(editor)
            return

        selection = None
        if self._selection_edit_mode == SelectionEditTreeView.SelectedEditColumnsOnly:
            selection = [i for i in self.selectionModel().selectedIndexes()
                         if i.column() == editor_index.column() and i != editor_index]

        # It's important to put all edits inside of an Sdf Change Block so they happen in a single pass and
        # no signals are emitted that may change state
        with Sdf.ChangeBlock():
            super(SelectionEditTreeView, self).commitData(editor)
            if selection:
                value = editor.value
                for index in selection:
                    # This try / except is covering for a very ugly and hard to isolate bug.  It appears that when
                    # commitData raises an exception, Qt holds onto some indices that should safely expire, triggering
                    # a deferred but hard crash.  I haven't found a reliable repro case, but this seems to make it
                    # go away.  A better solution likely involves better detection on the model side.
                    try:
                        self.model().setData(index, value, Qt.EditRole)
                    except Exception:
                        LOGGER.exception('Exception during multi-edit: {}'.format(traceback.format_exc()))
Ejemplo n.º 3
0
        def _ChangeAndVerify(newValDict, expectSignificantChange,
                             expectedTcps):

            # Just verify we have a tcps value and/or fps value to set
            self.assertTrue('tcps' in newValDict or 'fps' in newValDict)
            with Pcp._TestChangeProcessor(pcpCache) as cp:
                # Change block for when we're setting both fps and tcps
                with Sdf.ChangeBlock():
                    # Set the tcps value if present (None -> Clear)
                    if 'tcps' in newValDict:
                        val = newValDict['tcps']
                        if val is None:
                            layer.ClearTimeCodesPerSecond()
                            self.assertFalse(layer.HasTimeCodesPerSecond())
                        else:
                            layer.timeCodesPerSecond = val
                            self.assertTrue(layer.HasTimeCodesPerSecond())

                    # Set the fps value if present (None -> Clear)
                    if 'fps' in newValDict:
                        val = newValDict['fps']
                        if val is None:
                            layer.ClearFramesPerSecond()
                            self.assertFalse(layer.HasFramesPerSecond())
                        else:
                            layer.framesPerSecond = val
                            self.assertTrue(layer.HasFramesPerSecond())

                # Verify whether the change processor logged a significant
                # change for the expected affected paths or not based on
                # whether we expect a significant change.
                if expectSignificantChange:
                    self.assertEqual(cp.GetSignificantChanges(), affectedPaths)
                    # A significant change will have invalidated our
                    # prim's prim index.
                    self.assertFalse(pcpCache.FindPrimIndex('/A'))
                    # Recompute the new prim index
                    (pi, err) = pcpCache.ComputePrimIndex('/A')
                else:
                    # No significant should leave our prim's prim index
                    # valid.
                    self.assertEqual(cp.GetSignificantChanges(), [])
                    pi = pcpCache.FindPrimIndex('/A')
                    self.assertTrue(pi)

                refNode = pi.rootNode.children[0]
                ref2Node = refNode.children[0]

                # Verify the layer has the expected computed TCPS
                self.assertEqual(layer.timeCodesPerSecond, expectedTcps)
                # Verify the ref node offesets match the expected offsets
                # for the layer's expected computed TCPS.
                expectedOffsets = tcpsToExpecteOffsetsMap[expectedTcps]
                self.assertEqual(refNode.mapToRoot.timeOffset,
                                 expectedOffsets[0])
                self.assertEqual(ref2Node.mapToRoot.timeOffset,
                                 expectedOffsets[1])
Ejemplo n.º 4
0
def create_using_sdf():
    """Run the main execution of the current script."""
    layer = Sdf.Layer.CreateAnonymous()

    # TODO : Adding / Removing this ChangeBlock doesn't change the time
    # much. Is a change block only useful when authoring opinions?
    #
    with Sdf.ChangeBlock():
        _prepare_prim_specs_with_sdf(layer, PATHS)

    return layer.ExportToString()
Ejemplo n.º 5
0
 def makeVisible(self):
     if self.canChangeVis():
         # It is in general not kosher to use an Sdf.ChangeBlock around
         # operations at the Usd API level.  We have carefully arranged
         # (with insider knowledge) to have only "safe" mutations
         # happening inside the ChangeBlock.  We do this because
         # UsdImaging updates itself independently for each
         # Usd.Notice.ObjectsChanged it receives.  We hope to eliminate
         # the performance need for this by addressing bug #121992
         from pxr import Sdf
         with Sdf.ChangeBlock():
             UsdGeom.Imageable(self.prim).MakeVisible()
         self.visChanged()
Ejemplo n.º 6
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.º 7
0
    def test_156222(self):
        from pxr import Sdf, Usd

        # Test that removing all instances for a prototype prim and adding a new
        # instance with the same instancing key as the prototype causes the new
        # instance to be assigned to the prototype.
        l = Sdf.Layer.CreateAnonymous('.usda')
        Sdf.CreatePrimInLayer(l, '/Ref')

        # The bug is non-deterministic because of threaded composition,
        # but it's easier to reproduce with more instance prims.
        numInstancePrims = 50
        instancePrimPaths = [Sdf.Path('/Instance_{}'.format(i))
                             for i in range(numInstancePrims)]
        for path in instancePrimPaths:
            instancePrim = Sdf.CreatePrimInLayer(l, path)
            instancePrim.instanceable = True
            instancePrim.referenceList.Add(Sdf.Reference(primPath = '/Ref'))

        nonInstancePrim = Sdf.CreatePrimInLayer(l, '/NonInstance')
        nonInstancePrim.referenceList.Add(Sdf.Reference(primPath = '/Ref'))

        s = Usd.Stage.Open(l)
        self.assertEqual(len(s.GetPrototypes()), 1)

        # Check that the prototype prim is using one of the instanceable prim
        # index for its source.
        prototype = s.GetPrototypes()[0]
        prototypePath = prototype.GetPath()
        self.assertIn(prototype._GetSourcePrimIndex().rootNode.path,
                      instancePrimPaths)

        # In a single change block, uninstance all of the instanceable prims,
        # but mark the non-instance prim as instanceable.
        with Sdf.ChangeBlock():
            for path in instancePrimPaths:
                l.GetPrimAtPath(path).instanceable = False
            nonInstancePrim.instanceable = True

        # This should not cause a new prototype prim to be generated; instead, 
        # the prototype prim should now be using the newly-instanced prim index 
        # as its source.
        prototype = s.GetPrototypes()[0]
        self.assertEqual(prototype.GetPath(), prototypePath)
        self.assertEqual(prototype._GetSourcePrimIndex().rootNode.path,
                         nonInstancePrim.path)
Ejemplo n.º 8
0
    def commitData(self, editor):
        """override commit of data to allow us to edit multiple selected indexes
        """

        # TODO: Add an UndoBlock
        if self.indexWidget(self.currentIndex()) == editor:
            editorIndex = self.currentIndex()
        else:
            editorIndex = None

        if not editorIndex:
            super(TreeView, self).commitData(editor)
            return

        if self.__selectionEditMode == TreeView.SelectedEditColumnsOnly:
            selection = [
                i for i in self.selectionModel().selectedIndexes()
                if i.column() == editorIndex.column() and i != editorIndex
            ]
        else:
            selection = None

        # It's important to put all edits inside of an Sdf Change Block so
        # they happen in a single pass and no signals are emitted that may
        # change state
        with Sdf.ChangeBlock():
            super(TreeView, self).commitData(editor)
            if selection:
                value = editor.value
                for index in selection:
                    # This try / except is covering for a very ugly and hard
                    # to isolate bug.  It appears that when commitData
                    # raises an exception, Qt holds onto some indices that
                    # should safely expire, trigging a deferred but hard
                    # crash.  I haven't found a reliable repro case, but
                    # this seems to make it go away.  A better solution
                    # likely involves better detection on the model side.
                    try:
                        self.model().setData(index, value, QtCore.Qt.EditRole)
                    except Exception, e:
                        # TODO: We should do something better than printing to
                        # stderr
                        print("Exception during multi-edit:",
                              e,
                              file=sys.stderr)
Ejemplo n.º 9
0
def main():
    """Run the main execution of the current script."""
    layer = Sdf.Layer.CreateAnonymous()

    paths = {
        Sdf.Path("/AndMore"),
        Sdf.Path("/AnotherOne"),
        Sdf.Path("/AnotherOne/AndAnother"),
        Sdf.Path("/More"),
        Sdf.Path("/OkayNoMore"),
        Sdf.Path("/SomeSphere"),
        Sdf.Path("/SomeSphere/InnerPrim"),
        Sdf.Path("/SomeSphere/InnerPrim/LastOne"),
    }

    prefixes = set(prefix for path in paths for prefix in path.GetPrefixes())
    with Sdf.ChangeBlock():
        for path in prefixes:
            prim_spec = Sdf.CreatePrimInLayer(layer, path)
            prim_spec.specifier = Sdf.SpecifierDef
            prim_spec.typeName = UsdGeom.Xform.__name__

    print(layer.ExportToString())
Ejemplo n.º 10
0
 def Do(self, context):
     with Sdf.ChangeBlock():
         for prim in context.selectedPrims:
             prim.SetActive(False)
Ejemplo n.º 11
0
def ResetSessionVisibility(stage):
    session = stage.GetSessionLayer()
    from pxr import Sdf
    with Sdf.ChangeBlock():
        _RemoveVisibilityRecursive(session.pseudoRoot)
Ejemplo n.º 12
0
 def deactivate_selection(self):
     with Sdf.ChangeBlock():
         prims = self._get_selected_prims()
         for prim in prims:
             prim.SetActive(False)
Ejemplo n.º 13
0
 def clear_active_for_selection(self):
     with Sdf.ChangeBlock():
         prims = self._get_selected_prims()
         for prim in prims:
             prim.ClearActive()
Ejemplo n.º 14
0
 def Do(self):
     context = self.GetCurrentContext()
     with Sdf.ChangeBlock():
         for prim in context.selectedPrims:
             prim.SetActive(False)
Ejemplo n.º 15
0
    def _parseInstanceJSONFile(self, jsonFilename, subInstanceStageFilePath):
        # type: (str, str) -> None
        """
        Create USD Prim instances from the given Element JSON file.
        """
        with open(jsonFilename, 'r') as f:
            jsonData = json.load(f)

        layer = Sdf.Layer.CreateAnonymous(self.USDFileExtension)

        # Leverage the SDF API instead of the USD API in order to batch-create
        # Prims. This avoids fanning out change notifications, which results in
        # O(n2) performance and becomes *slow* when creating a large number of
        # instances -- which is the case here (sometimes upwards of a million
        # instances).
        with Sdf.ChangeBlock():
            instancersPrimSpecPath = '/Instancers'
            instancersPrimSpec = Sdf.CreatePrimInLayer(layer,
                                                       instancersPrimSpecPath)
            instancersPrimSpec.specifier = Sdf.SpecifierDef
            layer.defaultPrim = 'Instancers'

            for name, instances in jsonData.items():
                pointInstancerPrimSpecPath = instancersPrimSpecPath + '/' + self._getFileBasename(
                    name)
                pointInstancerPrimSpec = Sdf.CreatePrimInLayer(
                    layer, pointInstancerPrimSpecPath)
                pointInstancerPrimSpec.specifier = Sdf.SpecifierDef
                pointInstancerPrimSpec.typeName = 'PointInstancer'

                positionsBuffer = []
                orientationsBuffer = []
                for instanceName, instanceTransform in instances.items():
                    transformMatrix = Gf.Matrix4d(*instanceTransform)
                    positionsBuffer.append(
                        transformMatrix.ExtractTranslation())

                    quaternion = transformMatrix.ExtractRotation(
                    ).GetQuaternion().GetNormalized()
                    imaginaryComponents = quaternion.GetImaginary()
                    orientationsBuffer.append(
                        Gf.Quath(
                            quaternion.GetReal(),
                            Gf.Vec3h(imaginaryComponents[0],
                                     imaginaryComponents[1],
                                     imaginaryComponents[2])))

                positionsAttribute = Sdf.AttributeSpec(
                    pointInstancerPrimSpec, 'positions',
                    Sdf.ValueTypeNames.Vector3fArray)
                positionsAttribute.default = positionsBuffer

                orientationsAttribute = Sdf.AttributeSpec(
                    pointInstancerPrimSpec, 'orientations',
                    Sdf.ValueTypeNames.QuathArray)
                orientationsAttribute.default = orientationsBuffer

                protoIndicesAttribute = Sdf.AttributeSpec(
                    pointInstancerPrimSpec, 'protoIndices',
                    Sdf.ValueTypeNames.IntArray)
                protoIndicesAttribute.default = [0] * len(instances.items())

                meshReferencePrimSpecPath = pointInstancerPrimSpecPath + '/mesh'
                meshReferencePrimSpec = Sdf.CreatePrimInLayer(
                    layer, meshReferencePrimSpecPath)
                meshReferencePrimSpec.specifier = Sdf.SpecifierDef
                meshReferencePrimSpec.typeName = 'Mesh'
                relativeAssetFilePath = './' + os.path.relpath(
                    self._getAssetFilePathFromOBJFilePath(name),
                    self.PrimitivesDirectory).replace('\\', '/')
                meshReferencePrimSpec.referenceList.Prepend(
                    Sdf.Reference(relativeAssetFilePath))

                relationshipSpec = Sdf.RelationshipSpec(pointInstancerPrimSpec,
                                                        'prototypes',
                                                        custom=False)
                relationshipSpec.targetPathList.explicitItems.append(
                    meshReferencePrimSpecPath)

        layer.Export(subInstanceStageFilePath, comment='')
Ejemplo n.º 16
0
 def ClearActiveForSelection(self):
     with Sdf.ChangeBlock():
         prims = self._GetSelectedPrims()
         for prim in prims:
             prim.ClearActive()
Ejemplo n.º 17
0
 def DeactivateSelection(self):
     with Sdf.ChangeBlock():
         prims = self._GetSelectedPrims()
         for prim in prims:
             prim.SetActive(False)
Ejemplo n.º 18
0
 def do(self):
     context = self.get_current_context()
     with Sdf.ChangeBlock():
         for prim in context.selected_prims:
             prim.SetActive(False)