pub struct Layer {
pub identifier: String,
/* private fields */
}Expand description
A single loaded layer in the composition.
Fields§
§identifier: StringResolved, canonical identifier for this layer.
Implementations§
Source§impl Layer
impl Layer
Sourcepub fn open(identifier: impl AsRef<str>) -> Result<Self>
pub fn open(identifier: impl AsRef<str>) -> Result<Self>
Open the layer at identifier off the filesystem, read in whichever
format claims it.
The layer is read alone: the sublayers, references and payloads it
declares stay the asset paths it authored. Composing them is
Stage::open’s job.
Sourcepub fn open_with(
resolver: impl Resolver + 'static,
identifier: impl AsRef<str>,
) -> Result<Self>
pub fn open_with( resolver: impl Resolver + 'static, identifier: impl AsRef<str>, ) -> Result<Self>
Open the layer at identifier, resolving and reading it through
resolver — the door for layers a host serves from somewhere other than
the filesystem. See open.
Sourcepub fn from_bytes(
tag: impl Display,
bytes: impl Into<AssetBuffer>,
) -> Result<Self, FormatError>
pub fn from_bytes( tag: impl Display, bytes: impl Into<AssetBuffer>, ) -> Result<Self, FormatError>
Decode bytes as an anonymous layer tagged tag, in whichever format
their content names (see
LayerRegistry::read_bytes).
For layer bytes that were never an asset — compiled into a program, or
handed over by a host. The layer is anonymous because it resolved from
nowhere, so the relative asset paths it authors anchor against nothing;
C++ opens the schema data it compiles against the same way
(SdfLayer::OpenAsAnonymous). tag names their origin for diagnostics,
as in new_anonymous.
Sourcepub fn add_sink<S: LayerSink + 'static>(&mut self, sink: S) -> LayerSinkId
pub fn add_sink<S: LayerSink + 'static>(&mut self, sink: S) -> LayerSinkId
Install a LayerSink fired at this layer’s commit seam, returning its
LayerSinkId for a later remove_sink. Any
editor of this layer — a stage, the namespace editor, raw authoring —
fires the sink, so an external observer sees every committed edit. A bare
Fn(&str, &ChangeList) closure is a LayerSink, so this takes either a
full sink type or a closure observer.
Sourcepub fn remove_sink(&mut self, id: LayerSinkId)
pub fn remove_sink(&mut self, id: LayerSinkId)
Remove the layer sink with id; a no-op if it was already removed.
Sourcepub fn data(&self) -> &dyn AbstractData
pub fn data(&self) -> &dyn AbstractData
Borrow the layer’s data as a read-only AbstractData. Reads see the
staged-over-base view, so edits staged but not yet flushed are visible.
Sourcepub fn edit(
&mut self,
f: impl FnOnce(&mut LayerEdit<'_>) -> Result<(), AuthoringError>,
) -> Result<bool, EditError>
pub fn edit( &mut self, f: impl FnOnce(&mut LayerEdit<'_>) -> Result<(), AuthoringError>, ) -> Result<bool, EditError>
Author a batch of edits as one atomic unit: run f against the layer’s
LayerEdit view, then commit on success, or roll back on f’s error, a
sink veto, or a panic. Returns whether the edit produced a composition
change. This is the only way to mutate a layer — the commit is the closing
brace, not a separate call a caller can omit — so an edit is never left
staged-but-uncommitted. Mirrors C++ scene description committing through
Sdf_ChangeManager. To edit several of a stage’s layers atomically, use
Stage::batch_edit.
Panics if called re-entrantly on the same layer.
§Example
use openusd::sdf::{self, PrimSpec, Specifier};
let mut layer = sdf::Layer::new_anonymous("example.usda");
// On success the batch commits and the change record is returned.
layer
.edit(|l| {
PrimSpec::new(l.data_mut(), "/World", Specifier::Def, "Xform")?;
Ok(())
})
.expect("authored and committed");
assert!(layer.prim("/World").unwrap().is_some());
// If the closure returns an error, the whole batch rolls back — neither
// spec below survives, because the second authoring call fails.
let result = layer.edit(|l| {
PrimSpec::new(l.data_mut(), "/Good", Specifier::Def, "Xform")?;
PrimSpec::new(l.data_mut(), "/Good.prop", Specifier::Def, "Xform")?; // property path: invalid for a prim
Ok(())
});
assert!(result.is_err());
assert!(layer.prim("/Good").unwrap().is_none());Sourcepub fn is_dirty(&self) -> bool
pub fn is_dirty(&self) -> bool
Whether the layer has edits staged in its overlay but not yet committed.
Mirrors C++ SdfLayer::IsDirty for the in-flight-edit case.
Conservative about staged content: any uncommitted overlay write counts, including an idempotent edit (a field re-set to the value the base already holds) whose commit would derive no composition change.
Sourcepub fn identifier(&self) -> &str
pub fn identifier(&self) -> &str
The layer’s resolved, canonical identifier.
Sourcepub fn resolved_path(&self) -> Option<&str>
pub fn resolved_path(&self) -> Option<&str>
Where the layer was found, or None for an anonymous layer, which was
never read from anywhere (C++ SdfLayer::GetRealPath, empty for one).
This is the identifier except for a package, whose location is its package-relative default layer, and a layer found through a resolver search directory, whose identifier is the bare search path it was asked for.
Source§impl Layer
impl Layer
Sourcepub fn export(&self, filename: impl AsRef<str>) -> Result<(), ExportError>
pub fn export(&self, filename: impl AsRef<str>) -> Result<(), ExportError>
Write this layer to filename, choosing the format from the filename’s
extension (C++ SdfLayer::Export). This writes a copy; the layer’s own
identifier is unchanged.
.usda writes text, .usdc writes the binary crate, .usd writes
binary (the C++ USD_WRITE_NEW_USD_FILES_AS_BINARY default), and
.usdz writes an archive wrapping one crate-encoded layer. The reader
auto-detects the format regardless of extension, so text written to a
.usd path still reads back correctly.
The file is written beside the destination and renamed over it once
complete, keeping the destination’s permissions. The destination is
therefore never a half-written file, and a file a layer reads from is
never written into. A destination this layer
itself reads from is written through save, which also
rebinds the layer to what it wrote.
Sourcepub fn export_to_string(&self) -> Result<String, ExportError>
pub fn export_to_string(&self) -> Result<String, ExportError>
Serialize this layer to a usda text string (C++ ExportToString).
Always emits text, the canonical human-readable form, regardless of the
layer’s on-disk format. Named to avoid confusion with the infallible
ToString::to_string.
Sourcepub fn save(&mut self) -> Result<(), ExportError>
pub fn save(&mut self) -> Result<(), ExportError>
Write this layer to its own identifier, choosing
the format from the identifier’s extension (C++ SdfLayer::Save).
The identifier must be an absolute filesystem path — the canonical form
the resolver produces for layers loaded from disk.
Anonymous layers (is_anonymous) and layers whose
identifier is a relative path or a non-filesystem asset identifier (e.g.
scheme://…) have no persistent location here; save them with
export and an explicit destination instead.
A save is three steps, each leaving the layer whole if it fails. The
layer is serialized in memory and written to a temporary file beside
its own; a failure there changes nothing. The temporary file is then
renamed over the layer’s own, which replaces it atomically. Last, a
layer whose data decodes from its bytes on demand (the crate format)
rebinds to the data its format built over the bytes it serialized
(FileFormat::write_bytes),
dropping the bytes it read before, which releases any view of its own
file it held. Data that copied everything out of its bytes stays as
it is.
A rename that fails (a destination that is no longer a file, a
filesystem that refuses it) is ExportError::Replace: the temporary
file is removed and the layer still rebinds, which holds its edits in
memory for a later save to retry. Rebinding is not an edit: no change
list is derived and no sink fires.
A layer opened through a resolver that maps files goes back onto a
mapping of the file it saved, and holds no heap copy of it (C++
CrateFile::Packer::Close reopens the saved asset through the resolver
and maps it again). The layer moves to the asset its resolver opens
only when that asset shares its bytes, the bytes are a file mapping,
and they equal the bytes just written. A resolver is free to answer
with something older than the file the save replaced, and data decoded
from that would put superseded values back in the layer; equal bytes
are what show the mapping to be the saved file. In every other case, a
failed open among them, the asset is dropped unread and the layer
stays on the bytes it serialized. The save has succeeded either way.
A view another layer holds of the file does not block the replacement: that layer goes on reading the file it mapped, which the rename unlinks and leaves as it was.
Source§impl Layer
Identity, persistence, and typed-view lookups. Spec authoring lives on the
views themselves (PrimSpec::new and friends,
mirroring C++ Sdf*Spec::New); they write through LayerEdit::data_mut, so
every edit stages in the layer’s overlay for the next flush to record.
impl Layer
Identity, persistence, and typed-view lookups. Spec authoring lives on the
views themselves (PrimSpec::new and friends,
mirroring C++ Sdf*Spec::New); they write through LayerEdit::data_mut, so
every edit stages in the layer’s overlay for the next flush to record.
The typed-view lookups (Layer::prim, Layer::attribute,
Layer::relationship, Layer::pseudo_root) operate through the
AbstractData field interface, so they work uniformly on any backend —
in-memory Data or a file-loaded reader — matching C++
SdfLayer::GetPrimAtPath.
Sourcepub fn new_anonymous(tag: impl Display) -> Self
pub fn new_anonymous(tag: impl Display) -> Self
Create a blank in-memory writable layer with a unique anonymous
identifier of the form anon:<n>:<tag>, mirroring C++
SdfLayer::CreateAnonymous. tag is a human-readable hint, not an
address: two calls with the same tag get distinct identifiers, so
independent anonymous layers never alias (see Layer::is_anonymous).
The layer’s pseudo-root spec is pre-populated so layer-level metadata
(defaultPrim, subLayers, time codes, …) can be authored via
LayerEdit::pseudo_root_mut immediately.
Sourcepub fn is_anonymous(&self) -> bool
pub fn is_anonymous(&self) -> bool
Whether this layer’s identifier is anonymous (the anon: prefix minted
by new_anonymous). Mirrors C++
SdfLayer::IsAnonymous; an anonymous layer has no asset-resolvable
location.
Sourcepub fn is_anonymous_identifier(identifier: &str) -> bool
pub fn is_anonymous_identifier(identifier: &str) -> bool
Whether identifier is an anonymous-layer identifier (the anon: prefix),
without needing the layer itself. Mirrors C++
SdfLayer::IsAnonymousLayerIdentifier; the prefix is the single source of
truth for anonymity.
Sourcepub fn prim(
&self,
path: impl IntoPath,
) -> Result<Option<PrimSpecRef<'_>>, PathParseError>
pub fn prim( &self, path: impl IntoPath, ) -> Result<Option<PrimSpecRef<'_>>, PathParseError>
Look up a prim spec at path. Ok(None) when no spec exists there or
the spec is not a prim; Err when path fails to parse.
Sourcepub fn attribute(
&self,
path: impl IntoPath,
) -> Result<Option<AttributeSpecRef<'_>>, PathParseError>
pub fn attribute( &self, path: impl IntoPath, ) -> Result<Option<AttributeSpecRef<'_>>, PathParseError>
Look up an attribute spec at a property path.
Sourcepub fn relationship(
&self,
path: impl IntoPath,
) -> Result<Option<RelationshipSpecRef<'_>>, PathParseError>
pub fn relationship( &self, path: impl IntoPath, ) -> Result<Option<RelationshipSpecRef<'_>>, PathParseError>
Look up a relationship spec at a property path.
Sourcepub fn pseudo_root(&self) -> Option<PseudoRootSpecRef<'_>>
pub fn pseudo_root(&self) -> Option<PseudoRootSpecRef<'_>>
View this layer’s root pseudo-spec, which carries layer-wide metadata
(defaultPrim, subLayers, time codes, …).
Sourcepub fn relocates(&self) -> RelocateList
pub fn relocates(&self) -> RelocateList
The list of namespace relocations authored in this layer’s metadata,
or an empty list when none are authored. Mirrors C++
SdfLayer::GetRelocates. Reads through the backing AbstractData, so
it works on both in-memory and file-loaded layers.
Sourcepub fn has_relocates(&self) -> bool
pub fn has_relocates(&self) -> bool
Whether this layer’s metadata carries any relocates opinion, including
an explicit empty list (an opinion that there should be no relocates).
Mirrors C++ SdfLayer::HasRelocates.
Sourcepub fn start_time_code(&self) -> f64
pub fn start_time_code(&self) -> f64
The layer’s startTimeCode, or 0.0 when unauthored. Mirrors C++
SdfLayer::GetStartTimeCode.
Sourcepub fn has_start_time_code(&self) -> bool
pub fn has_start_time_code(&self) -> bool
Whether this layer authors a startTimeCode opinion. Mirrors C++
SdfLayer::HasStartTimeCode.
Sourcepub fn end_time_code(&self) -> f64
pub fn end_time_code(&self) -> f64
The layer’s endTimeCode, or 0.0 when unauthored. Mirrors C++
SdfLayer::GetEndTimeCode.
Sourcepub fn has_end_time_code(&self) -> bool
pub fn has_end_time_code(&self) -> bool
Whether this layer authors an endTimeCode opinion. Mirrors C++
SdfLayer::HasEndTimeCode.
Sourcepub fn time_codes_per_second(&self) -> f64
pub fn time_codes_per_second(&self) -> f64
The layer’s timeCodesPerSecond. Falls back to the authored
framesPerSecond, then to 24.0, when unauthored. Mirrors C++
SdfLayer::GetTimeCodesPerSecond.
Sourcepub fn has_time_codes_per_second(&self) -> bool
pub fn has_time_codes_per_second(&self) -> bool
Whether this layer authors a timeCodesPerSecond opinion. Mirrors C++
SdfLayer::HasTimeCodesPerSecond.
Sourcepub fn frames_per_second(&self) -> f64
pub fn frames_per_second(&self) -> f64
The layer’s framesPerSecond, or 24.0 when unauthored. Mirrors C++
SdfLayer::GetFramesPerSecond.
Sourcepub fn has_frames_per_second(&self) -> bool
pub fn has_frames_per_second(&self) -> bool
Whether this layer authors a framesPerSecond opinion. Mirrors C++
SdfLayer::HasFramesPerSecond.
Sourcepub fn frame_precision(&self) -> i32
pub fn frame_precision(&self) -> i32
The layer’s framePrecision, or 3 when unauthored. Mirrors C++
SdfLayer::GetFramePrecision.
Sourcepub fn has_frame_precision(&self) -> bool
pub fn has_frame_precision(&self) -> bool
Whether this layer authors a framePrecision opinion. Mirrors C++
SdfLayer::HasFramePrecision.