@@ -24,13 +24,15 @@ governing permissions and limitations under the License.
2424
2525// USD
2626#include < pxr/base/tf/pathUtils.h>
27+ #include < pxr/base/tf/stringUtils.h>
28+ #include < pxr/usd/ar/packageUtils.h>
2729#include < pxr/usd/usd/usdaFileFormat.h>
2830
2931PXR_NAMESPACE_OPEN_SCOPE
3032
3133using namespace adobe ::usd;
3234
33- const TfToken UsdGltfFileFormat::assetsPathToken (" gltfAssetsPath" );
35+ const TfToken UsdGltfFileFormat::assetsPathToken (" gltfAssetsPath" , TfToken::Immortal );
3436
3537TF_DEFINE_PUBLIC_TOKENS (UsdGltfFileFormatTokens, USDGLTF_FILE_FORMAT_TOKENS);
3638
@@ -89,32 +91,34 @@ UsdGltfFileFormat::CanRead(const std::string& filePath) const
8991 return true ;
9092}
9193
94+ /* static*/
9295bool
93- UsdGltfFileFormat::_ReadFromStream (SdfLayer* layer,
94- std::istream& input,
95- bool metadataOnly,
96- std::string* outErr,
97- std::istream& mtlinput) const
96+ UsdGltfFileFormat::OpenGltfAsset (const std::string& resolvedPath,
97+ std::shared_ptr<ArAsset>& asset,
98+ std::string& baseDir,
99+ bool & isAscii)
98100{
99- // // Read Obj data stream.
100- // UsdGltfStream gltfStream;
101- // if (!UsdObjReadDataFromStream(input, mtlinput, &gltfStream, outErr))
102- // return false;
103-
104- // // Translate obj to usd schema.
105- // SdfLayerRefPtr objAsUsd = UsdObjTranslateObjToUsd(gltfStream);
106- // if (!objAsUsd)
107- // return false;
108-
109- // // Move generated content into final layer.
110- // layer->TransferContent(objAsUsd);
101+ asset = ArGetResolver ().OpenAsset (ArResolvedPath (resolvedPath));
102+ if (!asset) {
103+ TF_WARN (" Couldn't open asset %s" , resolvedPath.c_str ());
104+ return false ;
105+ }
106+
107+ // Extract the inner most name of a potentially nest path, e.g. "archive.usdz[myAsset.gltf]"
108+ auto [packagePath, packagedPath] = ArSplitPackageRelativePathInner (resolvedPath);
109+
110+ // If we have a direct path on disk, we set the baseDir to the same folder
111+ if (packagedPath.empty ()) {
112+ baseDir = TfGetPathName (packagePath);
113+ }
114+
115+ const std::string& fileName = packagedPath.empty () ? packagePath : packagedPath;
116+ std::string ext = TfStringToLower (TfGetExtension (fileName));
117+ isAscii = (ext == " gltf" );
118+
111119 return true ;
112120}
113121
114- // void function(TfDebug::FILE_FORMAT_GLTF a) {
115- // TF_DEBUG_MSG(a, "Experiment debug cdoe\n");
116- // }
117-
118122bool
119123UsdGltfFileFormat::Read (PXR_NS::SdfLayer* layer,
120124 const std::string& resolvedPath,
@@ -123,44 +127,99 @@ UsdGltfFileFormat::Read(PXR_NS::SdfLayer* layer,
123127 TfStopwatch w;
124128 w.Start ();
125129 TF_DEBUG_MSG (FILE_FORMAT_GLTF, " Read: %s\n " , resolvedPath.c_str ());
126- SdfAbstractDataRefPtr layerData = InitData (layer->GetFileFormatArguments ());
127- GltfDataConstPtr data = TfDynamic_cast<const GltfDataConstPtr>(layerData);
128- UsdData usd;
130+
131+ std::shared_ptr<ArAsset> asset;
132+ std::string baseDir;
133+ bool isAscii = false ;
134+ if (!OpenGltfAsset (resolvedPath, asset, baseDir, isAscii)) {
135+ return false ;
136+ }
137+
138+ std::shared_ptr<const char > buffer = asset->GetBuffer ();
139+ size_t bufferSize = asset->GetSize ();
140+ TF_DEBUG_MSG (FILE_FORMAT_GLTF,
141+ " Type: %s, Base path: '%s', Size: %zu KB\n " ,
142+ isAscii ? " GLTF" : " GLB" ,
143+ baseDir.c_str (),
144+ bufferSize >> 10 );
145+
129146 tinygltf::Model gltf;
147+ GUARD (readGltfFromMemory (gltf, baseDir, isAscii, &*buffer, bufferSize),
148+ " Error reading glTF file\n " );
149+
150+ UsdData usd;
130151 ImportGltfOptions options;
131152 options.importGeometry = true ;
132153 options.importMaterials = true ;
133154 options.importImages = true ;
155+ GUARD (importGltf (options, gltf, usd, resolvedPath), " Error translating glTF to USD\n " );
156+
157+ SdfAbstractDataRefPtr layerData = InitData (layer->GetFileFormatArguments ());
158+ GltfDataConstPtr data = TfDynamic_cast<const GltfDataConstPtr>(layerData);
134159 WriteLayerOptions layerOptions;
135160 layerOptions.writeMaterialX = data->writeMaterialX ;
136161 layerOptions.pruneJoints = false ;
137162 layerOptions.assetsPath = data->assetsPath ;
138- GUARD ( readGltf (gltf, resolvedPath), " Error reading glTF file \n " ) ;
139- GUARD (importGltf (options, gltf, usd, resolvedPath), " Error translating glTF to USD \n " );
140- GUARD ( writeLayer (layerOptions, usd, layer, layerData, DEBUG_TAG, SdfFileFormat::_SetLayerData),
141- " Error writing to the USD layer\n " );
163+ std::string ext = isAscii ? " GLTF " : " GLB " ;
164+ GUARD (
165+ writeLayer (layerOptions, usd, layer, layerData, ext , DEBUG_TAG, SdfFileFormat::_SetLayerData),
166+ " Error writing to the USD layer\n " );
142167
168+ // Populate the GLTF resolver with the images we just parsed from the asset, so that we don't
169+ // have to open the asset again.
143170 if (options.importImages ) {
144171 Resolver::populateCache (resolvedPath, std::move (usd.images ));
145172 } else {
146173 Resolver::clearCache (resolvedPath);
147174 }
148175
149176 w.Stop ();
150- TF_DEBUG_MSG (FILE_FORMAT_GLTF, " Total time: %ld ms\n " , static_cast <long int >(w.GetMilliseconds ()));
177+ TF_DEBUG_MSG (
178+ FILE_FORMAT_GLTF, " Total time: %ld ms\n " , static_cast <long int >(w.GetMilliseconds ()));
179+
151180 return true ;
152181}
153182
154183bool
155184UsdGltfFileFormat::ReadFromString (SdfLayer* layer, const std::string& str) const
156185{
157- std::string error;
158- std::stringstream ss (str);
159- std::stringstream ssmtl (" " );
160- if (!_ReadFromStream (layer, ss, /* metadataOnly=*/ false , &error, ssmtl)) {
161- TF_RUNTIME_ERROR (" Failed to read GLTF data from string: %s" , error.c_str ());
162- return false ;
163- }
186+ TfStopwatch w;
187+ w.Start ();
188+ TF_DEBUG_MSG (FILE_FORMAT_GLTF, " ReadFromString: %zu KB\n " , str.size () >> 10 );
189+
190+ // We don't have a base directory for external references. So only complete GLTF files will work
191+ // with this path
192+ std::string baseDir;
193+ bool isAscii = true ;
194+
195+ tinygltf::Model gltf;
196+ GUARD (readGltfFromMemory (gltf, baseDir, isAscii, &str[0 ], str.size ()),
197+ " Error reading glTF from string\n " );
198+
199+ UsdData usd;
200+ ImportGltfOptions options;
201+ options.importGeometry = true ;
202+ options.importMaterials = true ;
203+ options.importImages = true ;
204+ GUARD (importGltf (options, gltf, usd, " " ), " Error translating glTF to USD\n " );
205+
206+ SdfAbstractDataRefPtr layerData = InitData (layer->GetFileFormatArguments ());
207+ GltfDataConstPtr data = TfDynamic_cast<const GltfDataConstPtr>(layerData);
208+ WriteLayerOptions layerOptions;
209+ layerOptions.writeMaterialX = data->writeMaterialX ;
210+ layerOptions.pruneJoints = false ;
211+ layerOptions.assetsPath = data->assetsPath ;
212+ std::string ext = isAscii ? " GLTF" : " GLB" ;
213+ GUARD (
214+ writeLayer (layerOptions, usd, layer, layerData, ext, DEBUG_TAG, SdfFileFormat::_SetLayerData),
215+ " Error writing to the USD layer\n " );
216+
217+ // Note, we can't populate the path resolver since we don't have an associated file
218+
219+ w.Stop ();
220+ TF_DEBUG_MSG (
221+ FILE_FORMAT_GLTF, " Total time: %ld ms\n " , static_cast <long int >(w.GetMilliseconds ()));
222+
164223 return true ;
165224}
166225
0 commit comments