ovui-data-adapters-common 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,338 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: LicenseRef-NvidiaProprietary
3
+ #
4
+ # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
5
+ # property and proprietary rights in and to this material, related
6
+ # documentation and any modifications thereto. Any use, reproduction,
7
+ # disclosure or distribution of this material and related documentation
8
+ # without an express license agreement from NVIDIA CORPORATION or
9
+ # its affiliates is strictly prohibited.
10
+
11
+ """Provider-neutral UI data-adapter interfaces and shared helpers."""
12
+
13
+ from ovui_data_adapters.common._adapter_registry import (
14
+ ADAPTER_ENTRY_POINT_GROUP,
15
+ AdapterFactories,
16
+ AdapterModuleLoadFailure,
17
+ AdapterProvider,
18
+ AdapterProviderNotFoundError,
19
+ AdapterProviderSelectionError,
20
+ AdapterRegistry,
21
+ AdapterRegistryError,
22
+ DuplicateAdapterProviderError,
23
+ discover_adapter_modules,
24
+ get_adapter_factories,
25
+ select_adapter,
26
+ )
27
+ from ovui_data_adapters.common._bound_camera_pose import BoundCameraPose
28
+ from ovui_data_adapters.common._command import Command, CommandCancelled
29
+ from ovui_data_adapters.common._environment import omniui_headless_enabled
30
+ from ovui_data_adapters.common._gpu_frame import (
31
+ _STANDALONE_NOOP_MARKER,
32
+ GpuFrame,
33
+ ZeroCopyState,
34
+ _Mode,
35
+ )
36
+ from ovui_data_adapters.common._subscription import SubscriptionProtocol
37
+ from ovui_data_adapters.common._undo_manager import UndoManagerProtocol
38
+ from ovui_data_adapters.common.create_actions import (
39
+ CREATE_ACTION_CATEGORY_ORDER,
40
+ CreateActionCatalog,
41
+ CreateActionCategory,
42
+ CreateActionCategoryDescriptor,
43
+ CreateActionDescriptor,
44
+ CreateActionErrorCode,
45
+ CreateActionRequirement,
46
+ CreateActionWarning,
47
+ CreateActionWarningSeverity,
48
+ CreateActionsAdapter,
49
+ CreateBindingPolicy,
50
+ CreatePlacementPolicy,
51
+ CreateRequest,
52
+ CreateResult,
53
+ CreateSelectionPolicy,
54
+ )
55
+ from ovui_data_adapters.common.core_materials import (
56
+ BindMaterialRequest,
57
+ BindMaterialResult,
58
+ CoreMaterialBindingPolicy,
59
+ CoreMaterialCatalog,
60
+ CoreMaterialDescriptor,
61
+ CoreMaterialErrorCode,
62
+ CoreMaterialFamily,
63
+ CoreMaterialGroupDescriptor,
64
+ CoreMaterialKind,
65
+ CoreMaterialRequirement,
66
+ CoreMaterialWarning,
67
+ CoreMaterialWarningSeverity,
68
+ CoreMaterialsAdapter,
69
+ CreateAndBindMaterialResult,
70
+ CreateMaterialRequest,
71
+ CreateMaterialResult,
72
+ )
73
+ from ovui_data_adapters.common.render_targets import (
74
+ RenderTargetActivationResult,
75
+ RenderTargetCatalog,
76
+ RenderTargetDescriptor,
77
+ RenderTargetKind,
78
+ RenderTargetOutputKind,
79
+ RenderTargetWarning,
80
+ RenderTargetWarningSeverity,
81
+ )
82
+ from ovui_data_adapters.common.render_vars import (
83
+ RenderVarCategoricalSettings,
84
+ RenderVarHdrSettings,
85
+ RenderVarOutputCatalog,
86
+ RenderVarOutputDescriptor,
87
+ RenderVarOutputFrame,
88
+ RenderVarOutputKind,
89
+ RenderVarOutputRequest,
90
+ RenderVarOutputRequestResult,
91
+ RenderVarPresetKind,
92
+ RenderVarProbeRequest,
93
+ RenderVarProbeResult,
94
+ RenderVarScalarRangeSettings,
95
+ RenderVarToneMap,
96
+ RenderVarVectorSettings,
97
+ RenderVarVisualizationPreset,
98
+ RenderVarWarning,
99
+ RenderVarWarningSeverity,
100
+ )
101
+ from ovui_data_adapters.common.render_settings import (
102
+ RenderSettingApplyResult,
103
+ RenderSettingDescriptor,
104
+ RenderSettingRequirement,
105
+ RenderSettingResetResult,
106
+ RenderSettingValidationResult,
107
+ RenderSettingValueConstraints,
108
+ RenderSettingValueState,
109
+ RenderSettingValueType,
110
+ RenderSettingVisibility,
111
+ RenderSettingWarning,
112
+ RenderSettingWarningSeverity,
113
+ RenderSettingsAdapter,
114
+ RenderSettingsCatalog,
115
+ RenderSettingsGroupDescriptor,
116
+ RenderSettingsProviderDescriptor,
117
+ )
118
+ from ovui_data_adapters.common.viewport_state import (
119
+ ViewportCameraState,
120
+ ViewportStateAdapter,
121
+ ViewportStateSnapshot,
122
+ ViewportStreamState,
123
+ )
124
+ from ovui_data_adapters.common.point_cloud import (
125
+ PointCloudChannelDescriptor,
126
+ PointCloudChannelSemantic,
127
+ PointCloudColorMode,
128
+ PointCloudCoordinateSpace,
129
+ PointCloudFrame,
130
+ PointCloudOutputCatalog,
131
+ PointCloudOutputDescriptor,
132
+ PointCloudRequest,
133
+ PointCloudRequestResult,
134
+ PointCloudWarning,
135
+ PointCloudWarningSeverity,
136
+ )
137
+ from ovui_data_adapters.common.adapters import (
138
+ _DEFAULT_TYPE_CATEGORY_MAP,
139
+ AABB,
140
+ AdapterCapabilities,
141
+ AdapterCapability,
142
+ AdapterCapabilityStatus,
143
+ AdapterItem,
144
+ AttributeMetadata,
145
+ BadgeFlags,
146
+ BoundingBox,
147
+ ChangeEvent,
148
+ ChangeEventType,
149
+ ContextManager,
150
+ GpuFrameHandle,
151
+ ImageProvider,
152
+ ItemFlags,
153
+ LayerEvent,
154
+ LayerEventType,
155
+ LayerHandle,
156
+ LayerSnapshot,
157
+ LayerStackCapabilities,
158
+ LayerStackAdapter,
159
+ Matrix4d,
160
+ PrimSpecDescriptor,
161
+ PrimSpecifier,
162
+ PropertyCapabilities,
163
+ PropertyAdapter,
164
+ RendererAdapter,
165
+ ReparentPosition,
166
+ SelectionAdapter,
167
+ StageAdapter,
168
+ StageCapabilities,
169
+ StageChoice,
170
+ TransformEditMode,
171
+ TransformEditPolicy,
172
+ TransformAdapter,
173
+ UnresolvedDeliveryDebtError,
174
+ VIEWPORT_CAMERA_POSE_SOURCE,
175
+ Vec3f,
176
+ VisibilityState,
177
+ is_camera_property_only_info_change,
178
+ is_viewport_camera_pose_change_event,
179
+ )
180
+
181
+ __all__ = [
182
+ # adapter registry
183
+ "ADAPTER_ENTRY_POINT_GROUP",
184
+ "AdapterFactories",
185
+ "AdapterModuleLoadFailure",
186
+ "AdapterProvider",
187
+ "AdapterProviderNotFoundError",
188
+ "AdapterProviderSelectionError",
189
+ "AdapterRegistry",
190
+ "AdapterRegistryError",
191
+ "DuplicateAdapterProviderError",
192
+ "discover_adapter_modules",
193
+ "get_adapter_factories",
194
+ "select_adapter",
195
+ "omniui_headless_enabled",
196
+ # adapter ABCs
197
+ "LayerStackAdapter",
198
+ "PropertyAdapter",
199
+ "RendererAdapter",
200
+ "CreateActionsAdapter",
201
+ "CoreMaterialsAdapter",
202
+ "RenderSettingsAdapter",
203
+ "SelectionAdapter",
204
+ "StageAdapter",
205
+ "TransformAdapter",
206
+ "ViewportStateAdapter",
207
+ # enums / flags
208
+ "AdapterCapabilityStatus",
209
+ "BadgeFlags",
210
+ "ChangeEventType",
211
+ "CreateActionCategory",
212
+ "CreateActionErrorCode",
213
+ "CreateActionRequirement",
214
+ "CreateActionWarningSeverity",
215
+ "CreateBindingPolicy",
216
+ "CreatePlacementPolicy",
217
+ "CreateSelectionPolicy",
218
+ "CoreMaterialBindingPolicy",
219
+ "CoreMaterialErrorCode",
220
+ "CoreMaterialFamily",
221
+ "CoreMaterialKind",
222
+ "CoreMaterialRequirement",
223
+ "CoreMaterialWarningSeverity",
224
+ "ItemFlags",
225
+ "LayerEventType",
226
+ "PrimSpecifier",
227
+ "ReparentPosition",
228
+ "PointCloudChannelSemantic",
229
+ "PointCloudColorMode",
230
+ "PointCloudCoordinateSpace",
231
+ "PointCloudWarningSeverity",
232
+ "RenderTargetKind",
233
+ "RenderTargetOutputKind",
234
+ "RenderTargetWarningSeverity",
235
+ "RenderVarOutputKind",
236
+ "RenderVarPresetKind",
237
+ "RenderVarToneMap",
238
+ "RenderVarWarningSeverity",
239
+ "RenderSettingRequirement",
240
+ "RenderSettingValueType",
241
+ "RenderSettingVisibility",
242
+ "RenderSettingWarningSeverity",
243
+ "TransformEditMode",
244
+ "VisibilityState",
245
+ # dataclasses
246
+ "AdapterCapabilities",
247
+ "AdapterCapability",
248
+ "AttributeMetadata",
249
+ "BoundCameraPose",
250
+ "ChangeEvent",
251
+ "CreateActionCatalog",
252
+ "CreateActionCategoryDescriptor",
253
+ "CreateActionDescriptor",
254
+ "CreateActionWarning",
255
+ "CreateRequest",
256
+ "CreateResult",
257
+ "BindMaterialRequest",
258
+ "BindMaterialResult",
259
+ "CoreMaterialCatalog",
260
+ "CoreMaterialDescriptor",
261
+ "CoreMaterialGroupDescriptor",
262
+ "CoreMaterialWarning",
263
+ "CreateAndBindMaterialResult",
264
+ "CreateMaterialRequest",
265
+ "CreateMaterialResult",
266
+ "LayerEvent",
267
+ "LayerHandle",
268
+ "LayerSnapshot",
269
+ "LayerStackCapabilities",
270
+ "PointCloudChannelDescriptor",
271
+ "PointCloudFrame",
272
+ "PointCloudOutputCatalog",
273
+ "PointCloudOutputDescriptor",
274
+ "PointCloudRequest",
275
+ "PointCloudRequestResult",
276
+ "PointCloudWarning",
277
+ "PrimSpecDescriptor",
278
+ "RenderTargetActivationResult",
279
+ "RenderTargetCatalog",
280
+ "RenderTargetDescriptor",
281
+ "RenderTargetWarning",
282
+ "RenderVarCategoricalSettings",
283
+ "RenderVarHdrSettings",
284
+ "RenderVarOutputCatalog",
285
+ "RenderVarOutputDescriptor",
286
+ "RenderVarOutputFrame",
287
+ "RenderVarOutputRequest",
288
+ "RenderVarOutputRequestResult",
289
+ "RenderVarProbeRequest",
290
+ "RenderVarProbeResult",
291
+ "RenderVarScalarRangeSettings",
292
+ "RenderVarVectorSettings",
293
+ "RenderVarVisualizationPreset",
294
+ "RenderVarWarning",
295
+ "RenderSettingApplyResult",
296
+ "RenderSettingDescriptor",
297
+ "RenderSettingResetResult",
298
+ "RenderSettingValidationResult",
299
+ "RenderSettingValueConstraints",
300
+ "RenderSettingValueState",
301
+ "RenderSettingWarning",
302
+ "RenderSettingsCatalog",
303
+ "RenderSettingsGroupDescriptor",
304
+ "RenderSettingsProviderDescriptor",
305
+ "PropertyCapabilities",
306
+ "StageCapabilities",
307
+ "StageChoice",
308
+ "TransformEditPolicy",
309
+ "ViewportCameraState",
310
+ "ViewportStateSnapshot",
311
+ "ViewportStreamState",
312
+ "VIEWPORT_CAMERA_POSE_SOURCE",
313
+ "CREATE_ACTION_CATEGORY_ORDER",
314
+ # opaque type aliases
315
+ "AABB",
316
+ "AdapterItem",
317
+ "BoundingBox",
318
+ "ContextManager",
319
+ "GpuFrameHandle",
320
+ "ImageProvider",
321
+ "Matrix4d",
322
+ "Vec3f",
323
+ # protocols and command surface (Steps 2/3)
324
+ "Command",
325
+ "CommandCancelled",
326
+ "SubscriptionProtocol",
327
+ "UnresolvedDeliveryDebtError",
328
+ "UndoManagerProtocol",
329
+ # zero-copy / GPU frame surface (Step 4)
330
+ "GpuFrame",
331
+ "ZeroCopyState",
332
+ "_Mode",
333
+ "_STANDALONE_NOOP_MARKER",
334
+ "is_camera_property_only_info_change",
335
+ "is_viewport_camera_pose_change_event",
336
+ # private lookup table — explicit so dotted access continues to work
337
+ "_DEFAULT_TYPE_CATEGORY_MAP",
338
+ ]
@@ -0,0 +1,253 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: LicenseRef-NvidiaProprietary
3
+ #
4
+ # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
5
+ # property and proprietary rights in and to this material, related
6
+ # documentation and any modifications thereto. Any use, reproduction,
7
+ # disclosure or distribution of this material and related documentation
8
+ # without an express license agreement from NVIDIA CORPORATION or
9
+ # its affiliates is strictly prohibited.
10
+
11
+ """Entry-point registry for data-adapter providers."""
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+ from importlib.metadata import entry_points
17
+ import traceback
18
+ from typing import Any, Callable, Iterable
19
+
20
+
21
+ ADAPTER_ENTRY_POINT_GROUP = "ovui_data_adapters.adapters"
22
+ AdapterFactory = Callable[..., Any]
23
+
24
+
25
+ class AdapterRegistryError(Exception):
26
+ """Base exception raised by the common adapter registry."""
27
+
28
+
29
+ class DuplicateAdapterProviderError(AdapterRegistryError):
30
+ """Raised when two providers use the same registry name."""
31
+
32
+
33
+ class AdapterProviderNotFoundError(AdapterRegistryError):
34
+ """Raised when an explicitly requested provider is unavailable."""
35
+
36
+
37
+ class AdapterProviderSelectionError(AdapterRegistryError):
38
+ """Raised when no adapter provider can be selected."""
39
+
40
+
41
+ @dataclass(frozen=True)
42
+ class AdapterFactories:
43
+ """Factory callables exposed by one registered provider."""
44
+
45
+ stage: AdapterFactory | None = None
46
+ properties: AdapterFactory | None = None
47
+ transforms: AdapterFactory | None = None
48
+ renderer: AdapterFactory | None = None
49
+ selection: AdapterFactory | None = None
50
+ layers: AdapterFactory | None = None
51
+ session: AdapterFactory | None = None
52
+
53
+
54
+ @dataclass(frozen=True)
55
+ class AdapterProvider:
56
+ """Provider metadata and factories registered through common."""
57
+
58
+ name: str
59
+ priority: int
60
+ requirements: tuple[str, ...]
61
+ factories: AdapterFactories
62
+
63
+
64
+ @dataclass(frozen=True)
65
+ class AdapterModuleLoadFailure:
66
+ """Structured diagnostic for one failed adapter entry point."""
67
+
68
+ name: str
69
+ value: str
70
+ exception_type: str
71
+ message: str
72
+ traceback_summary: tuple[str, ...]
73
+ module_name: str = ""
74
+ entry_point_value: str = ""
75
+ requirement_name: str | None = None
76
+ exception_text: str = ""
77
+
78
+ @classmethod
79
+ def from_exception(
80
+ cls,
81
+ name: str,
82
+ value: str,
83
+ exc: BaseException,
84
+ ) -> "AdapterModuleLoadFailure":
85
+ module_name = str(getattr(exc, "module_name", name))
86
+ entry_point_value = str(getattr(exc, "entry_point_value", value))
87
+ requirement_name = getattr(exc, "requirement_name", None)
88
+ exception_text = str(getattr(exc, "exception_text", str(exc)))
89
+ return cls(
90
+ name=name,
91
+ value=value,
92
+ exception_type=type(exc).__name__,
93
+ message=str(exc),
94
+ traceback_summary=tuple(
95
+ line.rstrip()
96
+ for line in traceback.format_exception(type(exc), exc, exc.__traceback__)
97
+ ),
98
+ module_name=module_name,
99
+ entry_point_value=entry_point_value,
100
+ requirement_name=requirement_name,
101
+ exception_text=exception_text,
102
+ )
103
+
104
+
105
+ class AdapterRegistry:
106
+ """Collect and select data-adapter providers discovered by common."""
107
+
108
+ def __init__(self) -> None:
109
+ self._providers: dict[str, AdapterProvider] = {}
110
+ self._load_failures: list[AdapterModuleLoadFailure] = []
111
+ self._active_provider_name: str | None = None
112
+
113
+ @property
114
+ def load_failures(self) -> tuple[AdapterModuleLoadFailure, ...]:
115
+ return tuple(self._load_failures)
116
+
117
+ @property
118
+ def module_load_failures(self) -> tuple[AdapterModuleLoadFailure, ...]:
119
+ return self.load_failures
120
+
121
+ @property
122
+ def active_provider(self) -> AdapterProvider | None:
123
+ if self._active_provider_name is None:
124
+ return None
125
+ return self._providers.get(self._active_provider_name)
126
+
127
+ def available_adapters(self) -> tuple[AdapterProvider, ...]:
128
+ return tuple(
129
+ self._providers[name]
130
+ for name in sorted(self._providers)
131
+ )
132
+
133
+ def register_adapter(
134
+ self,
135
+ *,
136
+ name: str,
137
+ priority: int = 0,
138
+ requirements: Iterable[str] = (),
139
+ factories: AdapterFactories,
140
+ ) -> AdapterProvider:
141
+ provider_name = self._normalize_provider_name(name)
142
+ if provider_name in self._providers:
143
+ raise DuplicateAdapterProviderError(
144
+ f"adapter provider already registered: {provider_name}"
145
+ )
146
+ if not isinstance(priority, int):
147
+ raise TypeError("priority must be an int")
148
+ if not isinstance(factories, AdapterFactories):
149
+ raise TypeError("factories must be an AdapterFactories instance")
150
+
151
+ provider = AdapterProvider(
152
+ name=provider_name,
153
+ priority=priority,
154
+ requirements=tuple(requirements),
155
+ factories=factories,
156
+ )
157
+ self._providers[provider_name] = provider
158
+ return provider
159
+
160
+ def require_adapter(self, name: str) -> AdapterProvider:
161
+ provider_name = self._normalize_provider_name(name)
162
+ try:
163
+ return self._providers[provider_name]
164
+ except KeyError as exc:
165
+ for failure in self._load_failures:
166
+ if self._normalize_provider_name(failure.name) == provider_name:
167
+ raise AdapterProviderNotFoundError(failure.message) from exc
168
+ available = ", ".join(sorted(self._providers)) or "none"
169
+ raise AdapterProviderNotFoundError(
170
+ f"adapter provider not found: {provider_name}; available: {available}"
171
+ ) from exc
172
+
173
+ def report_module_load_failure(
174
+ self,
175
+ name: str,
176
+ value: str,
177
+ exc: BaseException,
178
+ ) -> AdapterModuleLoadFailure:
179
+ failure = AdapterModuleLoadFailure.from_exception(name, value, exc)
180
+ self._load_failures.append(failure)
181
+ return failure
182
+
183
+ def select_adapter(self, requested_name: str | None = None) -> AdapterProvider:
184
+ if requested_name:
185
+ provider = self.require_adapter(requested_name)
186
+ else:
187
+ providers = self.available_adapters()
188
+ if not providers:
189
+ raise AdapterProviderSelectionError(
190
+ "no adapter providers are registered"
191
+ )
192
+ if len(providers) == 1:
193
+ provider = providers[0]
194
+ else:
195
+ provider = sorted(
196
+ providers,
197
+ key=lambda item: (-item.priority, item.name),
198
+ )[0]
199
+ self._active_provider_name = provider.name
200
+ return provider
201
+
202
+ def get_adapter_factories(
203
+ self,
204
+ requested_name: str | None = None,
205
+ ) -> AdapterFactories:
206
+ return self.select_adapter(requested_name).factories
207
+
208
+ @staticmethod
209
+ def _normalize_provider_name(name: str) -> str:
210
+ provider_name = str(name).strip()
211
+ if not provider_name:
212
+ raise ValueError("adapter provider name must not be empty")
213
+ return provider_name
214
+
215
+
216
+ def discover_adapter_modules(
217
+ registry: AdapterRegistry | None = None,
218
+ requested_name: str | None = None,
219
+ ) -> AdapterRegistry:
220
+ target_registry = registry if registry is not None else AdapterRegistry()
221
+ requested = str(requested_name or "").strip()
222
+ for entry_point in entry_points(group=ADAPTER_ENTRY_POINT_GROUP):
223
+ if requested and str(entry_point.name).strip() != requested:
224
+ continue
225
+ try:
226
+ register = entry_point.load()
227
+ register(target_registry)
228
+ except Exception as exc:
229
+ target_registry.report_module_load_failure(
230
+ entry_point.name,
231
+ entry_point.value,
232
+ exc,
233
+ )
234
+ return target_registry
235
+
236
+
237
+ def select_adapter(
238
+ registry: AdapterRegistry,
239
+ requested_name: str | None = None,
240
+ ) -> AdapterProvider:
241
+ return registry.select_adapter(requested_name)
242
+
243
+
244
+ def get_adapter_factories(
245
+ registry: AdapterRegistry | None = None,
246
+ requested_name: str | None = None,
247
+ ) -> AdapterFactories:
248
+ target_registry = (
249
+ discover_adapter_modules(requested_name=requested_name)
250
+ if registry is None
251
+ else registry
252
+ )
253
+ return target_registry.get_adapter_factories(requested_name)
@@ -0,0 +1,35 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: LicenseRef-NvidiaProprietary
3
+ #
4
+ # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
5
+ # property and proprietary rights in and to this material, related
6
+ # documentation and any modifications thereto. Any use, reproduction,
7
+ # disclosure or distribution of this material and related documentation
8
+ # without an express license agreement from NVIDIA CORPORATION or
9
+ # its affiliates is strictly prohibited.
10
+
11
+ """Data-only ``BoundCameraPose`` dataclass.
12
+
13
+ Part of ``ovui-data-adapters-common``; this module is stdlib-only at runtime.
14
+
15
+ Carries the world-space pose for a stage's authored ``boundCamera``.
16
+ The USD/pxr parser that produces this value (``read_bound_camera``)
17
+ lives in ``ovui_widgets.viewport.usd_camera`` because it depends on
18
+ ``pxr``; only the result type lives here so that future
19
+ ``ovui_data_adapters.openusd`` consumers can return it without
20
+ forcing a widget back-edge.
21
+ """
22
+
23
+ from dataclasses import dataclass
24
+ from typing import Tuple
25
+
26
+
27
+ @dataclass
28
+ class BoundCameraPose:
29
+ """World-space pose for the stage's ``boundCamera``."""
30
+
31
+ eye: Tuple[float, float, float]
32
+ target: Tuple[float, float, float]
33
+ up_axis: str # "Y" or "Z"
34
+ fov_degrees: float
35
+ prim_path: str