Skip to content

StorageService

Stores the scene hierarchy as queryable nodes: assemblies, parts, components, metadata, transforms, bounding boxes. Built automatically from loaded models, either by traversal or from a chunked manifest.

Access

Registered under the name "scene-hierarchy". Depends on mesh.

ts
import { StorageService } from "@optellix/xviewr-sdk";

await viewer.ready();
const storage = viewer.getService<StorageService>("scene-hierarchy");

Public API

Nodes

  • storeObject(object: THREE.Object3D, metadata?: Partial<StorageMetadata> & { parentId?, ownerFile?, nodeType? }): Promise<HierarchyNode>
  • getNode(id: string): HierarchyNode | null
  • removeNode(id: string): Promise<boolean>
  • updateNode(id: string, updates: Partial<HierarchyNode>): Promise<HierarchyNode>
  • queryNodes(options: QueryOptions): HierarchyNode[]

Hierarchy

  • buildHierarchyFromScene(scene: THREE.Object3D): Promise<HierarchyNode[]> — analyzes the scene and creates nodes.
  • buildHierarchyFromManifest(root: THREE.Object3D, fileSpec: FileSpec, hierarchy: { nodes? }): Promise<HierarchyNode[]> — for chunked manifest loads.
  • exportHierarchy(format: "json" | "xml" | "csv"): string
  • importHierarchy(data: string, format: "json" | "xml"): Promise<void>
  • clear(): Promise<void>
  • getStats(): { totalNodes, nodesByType, totalRelationships, memoryUsage }

Managers (read-only properties)

  • hierarchyManager — direct access to the node store.
  • datasetManager — custom dataset schemas attached to nodes.
  • assemblyManager — assembly relationships and BOM.

Events

EventPayload
storage:node-added{ node }
storage:node-removed{ nodeId }
storage:node-updated{ node, changes }
storage:hierarchy-built{ rootNodes, relationshipsBuilt }

Example

ts
const storage = viewer.getService<StorageService>("scene-hierarchy");

viewer.eventBus.on("storage:hierarchy-built", ({ rootNodes }) => {
  console.log("hierarchy ready:", rootNodes.length, "roots");
});

// Query all Part nodes deeper than depth 2.
const parts = storage.queryNodes({
  nodeType: NodeType.Part,
  customFilter: (n) => n.depth > 2,
});

// Export to JSON for persistence.
const json = storage.exportHierarchy("json");

Types

ts
enum NodeType {
  Root, Assembly, SubAssembly, Component, Part, Hardware, Reference
}

enum RelationType {
  Contains, References, Instances, Depends
}

interface HierarchyNode {
  id: string;
  name: string;
  path: string;
  parentId?: string;
  childIds: string[];
  depth: number;
  nodeType: NodeType;
  meshId: string;
  metadata: StorageMetadata;
  transform: TransformData;
  absoluteTransform: TransformData;
  boundingBox: THREE.Box3;
  isVisible: boolean;
  isLocked: boolean;
}

interface StorageMetadata {
  id: string;
  name: string;
  path: string;
  tags: string[];
  createdAt: number;
  updatedAt: number;
  customData: Record<string, any>;
  datasetType?: string;
  datasetData?: Record<string, any>;
}

interface TransformData {
  position: THREE.Vector3;
  rotation: THREE.Euler;
  scale: THREE.Vector3;
  matrix?: THREE.Matrix4;
}

interface QueryOptions {
  nodeType?: NodeType;
  depth?: number;
  tags?: string[];
  customFilter?: (node: HierarchyNode) => boolean;
  includeInvisible?: boolean;
  maxResults?: number;
}

interface BOMEntry {
  partNumber?: string;
  description?: string;
  material?: string;
  quantity: number;
  cost?: number;
  supplier?: string;
  category?: string;
  specifications?: Record<string, any>;
}

interface BOMItem {
  // Aggregated BOM line item exposed by assemblyManager.
}

XViewr SDK and xConvert CLI documentation.