def convert_to_usd(gltf_file, usd_file, fps, scale, arkit=False, verbose=False, use_euler_rotation=False): """Converts a glTF file to USD Arguments: gltf_file {str} -- path to glTF file usd_file {str} -- path to write USD file Keyword Arguments: verbose {bool} -- [description] (default: {False}) """ usd = GLTF2USD(gltf_file=gltf_file, usd_file=usd_file, fps=fps, scale=scale, verbose=verbose, use_euler_rotation=use_euler_rotation) if usd.stage: asset = usd.stage.GetRootLayer() usd.logger.info('Conversion complete!') asset.Save() usd.logger.info('created {}'.format(asset.realPath)) if usd_file.endswith('.usdz') or usd_file.endswith('.usdc'): usdc_file = '%s.%s' % (os.path.splitext(usd_file)[0], 'usdc') asset.Export(usdc_file, args=dict(format='usdc')) usd.logger.info('created {}'.format(usdc_file)) if usd_file.endswith('.usdz'): r = Ar.GetResolver() resolved_asset = r.Resolve(usdc_file) context = r.CreateDefaultContextForAsset(resolved_asset) success = check_usd_compliance(resolved_asset, arkit=args.arkit) with Ar.ResolverContextBinder(context): if arkit and not success: usd.logger.warning('USD is not ARKit compliant') return success = UsdUtils.CreateNewUsdzPackage( resolved_asset, usd_file) and success if success: usd.logger.info( 'created package {} with contents:'.format(usd_file)) zip_file = Usd.ZipFile.Open(usd_file) file_names = zip_file.GetFileNames() for file_name in file_names: usd.logger.info('\t{}'.format(file_name)) else: usd.logger.error('could not create {}'.format(usd_file))
def main(): parser = argparse.ArgumentParser( description='Utility for creating a .usdz ' 'file containging USD assets and for inspecting existing .usdz files.') parser.add_argument('usdzFile', type=str, nargs='?', help='Name of the .usdz file to create or to inspect ' 'the contents of.') parser.add_argument('inputFiles', type=str, nargs='*', help='Files to include in the .usdz file.') parser.add_argument('-r', '--recurse', dest='recurse', action='store_true', help='If specified, files in sub-directories are ' 'recursively added to the package.') parser.add_argument( '-a', '--asset', dest='asset', type=str, help='Resolvable asset path pointing to the root layer ' 'of the asset to be isolated and copied into the ' 'package.') parser.add_argument("--arkitAsset", dest="arkitAsset", type=str, help="Similar to the --asset option, the --arkitAsset " "option packages all of the dependencies of the named " "scene file. Assets targeted at the initial usdz " "implementation in ARKit operate under greater " "constraints than usdz files for more general 'in " "house' uses, and this option attempts to ensure that " "these constraints are honored; this may involve more " "transformations to the data, which may cause loss of " "features such as VariantSets.") parser.add_argument( '-c', '--checkCompliance', dest='checkCompliance', action='store_true', help='Perform compliance checking ' 'of the input files. If the input asset or \"root\" ' 'layer fails any of the compliance checks, the package ' 'is not created and the program fails.') parser.add_argument( '-l', '--list', dest='listTarget', type=str, nargs='?', default=None, const='-', help='List contents of the specified usdz file. If ' 'a file-path argument is provided, the list is output ' 'to a file at the given path. If no argument is ' 'provided or if \'-\' is specified as the argument, the' ' list is output to stdout.') parser.add_argument( '-d', '--dump', dest='dumpTarget', type=str, nargs='?', default=None, const='-', help='Dump contents of the specified usdz file. If ' 'a file-path argument is provided, the contents are ' 'output to a file at the given path. If no argument is ' 'provided or if \'-\' is specified as the argument, the' ' contents are output to stdout.') parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='Enable verbose mode, which causes messages ' 'regarding files being added to the package to be ' 'output to stdout.') args = parser.parse_args() usdzFile = args.usdzFile inputFiles = args.inputFiles if args.asset and args.arkitAsset: parser.error("Specify either --asset or --arkitAsset, not both.") elif (args.arkitAsset or args.asset) and len(inputFiles) > 0: parser.error("Specify either inputFiles or an asset (via --asset or " "--arkitAsset, not both.") # If usdzFile is not specified directly as an argument, check if it has been # specified as an argument to the --list or --dump options. In these cases, # output the list or the contents to stdout. if not usdzFile: if args.listTarget and args.listTarget != '-' and \ args.listTarget.endswith('.usdz') and \ os.path.exists(args.listTarget): usdzFile = args.listTarget args.listTarget = '-' elif args.dumpTarget and args.dumpTarget != '-' and \ args.dumpTarget.endswith('.usdz') and \ os.path.exists(args.dumpTarget): usdzFile = args.dumpTarget args.dumpTarget = '-' else: parser.error("No usdz file specified!") # Check if we're in package creation mode and verbose mode is enabled, # print some useful information. if (args.asset or args.arkitAsset or len(inputFiles) > 0): # Ensure that the usdz file has the right extension. if not usdzFile.endswith('.usdz'): usdzFile += '.usdz' if args.verbose: if os.path.exists(usdzFile): print("File at path '%s' already exists. Overwriting file." % usdzFile) if args.inputFiles: print('Creating package \'%s\' with files %s.' % (usdzFile, inputFiles)) if args.asset or args.arkitAsset: Tf.Debug.SetDebugSymbolsByName("USDUTILS_CREATE_USDZ_PACKAGE", 1) if not args.recurse: print('Not recursing into sub-directories.') else: if args.checkCompliance: parser.error( "--checkCompliance should only be specified when " "creatinga usdz package. Please use 'usdchecker' to check " "compliance of an existing .usdz file.") success = True if len(inputFiles) > 0: success = _CreateUsdzPackage(usdzFile, inputFiles, args.recurse, args.checkCompliance, args.verbose) and success elif args.asset: r = Ar.GetResolver() resolvedAsset = r.Resolve(args.asset) if args.checkCompliance: success = _CheckCompliance(resolvedAsset, arkit=False) and success context = r.CreateDefaultContextForAsset(resolvedAsset) with Ar.ResolverContextBinder(context): # Create the package only if the compliance check was passed. success = success and UsdUtils.CreateNewUsdzPackage( Sdf.AssetPath(args.asset), usdzFile) elif args.arkitAsset: r = Ar.GetResolver() resolvedAsset = r.Resolve(args.arkitAsset) if args.checkCompliance: success = _CheckCompliance(resolvedAsset, arkit=True) and success context = r.CreateDefaultContextForAsset(resolvedAsset) with Ar.ResolverContextBinder(context): # Create the package only if the compliance check was passed. success = success and UsdUtils.CreateNewARKitUsdzPackage( Sdf.AssetPath(args.arkitAsset), usdzFile) if args.listTarget or args.dumpTarget: if os.path.exists(usdzFile): zipFile = Usd.ZipFile.Open(usdzFile) if zipFile: if args.dumpTarget: if args.dumpTarget == usdzFile: _Err("The file into which to dump the contents of the " "usdz file '%s' must be different from the file " "itself." % usdzFile) return 1 _DumpContents(args.dumpTarget, zipFile) if args.listTarget: if args.listTarget == usdzFile: _Err("The file into which to list the contents of the " "usdz file '%s' must be different from the file " "itself." % usdzFile) return 1 _ListContents(args.listTarget, zipFile) else: _Err("Failed to open usdz file at path '%s'." % usdzFile) else: _Err("Can't find usdz file at path '%s'." % usdzFile) return 0 if success else 1
default=0, type=int, action='store') parser.add_argument('--numErrors', dest='numErrors', default=0, type=int, action='store') args = parser.parse_args() context = Ar.GetResolver().CreateDefaultContextForAsset(args.assetPath) with Ar.ResolverContextBinder(context): if not args.arkit: assert UsdUtils.CreateNewUsdzPackage( Sdf.AssetPath(args.assetPath), args.usdzFile, args.rename if args.rename else '') else: assert UsdUtils.CreateNewARKitUsdzPackage( Sdf.AssetPath(args.assetPath), args.usdzFile, args.rename if args.rename else '') zipFile = Usd.ZipFile.Open(args.usdzFile) assert zipFile with stream(args.outfile, 'w') as ofp: for fileName in zipFile.GetFileNames(): print >> ofp, fileName # Validate that the usdz file can be opened on a stage. stage = Usd.Stage.Open(args.usdzFile)
def convert_to_usd(gltf_file, usd_file, fps, scale, arkit=False, verbose=False, use_euler_rotation=False, optimize_textures=False, generate_texture_transform_texture=True, scale_texture=False): """Converts a glTF file to USD Arguments: gltf_file {str} -- path to glTF file usd_file {str} -- path to write USD file Keyword Arguments: verbose {bool} -- [description] (default: {False}) """ temp_dir = tempfile.mkdtemp() temp_usd_file = os.path.join(temp_dir, ntpath.basename(usd_file)) try: usd = GLTF2USD(gltf_file=gltf_file, usd_file=temp_usd_file, fps=fps, scale=scale, verbose=verbose, use_euler_rotation=use_euler_rotation, optimize_textures=optimize_textures, generate_texture_transform_texture= generate_texture_transform_texture, scale_texture=scale_texture) if usd.stage: asset = usd.stage.GetRootLayer() gltf_asset = usd.gltf_loader.get_asset() if gltf_asset: gltf_metadata = {'creator': 'gltf2usd v{}'.format(__version__)} if gltf_asset.generator: gltf_metadata['gltf_generator'] = gltf_asset.generator if gltf_asset.version: gltf_metadata['gltf_version'] = gltf_asset.version if gltf_asset.minversion: gltf_metadata['gltf_minversion'] = gltf_asset.minversion if gltf_asset.copyright: gltf_metadata['gltf_copyright'] = gltf_asset.copyright if gltf_asset.extras: for key, value in gltf_asset.extras.items(): gltf_metadata['gltf_extras_{}'.format(key)] = value asset.customLayerData = gltf_metadata usd.logger.info('Conversion complete!') asset.Save() usd.logger.info('created {}'.format(asset.realPath)) if not os.path.isdir(os.path.dirname(usd_file)): os.makedirs(os.path.dirname(usd_file)) if temp_usd_file.endswith('.usdz') or temp_usd_file.endswith( '.usdc'): usdc_file = '%s.%s' % (os.path.splitext(temp_usd_file)[0], 'usdc') asset.Export(usdc_file, args=dict(format='usdc')) usd.logger.info('created {}'.format(usdc_file)) if temp_usd_file.endswith('.usdz'): #change to directory of the generated usd files to avoid issues with # relative paths with CreateNewUsdzPackage os.chdir(os.path.dirname(usdc_file)) temp_usd_file = ntpath.basename(temp_usd_file) r = Ar.GetResolver() resolved_asset = r.Resolve(ntpath.basename(usdc_file)) context = r.CreateDefaultContextForAsset(resolved_asset) success = check_usd_compliance(resolved_asset, arkit=args.arkit) with Ar.ResolverContextBinder(context): if arkit and not success: usd.logger.warning('USD is not ARKit compliant') return success = UsdUtils.CreateNewUsdzPackage( resolved_asset, temp_usd_file) and success if success: shutil.copyfile(temp_usd_file, usd_file) usd.logger.info( 'created package {} with contents:'.format( usd_file)) zip_file = Usd.ZipFile.Open(usd_file) file_names = zip_file.GetFileNames() for file_name in file_names: usd.logger.info('\t{}'.format(file_name)) else: usd.logger.error( 'could not create {}'.format(usd_file)) else: # Copy textures referenced in the Usda/Usdc files from the temp directory to the target directory temp_stage = Usd.Stage.Open(temp_usd_file) usd_uv_textures = [ x for x in temp_stage.Traverse() if x.IsA(UsdShade.Shader) and UsdShade.Shader(x).GetShaderId() == 'UsdUVTexture' ] for usd_uv_texture in usd_uv_textures: file_name = usd_uv_texture.GetAttribute( 'inputs:file').Get() if file_name: file_name = str(file_name).replace('@', '') if os.path.isfile(os.path.join(temp_dir, file_name)): shutil.copyfile( os.path.join(temp_dir, file_name), os.path.join(os.path.dirname(usd_file), file_name)) shutil.copyfile(temp_usd_file, usd_file) finally: shutil.rmtree(temp_dir)