mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
9.3 KiB
9.3 KiB
PrimSpec JavaScript Functions Demo
This demonstrates the new JavaScript functions that have been added to the TinyUSDZ JavaScript scripting interface for working with PrimSpecs:
findPrimSpecByPath()- Search for PrimSpec by absolute pathgetPrimSpecMetadata()- Get PrimSpec metadata by absolute path
Function Overview
1. findPrimSpecByPath(pathString)
Searches for and retrieves basic PrimSpec information by absolute path string.
Function Signature:
findPrimSpecByPath(pathString) -> PrimSpec object | null
- Parameters:
pathString(string): Absolute USD path string (e.g., "/root/child/prim")
- Returns:
- PrimSpec object if found
nullif not found or invalid path
2. getPrimSpecMetadata(pathString)
Retrieves detailed metadata information for a PrimSpec by absolute path string.
Function Signature:
getPrimSpecMetadata(pathString) -> Metadata object | null
- Parameters:
pathString(string): Absolute USD path string (e.g., "/root/child/prim")
- Returns:
- Metadata object if found
nullif not found or invalid path
PrimSpec Object Structure
When found, the function returns a JSON object with the following structure:
{
"name": "primName", // Name of the PrimSpec
"typeName": "Mesh", // Type name (e.g., "Mesh", "Xform", etc.)
"specifier": "def", // Specifier: "def", "over", "class", or "invalid"
"propertyCount": 5, // Number of properties
"childrenCount": 2, // Number of child PrimSpecs
"propertyNames": [ // Array of property names
"points",
"faceVertexIndices",
"extent"
],
"childrenNames": [ // Array of child PrimSpec names
"material",
"childPrim"
]
}
Metadata Object Structure
When found, the getPrimSpecMetadata() function returns a JSON object with the following structure:
{
"active": true, // Active state (true/false/null)
"hidden": false, // Hidden state (true/false/null)
"instanceable": null, // Instanceable state (true/false/null)
"kind": "component", // USD Kind (string)
"documentation": "This is a mesh", // Documentation (string/null)
"comment": "Auto-generated", // Comment (string/null)
"displayName": "My Mesh", // Display name (string/null)
"sceneName": "Scene1", // Scene name (string/null)
"hasReferences": true, // Whether prim has references
"referencesCount": 2, // Number of references
"hasPayload": false, // Whether prim has payload
"payloadCount": 0, // Number of payloads
"hasInherits": false, // Whether prim has inherits
"inheritsCount": 0, // Number of inherits
"hasVariants": true, // Whether prim has variants
"variantsCount": 2, // Number of variant selections
"variantNames": ["modelingVariant", "shadingVariant"], // Variant names
"hasVariantSets": true, // Whether prim has variant sets
"variantSetsCount": 1, // Number of variant sets
"variantSetNames": ["material"], // Variant set names
"hasCustomData": true, // Whether prim has custom data
"hasAssetInfo": false, // Whether prim has asset info
"unregisteredMetasCount": 3, // Number of unregistered metadata
"unregisteredMetaNames": ["myCustomMeta1", "myCustomMeta2"], // Custom metadata names
"authored": true // Whether metadata is authored
}
Usage Example
// Search for a specific PrimSpec
var rootPrim = findPrimSpecByPath("/Root");
if (rootPrim) {
console.log("Found root prim:", rootPrim.name);
console.log("Type:", rootPrim.typeName);
console.log("Properties:", rootPrim.propertyNames);
console.log("Children:", rootPrim.childrenNames);
} else {
console.log("Root prim not found");
}
// Get metadata for the same PrimSpec
var rootMeta = getPrimSpecMetadata("/Root");
if (rootMeta) {
console.log("Root prim is active:", rootMeta.active);
console.log("Kind:", rootMeta.kind);
console.log("Has references:", rootMeta.hasReferences);
console.log("Variant sets:", rootMeta.variantSetNames);
if (rootMeta.documentation) {
console.log("Documentation:", rootMeta.documentation);
}
if (rootMeta.unregisteredMetasCount > 0) {
console.log("Custom metadata:", rootMeta.unregisteredMetaNames);
}
} else {
console.log("Root prim metadata not found");
}
// Search for a nested PrimSpec and its metadata
var meshPrim = findPrimSpecByPath("/Root/Geometry/Mesh");
var meshMeta = getPrimSpecMetadata("/Root/Geometry/Mesh");
if (meshPrim && meshMeta) {
console.log("Found mesh with", meshPrim.propertyCount, "properties");
console.log("Mesh is instanceable:", meshMeta.instanceable);
console.log("Mesh variants:", meshMeta.variantNames);
} else {
console.log("Mesh or its metadata not found");
}
// Example: Check if a prim has composition arcs
var composedPrimMeta = getPrimSpecMetadata("/ComposedPrim");
if (composedPrimMeta) {
var hasComposition = composedPrimMeta.hasReferences ||
composedPrimMeta.hasPayload ||
composedPrimMeta.hasInherits;
if (hasComposition) {
console.log("Prim has composition arcs:");
if (composedPrimMeta.hasReferences) {
console.log("- References:", composedPrimMeta.referencesCount);
}
if (composedPrimMeta.hasPayload) {
console.log("- Payloads:", composedPrimMeta.payloadCount);
}
if (composedPrimMeta.hasInherits) {
console.log("- Inherits:", composedPrimMeta.inheritsCount);
}
}
}
C++ Integration
To use these functions from C++, you need to:
- Create or load a USD Layer
- Use
RunJSScriptWithLayer()to execute JavaScript code with access to the Layer
#include "src/tydra/js-script.hh"
// Assuming you have a Layer object
tinyusdz::Layer layer;
// ... populate layer with PrimSpecs ...
std::string jsCode = R"(
// Find PrimSpec basic info
var prim = findPrimSpecByPath("/myPrim");
if (prim) {
console.log("Found:", prim.name, "type:", prim.typeName);
console.log("Properties:", prim.propertyCount);
console.log("Children:", prim.childrenCount);
}
// Get detailed metadata
var meta = getPrimSpecMetadata("/myPrim");
if (meta) {
console.log("Active:", meta.active);
console.log("Kind:", meta.kind);
console.log("Has composition:",
meta.hasReferences || meta.hasPayload || meta.hasInherits);
if (meta.hasVariants) {
console.log("Variants:", meta.variantNames);
}
}
)";
std::string err;
bool success = tinyusdz::tydra::RunJSScriptWithLayer(jsCode, &layer, err);
if (!success) {
std::cerr << "JavaScript error: " << err << std::endl;
}
Implementation Details
Both functions are implemented in src/tydra/js-script.cc and include:
Common Features:
- Path validation: Ensures the input string is a valid USD path
- Layer search: Uses the existing
Layer::find_primspec_at()method - Error handling: Returns
nullfor invalid paths or missing PrimSpecs
findPrimSpecByPath():
- JSON conversion: Converts basic PrimSpec data to JSON
- Structure info: Provides name, type, properties, and children info
getPrimSpecMetadata():
- Comprehensive metadata: Extracts all USD metadata fields
- Composition info: Details about references, payloads, inherits
- Variant info: Information about variants and variant sets
- Custom metadata: Handles unregistered metadata fields
- Boolean flags: Convenient flags for common checks
Requirements
- TinyUSDZ must be built with
TINYUSDZ_WITH_QJS=ONto enable QuickJS support - The functions are only available when using
RunJSScriptWithLayer()
Error Cases
Both functions return null in these cases:
- Invalid path string (empty, malformed)
- Path not found in the Layer
- Relative paths (not yet supported)
- No Layer context available
Metadata Fields Reference
The getPrimSpecMetadata() function provides access to the following USD metadata:
Core Metadata:
active- Whether the prim is active in the scenehidden- Whether the prim is hidden from traversalinstanceable- Whether the prim can be instancedkind- USD Kind classification (model, component, assembly, etc.)
Documentation:
documentation- Formal documentation stringcomment- Informal comment stringdisplayName- Human-readable display name (extension)sceneName- Scene name (USDZ extension)
Composition Arcs:
hasReferences/referencesCount- Reference compositionhasPayload/payloadCount- Payload compositionhasInherits/inheritsCount- Inheritance composition
Variants:
hasVariants/variantsCount/variantNames- Variant selectionshasVariantSets/variantSetsCount/variantSetNames- Variant set definitions
Custom Data:
hasCustomData- Whether prim has custom data dictionaryhasAssetInfo- Whether prim has asset info dictionaryunregisteredMetasCount/unregisteredMetaNames- Custom metadata fieldsauthored- Whether any metadata is authored