Class: OpenUSD::Stage
- Inherits:
-
Object
- Object
- OpenUSD::Stage
- Defined in:
- lib/openusd/stage.rb
Overview
Composed, editable view of one root layer and its composition arcs.
Instance Attribute Summary collapse
-
#edit_target ⇒ Object
Returns the value of attribute edit_target.
-
#pseudo_root ⇒ Object
readonly
Returns the value of attribute pseudo_root.
-
#resolver ⇒ Object
readonly
Returns the value of attribute resolver.
-
#root_layer ⇒ Object
readonly
Returns the value of attribute root_layer.
Class Method Summary collapse
-
.create(identifier) ⇒ Stage
Create an empty file-backed stage.
-
.create_in_memory ⇒ Stage
Create an anonymous in-memory stage.
-
.open(path, missing_assets: :error) ⇒ Stage
Open a composed stage.
Instance Method Summary collapse
-
#author_attribute(path, name, type_name) ⇒ Object
private
Find or author an attribute spec in the edit target.
-
#author_prim_metadata(path, operation, key, value) ⇒ Object
private
Apply one metadata mutation to an edit-target prim spec.
-
#author_relationship(path, name) ⇒ Object
private
Find or author a relationship spec in the edit target.
-
#child_paths(path) ⇒ Array<Path>
private
Direct composed child paths.
-
#default_prim ⇒ Prim?
Composed default prim.
-
#define_prim(path, type_name = nil) ⇒ Prim
Define a prim and any missing ancestors in the edit target.
-
#export(path) ⇒ Stage
Export the root layer by destination extension.
-
#initialize(root_layer, resolver: AssetResolver.new) ⇒ Stage
constructor
A new instance of Stage.
-
#invalidate! ⇒ Object
private
Invalidate the cached composition index after an edit.
-
#layer_stack ⇒ Array<Layer>
Layers participating in composition.
-
#opinions_for(path) ⇒ Array<PrimSpec>
private
Strongest-to-weakest opinions.
-
#prim_at(path) ⇒ Prim, ...
Find an active composed prim.
-
#remove_prim(path) ⇒ Stage
Remove or deactivate a prim in the edit target.
-
#root_paths ⇒ Array<Path>
private
Composed root paths.
-
#save ⇒ Stage
Save the root layer to its identifier.
-
#set_prim_type(path, type_name) ⇒ Object
private
Author a prim type in the edit target.
-
#set_variant_selection(path, set_name, choice) ⇒ Stage
Author a variant choice for a prim.
-
#traverse ⇒ Enumerator, Stage
Traverse active prims depth-first.
Constructor Details
#initialize(root_layer, resolver: AssetResolver.new) ⇒ Stage
Returns a new instance of Stage.
30 31 32 33 34 35 36 37 38 |
# File 'lib/openusd/stage.rb', line 30 def initialize(root_layer, resolver: AssetResolver.new) @root_layer = root_layer @resolver = resolver @edit_target = root_layer @pseudo_root = PseudoRoot.new(self) @composition = nil @index = nil @layer_cache = {} end |
Instance Attribute Details
#edit_target ⇒ Object
Returns the value of attribute edit_target.
6 7 8 |
# File 'lib/openusd/stage.rb', line 6 def edit_target @edit_target end |
#pseudo_root ⇒ Object (readonly)
Returns the value of attribute pseudo_root.
6 7 8 |
# File 'lib/openusd/stage.rb', line 6 def pseudo_root @pseudo_root end |
#resolver ⇒ Object (readonly)
Returns the value of attribute resolver.
6 7 8 |
# File 'lib/openusd/stage.rb', line 6 def resolver @resolver end |
#root_layer ⇒ Object (readonly)
Returns the value of attribute root_layer.
6 7 8 |
# File 'lib/openusd/stage.rb', line 6 def root_layer @root_layer end |
Class Method Details
.create(identifier) ⇒ Stage
Create an empty file-backed stage.
19 20 21 |
# File 'lib/openusd/stage.rb', line 19 def create(identifier) new(Layer.create(identifier)) end |
.create_in_memory ⇒ Stage
Create an anonymous in-memory stage.
25 26 27 |
# File 'lib/openusd/stage.rb', line 25 def create_in_memory new(Layer.create("anonymous:#{object_id}:#{Process.clock_gettime(Process::CLOCK_MONOTONIC)}")) end |
.open(path, missing_assets: :error) ⇒ Stage
Open a composed stage.
11 12 13 14 15 |
# File 'lib/openusd/stage.rb', line 11 def open(path, missing_assets: :error) = File.(path) resolver = AssetResolver.new(missing_assets: missing_assets) new(Layer.open(), resolver: resolver) end |
Instance Method Details
#author_attribute(path, name, type_name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Find or author an attribute spec in the edit target.
159 160 161 162 163 164 165 166 167 |
# File 'lib/openusd/stage.rb', line 159 def (path, name, type_name) spec = ensure_spec(edit_target, Path.parse(path)) property = spec.property_named(name) validate_property_kind!(property, AttributeSpec, "#{name} is authored as a relationship") property ||= spec.add_property(AttributeSpec.new(name, type_name || "token")) property.type_name = type_name if type_name invalidate! property end |
#author_prim_metadata(path, operation, key, value) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Apply one metadata mutation to an edit-target prim spec.
191 192 193 194 195 |
# File 'lib/openusd/stage.rb', line 191 def (path, operation, key, value) = ensure_spec(edit_target, Path.parse(path)). operation == :set ? [key] = value : .delete(key) invalidate! end |
#author_relationship(path, name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Find or author a relationship spec in the edit target.
171 172 173 174 175 176 177 178 |
# File 'lib/openusd/stage.rb', line 171 def (path, name) spec = ensure_spec(edit_target, Path.parse(path)) property = spec.property_named(name) validate_property_kind!(property, RelationshipSpec, "#{name} is authored as an attribute") property ||= spec.add_property(RelationshipSpec.new(name)) invalidate! property end |
#child_paths(path) ⇒ Array<Path>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns direct composed child paths.
143 144 145 146 147 148 149 |
# File 'lib/openusd/stage.rb', line 143 def child_paths(path) prefix = "#{Path.parse(path)}/" paths = composed_index.keys.select do |candidate| candidate.start_with?(prefix) && !candidate.delete_prefix(prefix).include?("/") end paths.sort.map { |candidate| Path.parse(candidate) } end |
#default_prim ⇒ Prim?
Returns composed default prim.
60 61 62 63 |
# File 'lib/openusd/stage.rb', line 60 def default_prim name = root_layer.["defaultPrim"] prim_at("/#{name}") if name end |
#define_prim(path, type_name = nil) ⇒ Prim
Define a prim and any missing ancestors in the edit target.
67 68 69 70 71 72 73 74 |
# File 'lib/openusd/stage.rb', line 67 def define_prim(path, type_name = nil) parsed = validate_prim_path(path) spec = ensure_spec(edit_target, parsed) spec.specifier = :def spec.type_name = type_name.to_s if type_name invalidate! Prim.new(self, parsed) end |
#export(path) ⇒ Stage
Export the root layer by destination extension.
113 114 115 116 |
# File 'lib/openusd/stage.rb', line 113 def export(path) root_layer.export(path) self end |
#invalidate! ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Invalidate the cached composition index after an edit.
205 206 207 208 209 |
# File 'lib/openusd/stage.rb', line 205 def invalidate! @index = nil @composition = nil self end |
#layer_stack ⇒ Array<Layer>
Returns layers participating in composition.
198 199 200 201 |
# File 'lib/openusd/stage.rb', line 198 def layer_stack composed_index @composition.layers end |
#opinions_for(path) ⇒ Array<PrimSpec>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns strongest-to-weakest opinions.
137 138 139 |
# File 'lib/openusd/stage.rb', line 137 def opinions_for(path) composed_index.fetch(Path.parse(path).to_s, []) end |
#prim_at(path) ⇒ Prim, ...
Find an active composed prim.
49 50 51 52 53 54 55 56 57 |
# File 'lib/openusd/stage.rb', line 49 def prim_at(path) parsed = Path.parse(path) return pseudo_root if parsed.to_s == "/" return nil if parsed.property? return nil unless composed_index.key?(parsed.to_s) prim = Prim.new(self, parsed) prim.active? ? prim : nil end |
#remove_prim(path) ⇒ Stage
Remove or deactivate a prim in the edit target.
78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/openusd/stage.rb', line 78 def remove_prim(path) parsed = validate_prim_path(path) remove_spec(edit_target, parsed) invalidate! if composed_index.key?(parsed.to_s) blocker = ensure_spec(edit_target, parsed) blocker.specifier = :over blocker.["active"] = false end invalidate! self end |
#root_paths ⇒ Array<Path>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns composed root paths.
153 154 155 |
# File 'lib/openusd/stage.rb', line 153 def root_paths composed_index.keys.select { |path| path.count("/") == 1 }.sort.map { |path| Path.parse(path) } end |
#save ⇒ Stage
Save the root layer to its identifier.
106 107 108 109 |
# File 'lib/openusd/stage.rb', line 106 def save root_layer.save self end |
#set_prim_type(path, type_name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Author a prim type in the edit target.
182 183 184 185 186 187 |
# File 'lib/openusd/stage.rb', line 182 def set_prim_type(path, type_name) spec = ensure_spec(edit_target, Path.parse(path)) spec.type_name = type_name&.to_s invalidate! type_name end |
#set_variant_selection(path, set_name, choice) ⇒ Stage
Author a variant choice for a prim.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/openusd/stage.rb', line 120 def set_variant_selection(path, set_name, choice) prim = prim_at(path) raise CompositionError, "prim not found: #{path}" unless prim choices = prim.variant_sets[set_name.to_s] raise CompositionError, "variant set not found: #{set_name}" unless choices raise CompositionError, "variant not found: #{choice}" unless choices.key?(choice.to_s) spec = ensure_spec(edit_target, Path.parse(path)) spec.["variants"] ||= {} spec.["variants"][set_name.to_s] = choice.to_s invalidate! self end |
#traverse ⇒ Enumerator, Stage
Traverse active prims depth-first.
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/openusd/stage.rb', line 93 def traverse return enum_for(__method__) unless block_given? walk = lambda do |prim| yield prim prim.children.each { |child| walk.call(child) } end pseudo_root.children.each { |prim| walk.call(prim) } self end |