Skip to main content

Layer

Struct Layer 

Source
pub struct Layer {
    pub identifier: String,
    /* private fields */
}
Expand description

A single loaded layer in the composition.

Fields§

§identifier: String

Resolved, canonical identifier for this layer.

Implementations§

Source§

impl Layer

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn remove_sink(&mut self, id: LayerSinkId)

Remove the layer sink with id; a no-op if it was already removed.

Source

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.

Source

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());
Source

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.

Source

pub fn identifier(&self) -> &str

The layer’s resolved, canonical identifier.

Source

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

Source

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.

Source

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.

Source

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.

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn attribute( &self, path: impl IntoPath, ) -> Result<Option<AttributeSpecRef<'_>>, PathParseError>

Look up an attribute spec at a property path.

Source

pub fn relationship( &self, path: impl IntoPath, ) -> Result<Option<RelationshipSpecRef<'_>>, PathParseError>

Look up a relationship spec at a property path.

Source

pub fn pseudo_root(&self) -> Option<PseudoRootSpecRef<'_>>

View this layer’s root pseudo-spec, which carries layer-wide metadata (defaultPrim, subLayers, time codes, …).

Source

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.

Source

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.

Source

pub fn start_time_code(&self) -> f64

The layer’s startTimeCode, or 0.0 when unauthored. Mirrors C++ SdfLayer::GetStartTimeCode.

Source

pub fn has_start_time_code(&self) -> bool

Whether this layer authors a startTimeCode opinion. Mirrors C++ SdfLayer::HasStartTimeCode.

Source

pub fn end_time_code(&self) -> f64

The layer’s endTimeCode, or 0.0 when unauthored. Mirrors C++ SdfLayer::GetEndTimeCode.

Source

pub fn has_end_time_code(&self) -> bool

Whether this layer authors an endTimeCode opinion. Mirrors C++ SdfLayer::HasEndTimeCode.

Source

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.

Source

pub fn has_time_codes_per_second(&self) -> bool

Whether this layer authors a timeCodesPerSecond opinion. Mirrors C++ SdfLayer::HasTimeCodesPerSecond.

Source

pub fn frames_per_second(&self) -> f64

The layer’s framesPerSecond, or 24.0 when unauthored. Mirrors C++ SdfLayer::GetFramesPerSecond.

Source

pub fn has_frames_per_second(&self) -> bool

Whether this layer authors a framesPerSecond opinion. Mirrors C++ SdfLayer::HasFramesPerSecond.

Source

pub fn frame_precision(&self) -> i32

The layer’s framePrecision, or 3 when unauthored. Mirrors C++ SdfLayer::GetFramePrecision.

Source

pub fn has_frame_precision(&self) -> bool

Whether this layer authors a framePrecision opinion. Mirrors C++ SdfLayer::HasFramePrecision.

Trait Implementations§

Source§

impl Debug for Layer

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Layer

§

impl !Send for Layer

§

impl !Sync for Layer

§

impl !UnwindSafe for Layer

§

impl Freeze for Layer

§

impl Unpin for Layer

§

impl UnsafeUnpin for Layer

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.