Skip to content

Commit fd864e3

Browse files
anwang2009pixar-oss
authored andcommitted
Move sdf anonymous layer default file format to usda. Introduces SDF_LEGACY_FILE_FORMAT_IMPORT, which currently allows the legacy "#sdf 1.4.32" cookie to be ingested as "#usda 1.0".
See PixarAnimationStudios#3012 (Internal change: 2366602)
1 parent d7fcbfe commit fd864e3

4 files changed

Lines changed: 92 additions & 4 deletions

File tree

pxr/usd/sdf/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ pxr_test_scripts(
204204
testenv/testSdfFileFormat.py
205205
testenv/testSdfLayer.py
206206
testenv/testSdfLayerMuting.py
207+
testenv/testSdfLegacyFileFormat.py
207208
testenv/testSdfListOp.py
208209
testenv/testSdfParsing.py
209210
testenv/testSdfPath.py
@@ -536,6 +537,20 @@ pxr_register_test(testSdfLayerMuting
536537
COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testSdfLayerMuting"
537538
)
538539

540+
pxr_register_test(testSdfLegacyFileFormat
541+
PYTHON
542+
ENV
543+
SDF_FILE_FORMAT_LEGACY_IMPORT=allow
544+
COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testSdfLegacyFileFormat"
545+
)
546+
547+
pxr_register_test(testSdfLegacyFileFormat_Error
548+
PYTHON
549+
ENV
550+
SDF_FILE_FORMAT_LEGACY_IMPORT=error
551+
COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testSdfLegacyFileFormat"
552+
)
553+
539554
pxr_register_test(testSdfListOp
540555
PYTHON
541556
COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testSdfListOp"

pxr/usd/sdf/layer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
#include "pxr/usd/sdf/relationshipSpec.h"
2828
#include "pxr/usd/sdf/schema.h"
2929
#include "pxr/usd/sdf/specType.h"
30-
#include "pxr/usd/sdf/textFileFormat.h"
31-
#include "pxr/usd/sdf/types.h"
3230
#include "pxr/usd/sdf/subLayerListEditor.h"
31+
#include "pxr/usd/sdf/types.h"
32+
#include "pxr/usd/sdf/usdaFileFormat.h"
3333
#include "pxr/usd/sdf/variantSetSpec.h"
3434
#include "pxr/usd/sdf/variantSpec.h"
3535

@@ -335,7 +335,7 @@ SdfLayer::CreateAnonymous(
335335
}
336336

337337
if (!fileFormat) {
338-
fileFormat = SdfFileFormat::FindById(SdfTextFileFormatTokens->Id);
338+
fileFormat = SdfFileFormat::FindById(SdfUsdaFileFormatTokens->Id);
339339
}
340340

341341
if (!fileFormat) {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/pxrpythonsubst
2+
#
3+
# Copyright 2025 Pixar
4+
#
5+
# Licensed under the terms set forth in the LICENSE.txt file available at
6+
# https://openusd.org/license.
7+
8+
from pxr import Sdf, Tf
9+
import os
10+
import unittest
11+
12+
class TestSdfLegacyFileFormat(unittest.TestCase):
13+
def test_ReadLegacySdfFileFormat(self):
14+
legacyRead = Tf.GetEnvSetting("SDF_FILE_FORMAT_LEGACY_IMPORT")
15+
16+
layer = Sdf.Layer.CreateAnonymous()
17+
importStr = """#sdf 1.4.32
18+
def "Prim" {}
19+
"""
20+
21+
if legacyRead == "allow" or legacyRead == "warn":
22+
success = layer.ImportFromString(importStr)
23+
self.assertTrue(success)
24+
elif legacyRead == "error":
25+
with self.assertRaises(Tf.ErrorException):
26+
layer.ImportFromString(importStr)
27+
28+
if __name__ == "__main__":
29+
unittest.main()

pxr/usd/sdf/usdaFileFormat.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,24 @@ TF_DEFINE_ENV_SETTING(
3636
"Warn when reading a text file (.usda or .usda derived) larger than this "
3737
"number of MB (no warnings if set to 0)");
3838

39+
TF_DEFINE_ENV_SETTING(SDF_FILE_FORMAT_LEGACY_IMPORT, "allow",
40+
"By default, we allow imported strings with the legacy `#sdf 1.4.32` "
41+
"header format to be read as .usda version 1.0. When this is set to "
42+
"'warn,' a warning will be emitted when the usda file format attempts "
43+
"to import a string with header `#sdf 1.4.32`. When this is set to "
44+
"'error', strings imported with the sdf header will no longer be ingested "
45+
"and an error will be emitted.");
46+
47+
TF_DEFINE_PRIVATE_TOKENS(
48+
_tokens,
49+
50+
(allow)
51+
(warn)
52+
(error)
53+
((legacyCookie, "#sdf 1.4.32"))
54+
((modernCookie, "#usda 1.0"))
55+
);
56+
3957
// Our interface to the parser for parsing to SdfData.
4058
extern bool Sdf_ParseLayer(
4159
const string& context,
@@ -365,8 +383,34 @@ SdfUsdaFileFormat::ReadFromString(
365383
// code will eventually be removed, it's being put in place so as to provide
366384
// backward compatibility for in-code layer constructs to work with pegtl
367385
// parser also. This code should be removed when (USD-9838) gets worked on.
368-
const std::string trimmedStr = TfStringTrimLeft(str);
386+
std::string trimmedStr = TfStringTrimLeft(str);
369387

388+
// The legacy sdf format is deprecated in favor of the usda format.
389+
// Since `sdf 1.4.32` is equivalent in content to `usda 1.0`, allow
390+
// imported strings headed with the former to be read by the latter.
391+
if (TfStringStartsWith(trimmedStr, _tokens->legacyCookie)) {
392+
static const std::string readSdf =
393+
TfGetEnvSetting(SDF_FILE_FORMAT_LEGACY_IMPORT);
394+
395+
if (_tokens->allow == readSdf || _tokens->warn == readSdf) {
396+
trimmedStr = _tokens->modernCookie.GetString() +
397+
trimmedStr.substr((_tokens->legacyCookie).size());
398+
399+
if (_tokens->warn == readSdf) {
400+
TF_WARN("'%s' is a deprecated format for reading. "
401+
"Use '%s' instead.",
402+
_tokens->legacyCookie.GetText(),
403+
_tokens->modernCookie.GetText());
404+
}
405+
} else {
406+
TF_RUNTIME_ERROR("'%s' is not a supported format for reading. "
407+
"Use '%s' instead.",
408+
_tokens->legacyCookie.GetText(),
409+
_tokens->modernCookie.GetText());
410+
return false;
411+
}
412+
}
413+
370414
if (!Sdf_ParseLayerFromString(
371415
trimmedStr, GetFormatId(), GetVersionString(),
372416
TfDynamic_cast<SdfDataRefPtr>(data), &hints)) {

0 commit comments

Comments
 (0)