Skip to content

Instantly share code, notes, and snippets.

@meshula
Created August 27, 2025 16:20
Show Gist options
  • Save meshula/2d119caa605b7ae524056294edc18c5c to your computer and use it in GitHub Desktop.
Save meshula/2d119caa605b7ae524056294edc18c5c to your computer and use it in GitHub Desktop.
relocates specification

Relocates Arc

Overview

The relocates composition arc provides non-destructive namespace remapping of prims from remote layer stacks to new path locations in the local namespace. Relocates enable reparenting or renaming of prims in situations where direct editing of the composition source would be destructive, affecting all other contexts that reference the same scene description.

Purpose and Rationale

Relocates address a fundamental limitation in USD composition: prims with underlying PrimSpecs from composition arcs cannot be directly reparented without modifying the source scene description. While it is technically possible to reparent composition source prims directly, such changes are destructive and would affect all other instances that share that scene description.

Relocates provide a solution by allowing non-destructive namespace transformation through path mapping specifications in layer metadata, ensuring that:

  • Source composition targets remain unmodified
  • Changes apply only within the local composition context
  • Multiple referencing contexts can apply different relocates independently
  • Complex namespace reorganization can be achieved without asset modification

Layer Metadata Specification

Relocates are defined in layer metadata using the relocates field, which contains a dictionary mapping source paths to target paths:

#usda 1.0
(
    relocates = {
        </SourcePrim/Child> : </TargetLocation/NewChild>,
        </AnotherSource> : </NewLocation>
    }
)

Syntax

  • Dictionary Format: The relocates field must be a dictionary with source-to-target path mappings
  • Prim Paths Only: Both source and target paths must be prim paths; property paths are not supported
  • Absolute Paths: All paths must be absolute paths beginning with /
  • Multiple Mappings: A single layer can specify multiple relocates mappings

Field Name Convention

The relocates dictionary uses the field name relocates in USD text syntax, corresponding to the internal layerRelocates field in the USD data model.

Composition Algorithm Integration

Relocates Processing

Although Relocates appears in the LIVERPS strength ordering acroynm as E, it is not a composition arc per se. During composition, relocates are applied to each arc as it is being processed. For each prim being composed:

  1. Target Path Matching: Examine all relocates entries in the current layer stack to find entries whose target path matches the prim's current path
  2. Source Resolution: If a matching target is found, execute composition on the mapped source path in the appropriate layer stack
  3. Opinion Integration: Add the resolved source opinions to the prim's composition
  4. Ancestral Opinion Removal: Remove all previously-computed ancestral opinions except those from ancestral variant arcs. Note that until all composition is resolved, a list of removed ancestral opinions must be maintained for reference.

Namespace Mapping for Relocates

Composition arcs authored in layer stacks with relocates receive additional namespace mapping composed on top of their standard namespace mappings. This additional mapping includes:

  1. Prefix Matching: Identify all relocates entries whose source paths are prefixed by the path where the composition arc is authored
  2. Mapping Construction: Create namespace mapping entries that map the source namespace at or under the relocates source path to the corresponding relocates target path
  3. Composition: Compose the relocates namespace mapping with the arc's standard namespace mapping

Example of Namespace Mapping Composition

Given a layer with relocates:

#usda 1.0
(
    relocates = {
        </Model/Geometry> : </Model/RenamedGeometry>,
        </Other/Objects> : </Other/NewObjects>
    }
)

def "Model" (
    references = @source.usd@</Source>
)
{
}

The relocates namespace mapping for /Model includes [(/Model/Geometry, /Model/RenamedGeometry)]. When composing the reference arc, this combines with the standard reference mapping [(/Source, /Model)] to produce the final mapping [(/Source, /Model), (/Source/Geometry, /Model/RenamedGeometry)].

Validation Rules and Error Conditions

Invalid Relocates Entries

The following relocates entries are composition errors and will be ignored:

  1. Root/Pseudo-Root Restriction: Relocates cannot apply to the pseudo-root (/) or root prim paths
  2. Non-Prim Paths: Source and target paths must be prim paths, not property or variant selection paths
  3. Ancestral Conflicts: A relocate may not place a prim at the location of an existing ancestor (e.g., /Prim/Child/GrandChild to /Prim/Child)
  4. Descendant Cycles: A relocate may not place a target path below a source path (e.g., /Prim/Child to /Prim/Child/GrandChild)
  5. Uniqueness Violations: Each source path may have only one target, and each target may have only one source
  6. Self-Reference: A target path must not be identical to its source path
  7. Ancestral Relocates Consistency: When ancestral relocates exist, relocate source paths must use the relocated ancestral path

Example of Ancestral Relocates Consistency

If /Root references /Ref, and /Ref also references /Ref2, and /Root/Ref is relocated to /Root/RefRelocated, then any additional relocate using /Root/Ref/Ref2 as a source path must use the relocated path /Root/RefRelocated/Ref2.

Source Opinion Conflicts

If opinions are authored in a layer stack at a source path of a relocates statement in that same layer stack, it is a composition error and those source opinions are ignored. This prevents conflicts between relocated content and local opinions at the source location.

Stage Population Integration

Ordered Prim Children with Relocates

During stage population, relocates affect the computation of ordered prim children. For each layer stack in reverse strength order:

  1. Relocates Analysis: Retrieve relocates that affect the children of the current scene object, producing:

    • removed_children: Token set of children that have been relocated away
    • extended_children: Token set of children that have been relocated into this location
    • renamed_children: Dictionary mapping original child names to new names
  2. Child List Processing:

    • Remove children present in removed_children
    • Replace children according to renamed_children mappings
    • Append path-element-sorted extended_children
    • Track relocated_names to prevent reuse
  3. Final Filtering: Exclude any child names present in relocated_names from the final result

Relocates and Inheritance

Relocated prims continue to receive the same opinions from inherit arcs they would have received if not relocated. This ensures that inheritance relationships remain intact across namespace transformations.

Practical Usage Examples

Basic Renaming Example

Source asset character.usd:

#usda 1.0
(
    defaultPrim = "Character"
)

def "Character"
{
    def "Clothing"
    {
        def "Shirt" { }
        def "Pants" { }
    }
}

Referencing layer with relocates:

#usda 1.0
(
    relocates = {
        </CharacterRoot/Clothing> : </CharacterRoot/Wardrobe>
    }
)

def "CharacterRoot" (
    references = @character.usd@
)
{
}

Result: The Clothing prim and its children (Shirt, Pants) appear under the path /CharacterRoot/Wardrobe instead of /CharacterRoot/Clothing.

Complex Reparenting Example

Source asset with deep hierarchy:

#usda 1.0

def "Environment" 
{
    def "Terrain"
    {
        def "Ground" { }
    }
    
    def "Props"
    {
        def "Trees" 
        {
            def "Oak" { }
            def "Pine" { }
        }
    }
}

Assembly with relocates:

#usda 1.0
(
    relocates = {
        </Scene/Environment/Props/Trees> : </Scene/Landscape/Forest>,
        </Scene/Environment/Terrain> : </Scene/Landscape/Terrain>
    }
)

def "Scene" (
    references = @environment.usd@</Environment>
)
{
    def "Landscape" # New organizational structure
    {
        # Trees and Terrain will be relocated here
    }
}

Result:

  • Trees appear at /Scene/Landscape/Forest with children Oak and Pine
  • Terrain appears at /Scene/Landscape/Terrain with child Ground
  • Original /Scene/Props namespace is effectively removed

Multi-Asset Relocates

Multiple assets with conflicting namespaces:

#usda 1.0
(
    relocates = {
        </Set/AssetA/Geometry> : </Set/ModelA/Geo>,
        </Set/AssetB/Geometry> : </Set/ModelB/Geo>
    }
)

def "Set"
{
    def "AssetA" (
        references = @assetA.usd@
    ) { }
    
    def "AssetB" (
        references = @assetB.usd@ 
    ) { }
}

This allows both assets to have Geometry children without namespace conflicts, relocating them to distinct target locations.

Performance Considerations

Composition Cost

Relocates add computational overhead during composition:

  • Additional namespace mapping calculations
  • Path translation for all affected descendant prims
  • Potential cache invalidation when relocates change

Optimization Strategies

  1. Minimize Depth: Prefer relocating higher-level prims rather than many individual children
  2. Batch Operations: Group related relocates in the same layer when possible
  3. Stable Mappings: Avoid frequently changing relocates to maintain composition cache effectiveness

Interaction with Other Composition Arcs

Relocates and References

Relocates can be applied to referenced content, allowing non-destructive reorganization of asset namespace without modifying source files. The namespace mapping composes with reference mappings as described above.

Relocates and Variants

Relocates do not affect variant selection paths but can relocate prims that contain variant sets. Variant selections remain valid after relocation.

Relocates and Inheritance

Inherit arcs continue to function normally for relocated prims. Both direct and implied inherit relationships are preserved across relocates transformations.

Relocates and Instancing

Instanceable prims can be relocated. The relocates affects the instance anchor point but does not modify the internal structure of instance prototypes.

Validation Tools

USD validation tools should verify:

  • Relocates path validity and restrictions
  • Consistency with ancestral relocates
  • Absence of source opinion conflicts
  • Proper dictionary syntax and types

This specification ensures relocates provide robust, non-destructive namespace transformation capabilities while maintaining composition consistency and performance characteristics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment