예제 #1
0
    def CheckCompliance(self, inputFile):
        from pxr import Sdf, Usd, UsdUtils
        if not Usd.Stage.IsSupportedFile(inputFile):
            _AddError("Cannot open file '%s' on a USD stage." % args.inputFile)
            return

        # Collect all warnings using a diagnostic delegate.
        delegate = UsdUtils.CoalescingDiagnosticDelegate()
        usdStage = Usd.Stage.Open(inputFile)
        stageOpenDiagnostics = delegate.TakeUncoalescedDiagnostics()

        for rule in self._rules:
            rule.CheckStage(usdStage)
            rule.CheckDiagnostics(stageOpenDiagnostics)

        with Ar.ResolverContextBinder(usdStage.GetPathResolverContext()):
            # This recursively computes all of inputFiles's external
            # dependencies.
            (allLayers, allAssets, unresolvedPaths) = \
                    UsdUtils.ComputeAllDependencies(Sdf.AssetPath(inputFile))
            for rule in self._rules:
                rule.CheckUnresolvedPaths(unresolvedPaths)
                rule.CheckDependencies(usdStage, allLayers, allAssets)

            if self._rootPackageOnly:
                rootLayer = usdStage.GetRootLayer()
                if rootLayer.GetFileFormat().IsPackage():
                    packagePath = Ar.SplitPackageRelativePathInner(
                        rootLayer.identifier)[0]
                    self._CheckPackage(packagePath)
                else:
                    self._AddError(
                        "Root layer of the USD stage (%s) doesn't belong to "
                        "a package, but 'rootPackageOnly' is True!" %
                        Usd.Describe(usdStage))
            else:
                # Process every package just once by storing them all in a set.
                packages = set()
                for layer in allLayers:
                    if _IsPackageOrPackagedLayer(layer):
                        packagePath = Ar.SplitPackageRelativePathInner(
                            layer.identifier)[0]
                        packages.add(packagePath)
                    self._CheckLayer(layer)
                for package in packages:
                    self._CheckPackage(package)

                # Traverse the entire stage and check every prim.
                from pxr import Usd
                # Author all variant switches in the session layer.
                usdStage.SetEditTarget(usdStage.GetSessionLayer())
                allPrimsIt = iter(
                    Usd.PrimRange.Stage(usdStage,
                                        Usd.TraverseInstanceProxies()))
                self._TraverseRange(allPrimsIt, isStageRoot=True)
예제 #2
0
    def _CheckPackage(self, packagePath):
        self._Msg("Checking package <%s>." % packagePath)

        # XXX: Should we open the package on a stage to ensure that it is valid 
        # and entirely self-contained.

        from pxr import Usd
        pkgExt = Ar.GetResolver().GetExtension(packagePath)
        if pkgExt != "usdz":
            self._AddError("Package at path %s has an invalid extension." 
                           % packagePath)
            return

        # Check the parent package first.
        if Ar.IsPackageRelativePath(packagePath):
            parentPackagePath = Ar.SplitPackageRelativePathInner(packagePath)[0]
            self._CheckPackage(parentPackagePath)
        
        # Avoid checking the same parent package multiple times.
        if packagePath in self._checkedPackages:
            return
        self._checkedPackages.add(packagePath)

        resolvedPath = Ar.GetResolver().Resolve(packagePath)
        if len(resolvedPath) == 0:
            self._AddError("Failed to resolve package path '%s'." % packagePath)
            return

        zipFile = Usd.ZipFile.Open(resolvedPath)
        if not zipFile:
            self._AddError("Could not open package at path '%s'." % 
                           resolvedPath)
            return
        for rule in self._rules:
            rule.CheckZipFile(zipFile, packagePath)
예제 #3
0
    def RunCommand(self):
        if not self._item:
            return

        # Get layer path from item
        layerPath = getattr(self._item, "layerPath")
        if not layerPath:
            print("Error: Could not find layer file.")
            return

        if Ar.IsPackageRelativePath(layerPath):
            layerName = os.path.basename(
                Ar.SplitPackageRelativePathInner(layerPath)[1])
        else:
            layerName = os.path.basename(layerPath)

        layerName += ".tmp"

        usdeditExe = self._FindUsdEdit()
        if not usdeditExe:
            print(
                "Warning: Could not find 'usdedit', expected it to be in PATH."
            )
            return

        print("Opening file: %s" % layerPath)

        command = [usdeditExe, '-n', layerPath, '-p', layerName]

        subprocess.Popen(command, close_fds=True)
예제 #4
0
    def _CheckPackage(self, packagePath):
        self._Msg("Checking package <%s>." % packagePath)
        # XXX: Should we open the package on a stage to ensure that it is valid
        # and entirely self-contained.

        from pxr import Ar, Usd
        pkgExt = Ar.GetResolver().GetExtension(packagePath)
        if self._arkit and pkgExt != "usdz":
            self._AddFailedCheck(
                "Package at path %s has an invalid extension." % packagePath,
                ruleNum=5)
            return

        # Check the parent package first.
        if Ar.IsPackageRelativePath(packagePath):
            parentPackagePath = Ar.SplitPackageRelativePathInner(
                packagePath)[0]
            self._CheckPackage(parentPackagePath)

        # Avoid checking the same parent package multiple times.
        if packagePath in self._checkedPackages:
            return
        self._checkedPackages.add(packagePath)

        resolvedPath = Ar.GetResolver().Resolve(packagePath)
        if len(resolvedPath) == 0:
            self._AddError("Failed to resolve package path '%s'." %
                           packagePath)
            return

        zipFile = Usd.ZipFile.Open(resolvedPath)
        if not zipFile:
            self._AddError("Could not open package at path '%s'." %
                           resolvedPath)
            return

        fileNames = zipFile.GetFileNames()
        for fileName in fileNames:
            fileExt = Ar.GetResolver().GetExtension(fileName)
            if fileExt not in ComplianceChecker._allowedFileExtensions:
                self._AddFailedCheck(
                    "File '%s' in package '%s' has unknown or "
                    "unsupported extension '%s'." %
                    (fileName, packagePath, fileExt),
                    ruleNum=[4, 5])
            fileInfo = zipFile.GetFileInfo(fileName)
            offset = fileInfo.dataOffset
            if offset % 64 != 0:
                self._AddFailedCheck(
                    "File '%s' in package '%s' has an invalid "
                    "offset %s." % (fileName, packagePath, offset),
                    ruleNum=1)
            if fileInfo.compressionMethod != 0:
                self._AddFailedCheck(
                    "File '%s' in package '%s' has "
                    "compression. Compression method is '%s', actual size is "
                    "%s. Uncompressed size is %s." %
                    (fileName, packagePath, fileInfo.compressionMethod,
                     fileInfo.size, fileInfo.uncompressedSize),
                    ruleNum=2)
예제 #5
0
 def _CheckRootPackage(self, usdStage):
     from pxr import Ar
     rootLayer = usdStage.GetRootLayer()
     if rootLayer.GetFileFormat().IsPackage():
         packagePath = Ar.SplitPackageRelativePathInner(
             rootLayer.identifier)[0]
         self._CheckPackage(packagePath)
     else:
         self._AddError(
             "Root layer of the USD stage (%s) doesn't belong to "
             "a package!" % Usd.Describe(usdStage))
예제 #6
0
    def _CheckDependencies(self, usdStage, layerDeps, assetDeps,
                           unresolvedPaths):
        from pxr import Ar

        def _IsPackageOrPackagedLayer(layer):
            return layer.GetFileFormat().IsPackage() or \
                    Ar.IsPackageRelativePath(layer.identifier)

        # Process every package just once by storing them all in a set.
        packages = set()
        for layer in layerDeps:
            if _IsPackageOrPackagedLayer(layer):
                packagePath = Ar.SplitPackageRelativePathInner(
                    layer.identifier)[0]
                packages.add(packagePath)
            self._CheckLayer(layer)
        for package in packages:
            self._CheckPackage(package)

        # If the root layer is a package, validate that all the loaded layers
        # belong to the package.
        rootLayer = usdStage.GetRootLayer()
        if self._arkit and _IsPackageOrPackagedLayer(rootLayer):
            packagePath = usdStage.GetRootLayer().realPath
            if packagePath:
                if Ar.IsPackageRelativePath(packagePath):
                    packagePath = Ar.SplitPackageRelativePathOuter(
                        packagePath)[0]
                for layer in layerDeps:
                    # In-memoery layers that session layers won't have a real
                    # path. We can skip them.
                    if layer.realPath:
                        if not layer.realPath.startswith(packagePath):
                            self._AddFailedCheck(
                                "Found loaded layer '%s' that "
                                "does not belong to the package '%s'." %
                                (layer.identifier, packagePath),
                                ruleNum=4)
                for asset in assetDeps:
                    if not asset.startswith(packagePath):
                        self._AddFailedCheck(
                            "Found asset reference '%s' that "
                            "does not belong to the package '%s'." %
                            (asset, packagePath),
                            ruleNum=4)

        for unresolvedPath in unresolvedPaths:
            self._AddFailedCheck(
                "Found unresolvable external dependency '%s'." %
                unresolvedPath,
                ruleNum=4)
예제 #7
0
    def test_SplitPackageRelativePathInner(self):
        """Test Ar.SplitPackageRelativePathInner"""
        self.assertEqual(Ar.SplitPackageRelativePathInner(""), ("", ""))
        self.assertEqual(Ar.SplitPackageRelativePathInner("foo.file"),
                         ("foo.file", ""))
        self.assertEqual(
            Ar.SplitPackageRelativePathInner("foo.pack[bar.file]"),
            ("foo.pack", "bar.file"))
        self.assertEqual(
            Ar.SplitPackageRelativePathInner("foo.pack[bar.pack[baz.file]]"),
            ("foo.pack[bar.pack]", "baz.file"))
        self.assertEqual(
            Ar.SplitPackageRelativePathInner("foo[0].pack[bar.file]"),
            ("foo[0].pack", "bar.file"))

        # Corner case: ensure delimiter characters in paths are unescaped
        # when removed from delimiters by Ar.SplitPackageRelativePathInner.
        self.assertEqual(
            Ar.SplitPackageRelativePathInner(
                "foo]a.pack[bar\\[b.pack[baz\\]c.file]]"),
            ("foo]a.pack[bar\\[b.pack]", "baz]c.file"))