import * as THREE from "three"; declare global { interface Window { THREE?: typeof THREE; } } import { NestedGroup, ObjectGroup } from "../scene/nestedgroup.js"; import { Grid } from "../scene/grid.js"; import { AxesHelper } from "../scene/axes.js"; import { OrientationMarker } from "../scene/orientation.js"; import { TreeView } from "../ui/treeview.js"; import { Clipping } from "../scene/clipping.js"; import { Animation } from "../scene/animation.js"; import type { DisposableTree } from "../utils/utils.js"; import { ShapeRenderer } from "../scene/render-shape.js"; import type { ShapeTreeData, RenderResult } from "../scene/render-shape.js"; import type { KeyMappingConfig } from "../utils/utils.js"; import { Controls } from "../camera/controls.js"; import { Camera, type CameraDirection } from "../camera/camera.js"; import { BoundingBox, BoxHelper } from "../scene/bbox.js"; import { Tools } from "../tools/cad_tools/tools.js"; import { PickedObject, Raycaster } from "../rendering/raycast.js"; import { ViewerState } from "./viewer-state.js"; import type { Display } from "../ui/display.js"; import type { Vector3Tuple, QuaternionTuple } from "three"; import { CollapseState, type ZebraColorScheme, type ZebraMappingMode, type StudioToneMapping, type StudioTextureMapping, type StudioBackground, type NotificationCallback, type RenderOptions, type ViewerOptions, type Shapes, type VisibilityState, type ActiveTab, type Axis, type ClipIndex, type ThemeInput, type BoundingBoxFlat, type Keymap } from "./types.js"; /** * Material settings for the viewer. */ interface MaterialSettings { ambientIntensity: number; directIntensity: number; metalness: number; roughness: number; } /** * Bounding box tracking for the last selected object. */ interface LastBboxInfo { id: string; bbox: BoxHelper; needsUpdate: boolean; } /** * Camera location settings. */ interface CameraLocationSettings { position: number[]; quaternion: number[]; target: number[]; zoom: number; } /** * Reset location settings from controls. */ interface ResetLocation { target0: THREE.Vector3; position0: THREE.Vector3; quaternion0: THREE.Quaternion; zoom0: number; } /** * Keymap configuration - re-export from utils for API compatibility. */ type KeymapConfig = Partial; /** * Image capture result. */ interface ImageResult { task: string; dataUrl: string | ArrayBuffer | null; } /** * Raycast event from keyboard or mouse. */ interface RaycastEvent { key?: string; mouse?: "left" | "right"; shift?: boolean; } /** * Backend response structure. */ interface BackendResponse { subtype: string; [key: string]: unknown; } /** * Display options for viewer construction. */ interface DisplayOptionsInternal { measureTools?: boolean; measurementDebug?: boolean; selectTool?: boolean; explodeTool?: boolean; zscaleTool?: boolean; zebraTool?: boolean; glass?: boolean; tools?: boolean; canvas?: HTMLCanvasElement; gl?: WebGLRenderingContext | WebGL2RenderingContext; keymap?: KeymapConfig; [key: string]: unknown; } /** * State that exists only after render() and before clear(). * Groups all resources that are created together during rendering. */ interface RenderedState { scene: THREE.Scene; ambientLight: THREE.AmbientLight; directLight: THREE.DirectionalLight; camera: Camera; controls: Controls; gridHelper: Grid; axesHelper: AxesHelper; clipping: Clipping; orientationMarker: OrientationMarker; nestedGroup: NestedGroup; treeview: TreeView; } /** * Main CAD viewer class that manages the 3D scene, rendering, and user interaction. * * The Viewer is created by Display and handles: * - WebGL rendering with Three.js * - Camera management (orthographic/perspective) * - Scene graph with CAD objects (NestedGroup/ObjectGroup) * - Clipping planes * - Material settings * - Animation playback * - Object picking and selection * * ## Lifecycle * 1. Created by Display constructor * 2. `render()` called to display CAD shapes * 3. User interacts via UI (calls setter methods) * 4. `clear()` to remove shapes (optional) * 5. `dispose()` for cleanup * * ## State Management * All state is centralized in `ViewerState`. Use getter/setter methods * rather than accessing state directly. * * @example * ```typescript * // Access via Display * const display = new Display(container, options); * display.render(shapes, states, options); * * // Access viewer methods * display.viewer.setAxes(true); * display.viewer.switchCamera(false); // perspective * ``` * * @public */ declare class Viewer { state: ViewerState; notifyCallback: NotificationCallback | null; pinAsPngCallback: ((data: ImageResult) => void) | null; updateMarker: boolean; ready: boolean; display: Display; renderer: THREE.WebGLRenderer; private _externalGl; onAfterRender: (() => void) | null; mouse: THREE.Vector2; cadTools: Tools; animation: Animation; clipNormals: [THREE.Vector3, THREE.Vector3, THREE.Vector3]; private _rendered; /** * Get rendered state, throwing if not yet rendered. */ get rendered(): RenderedState; tree: ShapeTreeData | null; bbox: BoundingBox | null; bb_max: number; bb_radius: number; private _stencilCSize; private _treeNeedsRebuild; private _pendingDisposal; shapes: Shapes | null; gridSize: number; private _previousGridSize; hasAnimationLoop: boolean; mixer: THREE.AnimationMixer | null; continueAnimation: boolean; clipAction: THREE.AnimationAction | null; shapeRenderer: ShapeRenderer | null; camera_distance: number; materialSettings: MaterialSettings | null; renderOptions: RenderOptions | null; lastNotification: Record; lastBbox: LastBboxInfo | null; lastObject: PickedObject | null; lastSelection: PickedObject | null; lastPosition: THREE.Vector3 | null; bboxNeedsUpdate: boolean; keepHighlight: boolean; expandedTree: ShapeTreeData | null; compactTree: ShapeTreeData | null; expandedNestedGroup: NestedGroup | null; compactNestedGroup: NestedGroup | null; raycaster: Raycaster | null; private _studioManager; /** Environment manager — proxied from StudioManager for display.ts access. */ get envManager(): import("../index.js").EnvironmentManager; zScale: number; clipNormal0: Vector3Tuple | null; clipNormal1: Vector3Tuple | null; clipNormal2: Vector3Tuple | null; keymap: KeymapConfig | null; info: DisposableTree | null; /** * Create Viewer. * @param display - The Display object. * @param options - configuration parameters. * @param notifyCallback - The callback to receive changes of viewer parameters. * @param pinAsPngCallback - Optional callback for PNG pinning. * @param updateMarker - enforce to redraw orientation marker after every ui activity */ constructor(display: Display, options: DisplayOptionsInternal, notifyCallback: NotificationCallback | null, pinAsPngCallback?: ((data: ImageResult) => void) | null, updateMarker?: boolean); /** * Return three-cad-viewer version as semver string. * @returns semver version * @public */ version(): string; /** * Apply render options and build materialSettings object. * Called by render() after state is populated with render options. * @param options - The provided options object for rendering. */ setRenderDefaults(options: RenderOptions): void; /** * Apply view options to state. * Called by render() after state is populated. * @param options - The provided options object for the view. */ setViewerDefaults(options: ViewerOptions): void; /** * @deprecated Use state properties directly. Kept for backwards compatibility. */ setDisplayDefaults(): void; dumpOptions(): void; /** * Get or create the ShapeRenderer instance with current configuration. */ private getShapeRenderer; /** * Render the shapes of the CAD object. * @param exploded - Whether to render the compact or exploded version * @param shapes - The Shapes object. * @returns A nested THREE.Group object and navigation tree. */ renderTessellatedShapes(exploded: boolean, shapes: Shapes): RenderResult; /** * Add a position animation track (full 3D translation). * @param selector - path/id of group to be animated. * @param times - array of keyframe times. * @param positions - array of [x, y, z] position offsets. */ addPositionTrack(selector: string, times: number[], positions: number[][]): void; /** * Add a single-axis translation animation track. * @param selector - path/id of group to be animated. * @param axis - which axis to translate along ("x", "y", or "z"). * @param times - array of keyframe times. * @param values - array of translation values along the axis. */ addTranslationTrack(selector: string, axis: Axis, times: number[], values: number[]): void; /** * Add a quaternion rotation animation track. * @param selector - path/id of group to be animated. * @param times - array of keyframe times. * @param quaternions - array of [x, y, z, w] quaternion values. */ addQuaternionTrack(selector: string, times: number[], quaternions: number[][]): void; /** * Add a single-axis rotation animation track. * @param selector - path/id of group to be animated. * @param axis - which axis to rotate around ("x", "y", or "z"). * @param times - array of keyframe times. * @param angles - array of rotation angles in degrees. */ addRotationTrack(selector: string, axis: Axis, times: number[], angles: number[]): void; /** * Initialize the animation. * @param duration - overall duration of the animation. * @param speed - speed of the animation. * @param label - animation label. * @param repeat - whether to repeat the animation. */ initAnimation(duration: number, speed: number, label?: string, repeat?: boolean): void; /** * Check whether animation object exists */ hasAnimation(): boolean; /** * Clear the animation object and dispose dependent objects */ clearAnimation(): void; /** * Set the animation to a specific relative time (0-1). * Pauses the animation at that point. * @param fraction - relative time between 0 and 1. */ setRelativeTime(fraction: number): void; /** * Get the current relative animation time (0-1). * @returns relative time between 0 and 1. */ getRelativeTime(): number; /** * Creates ChangeNotification object if new value != old value and sends change notifications via viewer.notifyCallback. * @param changes - change information. * @param notify - whether to send notification or not. */ checkChanges: (changes: Record, notify?: boolean) => void; /** * Notifies the states by checking for changes and passing the states to the checkChanges method. */ notifyStates: () => void; /** * Render scene and update orientation marker * If no animation loop exists, this needs to be called manually after every camera/scene change * @param updateMarker - whether to update the orientation marker * @param notify - whether to send notification or not. */ update: (updateMarker: boolean, notify?: boolean) => void; /** * Start the animation loop */ animate: () => void; toggleAnimationLoop(flag: boolean): void; /** * Remove all assets and event handlers. Call when done with the viewer. * * This disposes: * - WebGL renderer and context * - All Three.js objects (geometries, materials, textures) * - Event listeners * - CAD tools and raycaster * * After calling dispose(), the viewer instance should not be used. * * @public */ dispose(): void; /** * Clear the current CAD view without disposing the renderer. * * Use this to remove shapes before rendering new ones. * The viewer remains usable after clear(). * * @public */ clear(): void; /** * Synchronizes the states of two tree structures recursively. * * @param compactTree - The compact tree structure. * @param expandedTree - The expanded tree structure. * @param exploded - Whether rendering in exploded mode. * @param path - The current path in the tree structure. */ syncTreeStates: (compactTree: ShapeTreeData | VisibilityState, expandedTree: ShapeTreeData | VisibilityState, exploded: boolean, path: string) => void; /** * Get the color of a node from its path * @param path - path of the CAD object */ getNodeColor: (path: string) => string | null; /** * Build nestedGroup and treeview for initial render. * @param scene - The scene to add the group to * @param expanded - whether to render the exploded or compact version * @returns The nestedGroup and treeview */ private buildInitialGroup; /** * Toggle the two version of the NestedGroup. * Must only be called after render() has completed. * @param expanded - whether to render the exploded or compact version */ toggleGroup(expanded: boolean): void; /** * Set the active sidebar tab. * @param tabName - Tab name: "tree", "clip", "material", "zebra", or "studio" * @param notify - whether to send notification or not. */ setActiveTab(tabName: ActiveTab, notify?: boolean): void; toggleTab(disable: boolean): void; /** * Render a CAD object and build the navigation tree. * * This is the main entry point for displaying CAD geometry. It: * - Creates the Three.js scene with lights, camera, and controls * - Tessellates and renders the shape geometry * - Builds the navigation tree UI * - Sets up clipping planes and helpers * * @param shapes - the Shapes object representing the tessellated CAD object * @param renderOptions - the render options (edge color, opacity, etc.) * @param viewerOptions - the viewer options (camera position, clipping, etc.) * @public */ render(shapes: Shapes, renderOptions: RenderOptions, viewerOptions: ViewerOptions): void; /** * Move the camera to a given location. * @param relative - flag whether the position is a relative (e.g. [1,1,1] for iso) or absolute point. * @param position - the camera position as THREE.Vector3 * @param quaternion - the camera rotation expressed by a quaternion. * @param zoom - zoom value. * @param notify - whether to send notification or not. * @public */ setCamera: (relative: boolean, position: THREE.Vector3, quaternion?: THREE.Quaternion | null, zoom?: number | null, notify?: boolean) => void; /** * Move the camera to one of the preset locations. * @param dir - can be "iso", "top", "bottom", "front", "rear", "left", "right" * @param zoom - zoom value * @param notify - whether to send notification or not. * @public */ presetCamera: (dir: CameraDirection, zoom?: number | null, notify?: boolean) => void; /** * Get reset location value. * @returns target, position, quaternion, zoom as object. */ getResetLocation: () => ResetLocation; /** * Set reset location value. * @param target - camera target as 3 dim Array [x,y,z]. * @param position - camera position as 3 dim Array [x,y,z]. * @param quaternion - camera rotation as 4 dim quaternion array [x,y,z,w]. * @param zoom - camera zoom value. * @param notify - whether to send notification or not. */ setResetLocation: (target: Vector3Tuple, position: Vector3Tuple, quaternion: QuaternionTuple, zoom: number, notify?: boolean) => void; /** * Get camera type. * @returns "ortho" or "perspective". */ getCameraType(): string; /** * Set camera mode to OrthographicCamera or PerspectiveCamera. * @param flag - true for orthographic, false for perspective * @param notify - whether to send notification or not. * @public */ switchCamera(flag: boolean, notify?: boolean): void; /** * Recenter camera on the bounding box center of all objects. * @param notify - whether to send notification or not. */ recenterCamera(notify?: boolean): void; /** * Centers the camera view on all visible objects in the scene. * Calculates a bounding box that encompasses all visible ObjectGroup instances * and sets the camera target to the center of that bounding box. * * @param notify - Whether to notify listeners of the camera update */ centerVisibleObjects(notify?: boolean): void; /** * Reset zoom to 1.0. * @public */ resize: () => void; /** * Reset the view to the initial camera and controls settings. * @public */ reset: () => void; /** * Enable/disable local clipping * @param flag - whether to enable local clipping */ setLocalClipping(flag: boolean): void; /** * Sets the visibility state of an object in the viewer. * * @param path - The path of the object. * @param state - The visibility state (0 or 1). * @param iconNumber - The icon number. * @param notify - Whether to notify the changes. * @param update - Whether to update the view. */ setObject: (path: string, state: number, iconNumber: number, notify?: boolean, update?: boolean) => void; /** * Sets the bounding box for a given ID. * @param id - The ID of the group. */ setBoundingBox: (id: string) => void; /** * Refresh clipping plane * @param index - index of the plane: 0,1,2 * @param value - distance on the clipping normal from the center */ refreshPlane: (index: ClipIndex, value: number) => void; /** * Backup animation (for switch to explode animation) */ backupAnimation(): void; /** * Restore animation (for switch back from explode animation) */ restoreAnimation(): void; /** * Handler for the animation control * @param btn - the pressed button as string: "play", "pause", "stop" */ controlAnimation: (btn: string) => void; /** * Set state of one entry of a treeview leaf given by an id * @param id - object id * @param state - 2 dim array [mesh, edges] = [0/1, 0/1] * @param _nodeType - node type (unused) * @param notify - whether to send notification or not. */ setState: (id: string, state: VisibilityState, _nodeType?: string, notify?: boolean) => void; removeLastBbox(): void; /** * Handle bounding box and notifications for picked elements * @param path - path of object * @param name - name of object (id = path/name) * @param meta - meta key pressed * @param shift - shift key pressed * @param alt - alt key pressed * @param point - picked point * @param nodeType - node type * @param tree - whether from tree */ handlePick: (path: string, name: string, meta: boolean, shift: boolean, alt: boolean, point: THREE.Vector3 | null, nodeType?: string | null, tree?: boolean) => void; setPickHandler(flag: boolean): void; /** * Find the shape that was double clicked and send notification * @param e - a DOM PointerEvent or MouseEvent */ pick: (e: PointerEvent | MouseEvent) => void; clearSelection: () => void; _releaseLastSelected: () => void; _removeLastSelected: () => void; /** * Set raycast mode * @param flag - turn raycast mode on or off */ setRaycastMode(flag: boolean): void; handleRaycast: () => void; handleRaycastEvent: (event: RaycastEvent) => void; /** * Handle a backend response sent by the backend * The response is a JSON object sent by the Python backend through VSCode * @param response */ handleBackendResponse: (response: BackendResponse) => void; /** * Get whether axes helpers are visible. * @returns true if axes are shown * @public */ getAxes(): boolean; /** * Show or hide the axes helper (X/Y/Z indicators). * @param flag - true to show axes, false to hide * @param notify - whether to send notification to callback * @public */ setAxes: (flag: boolean, notify?: boolean) => void; /** * Show/hide grids * @param action - one of "grid" (all grids), "grid-xy","grid-xz", "grid-yz" * @param flag - visibility flag * @param notify - whether to send notification or not. */ setGrid: (action: string, flag: boolean, notify?: boolean) => void; /** * Get visibility of grids. * @returns grids value. */ getGrids(): [boolean, boolean, boolean]; /** * Toggle grid visibility * @param grids - 3 dim grid visibility (xy, xz, yz) * @param notify - whether to send notification or not. */ setGrids: (grids: [boolean, boolean, boolean], notify?: boolean) => void; /** * Set grid center * @param center - true for centering grid at (0,0,0) * @param notify - whether to send notification or not. */ setGridCenter: (center: boolean, notify?: boolean) => void; /** * Get location of axes. * @returns axes0 value, true means at origin (0,0,0) */ getAxes0(): boolean; /** * Set whether grids and axes center at the origin or the object's boundary box center * @param flag - whether grids and axes center at the origin (0,0,0) * @param notify - whether to send notification or not. */ setAxes0: (flag: boolean, notify?: boolean) => void; /** * Get transparency state of CAD objects. * @returns transparent value. */ getTransparent(): boolean; /** * Set CAD objects transparency. * @param flag - whether to show the CAD object in transparent mode * @param notify - whether to send notification or not. * @public */ setTransparent: (flag: boolean, notify?: boolean) => void; /** * Get blackEdges value. * @returns blackEdges value. */ getBlackEdges(): boolean; /** * Show edges in black or the default edge color. * @param flag - whether to show edges in black * @param notify - whether to send notification or not. * @public */ setBlackEdges: (flag: boolean, notify?: boolean) => void; /** * Show or hide the CAD tools panel * @param flag - whether to show tools * @param notify - whether to send notification or not. */ setTools: (flag: boolean, notify?: boolean) => void; /** * Enable or disable glass mode (overlay navigation) * @param flag - whether to enable glass mode * @param notify - whether to send notification or not. */ setGlass: (flag: boolean, notify?: boolean) => void; /** * Get default color of the edges. * @returns edgeColor value. */ getEdgeColor(): number; /** * Set the default edge color * @param color - edge color (0xrrggbb) * @param notify - whether to send notification or not. */ setEdgeColor: (color: number, notify?: boolean) => void; /** * Get default opacity. * @returns opacity value. */ getOpacity(): number; /** * Set the default opacity * @param opacity - opacity (between 0.0 and 1.0) * @param notify - whether to send notification or not. */ setOpacity: (opacity: number, notify?: boolean) => void; /** * Get whether tools are shown/hidden. * @returns tools value. */ getTools(): boolean; /** * Show/hide the CAD tools * @param flag - visibility flag * @param notify - whether to send notification or not. */ showTools: (flag: boolean, notify?: boolean) => void; /** * Get intensity of ambient light. * @returns ambientLight value. */ getAmbientLight(): number; /** * Set the intensity of ambient light. * @param val - the new ambient light intensity (0-4) * @param notify - whether to send notification or not. * @public */ setAmbientLight: (val: number, notify?: boolean) => void; /** * Get intensity of direct light. * @returns directLight value. */ getDirectLight(): number; /** * Set the intensity of directional light. * @param val - the new direct light intensity (0-4) * @param notify - whether to send notification or not. * @public */ setDirectLight: (val: number, notify?: boolean) => void; /** * Retrieves the metalness value. * * @returns The current metalness value. */ getMetalness: () => number; /** * Sets the metalness value for the viewer and updates related properties. * * @param value - The metalness value to set (0-1). * @param notify - Whether to notify about the changes. * @public */ setMetalness: (value: number, notify?: boolean) => void; /** * Retrieves the roughness value. * * @returns The current roughness value. */ getRoughness: () => number; /** * Sets the roughness value for the viewer and updates related components. * * @param value - The roughness value to set (0-1). * @param notify - Whether to notify about the changes. * @public */ setRoughness: (value: number, notify?: boolean) => void; /** * Resets the material settings of the viewer to their default values. * Updates the metalness, roughness, ambient light intensity, and direct light intensity * based on the current material settings. */ resetMaterial: () => void; enableZebraTool: (flag: boolean) => void; /** * Sets the stripe count value for the viewer and updates related components. * @param value - The stripe count value to set. */ setZebraCount: (value: number) => void; /** * Sets the stripe opacity value for the viewer and updates related components. * @param value - The stripe opacity value to set. */ setZebraOpacity: (value: number) => void; /** * Sets the stripe direction value for the viewer and updates related components. * @param value - The stripe direction value to set. */ setZebraDirection: (value: number) => void; /** * Sets the stripe color scheme for the viewer and updates related components. * @param value - The color scheme ("blackwhite", "colorful", "grayscale"). */ setZebraColorScheme: (value: ZebraColorScheme) => void; /** * Sets the stripe mapping mode for the viewer and updates related components. * @param value - The mapping mode ("reflection", "normal"). */ setZebraMappingMode: (value: ZebraMappingMode) => void; /** * Resets zebra tool settings to defaults: count=9, opacity=1, direction=0, * colorScheme=blackwhite, mappingMode=reflection. */ resetZebra: () => void; /** * Gets the current stripe count value. * @returns The stripe count (2-50). */ getZebraCount: () => number; /** * Gets the current stripe opacity value. * @returns The stripe opacity (0-1). */ getZebraOpacity: () => number; /** * Gets the current stripe direction value. * @returns The stripe direction in degrees (0-90). */ getZebraDirection: () => number; /** * Gets the current stripe color scheme. * @returns The color scheme ("blackwhite", "colorful", "grayscale"). */ getZebraColorScheme: () => ZebraColorScheme; /** * Gets the current stripe mapping mode. * @returns The mapping mode ("reflection", "normal"). */ getZebraMappingMode: () => ZebraMappingMode; /** * Sets the studio environment preset. * @param value - The environment name ("studio", "neutral", "outdoor", "none", or custom HDR URL). * @param notify - Whether to notify about the changes. * @public */ setStudioEnvironment: (value: string, notify?: boolean) => void; /** * Sets the studio environment intensity. * @param value - The environment intensity (0-3). * @param notify - Whether to notify about the changes. * @public */ setStudioEnvIntensity: (value: number, notify?: boolean) => void; /** * Sets the background mode for Studio mode. * @param value - The background mode ("grey", "white", "gradient", "environment", or "transparent"). * @param notify - Whether to notify about the changes. * @public */ setStudioBackground: (value: StudioBackground, notify?: boolean) => void; /** * Sets the tone mapping mode for Studio mode. * @param value - The tone mapping mode ("neutral", "ACES", or "none"). * @param notify - Whether to notify about the changes. * @public */ setStudioToneMapping: (value: StudioToneMapping, notify?: boolean) => void; /** * Sets the exposure value for Studio mode. * @param value - The exposure value (0-2). * @param notify - Whether to notify about the changes. * @public */ setStudioExposure: (value: number, notify?: boolean) => void; /** * Sets whether 4K environment maps are used (default: 2K). * @param value - True for 4K, false for 2K. * @param notify - Whether to notify about the changes. * @public */ setStudio4kEnvMaps: (value: boolean, notify?: boolean) => void; /** * Gets whether 4K environment maps are enabled. * @returns True for 4K, false for 2K. * @public */ getStudio4kEnvMaps: () => boolean; /** * Sets the environment rotation for Studio mode. * @param value - The rotation in degrees (0-360). * @param notify - Whether to notify about the changes. * @public */ setStudioEnvRotation: (value: number, notify?: boolean) => void; /** * Gets the current environment rotation for Studio mode. * @returns The rotation in degrees (0-360). * @public */ getStudioEnvRotation: () => number; /** * Sets the texture mapping mode for Studio mode. * @param value - The texture mapping mode ("triplanar" or "parametric"). * @param notify - Whether to notify about the changes. * @public */ setStudioTextureMapping: (value: StudioTextureMapping, notify?: boolean) => void; /** * Gets the current texture mapping mode for Studio mode. * @returns The texture mapping mode ("triplanar" or "parametric"). * @public */ getStudioTextureMapping: () => StudioTextureMapping; /** * Gets the current studio environment preset. * @returns The environment name ("studio", "neutral", "outdoor", "none", or custom HDR URL). * @public */ getStudioEnvironment: () => string; /** * Gets the current studio environment intensity. * @returns The environment intensity (0-3). * @public */ getStudioEnvIntensity: () => number; /** * Gets the current background mode for Studio mode. * @returns The background mode ("grey", "white", "gradient", "environment", or "transparent"). * @public */ getStudioBackground: () => StudioBackground; /** * Gets the current tone mapping mode for Studio mode. * @returns The tone mapping mode ("neutral", "ACES", or "none"). * @public */ getStudioToneMapping: () => StudioToneMapping; /** * Gets the current exposure value for Studio mode. * @returns The exposure value (0-3). * @public */ getStudioExposure: () => number; /** * Sets the shadow intensity in Studio mode. * A value of 0 disables shadows; values > 0 enable them at that darkness. * @param value - The shadow intensity (0-1). * @param notify - Whether to notify about the changes. * @public */ setStudioShadowIntensity: (value: number, notify?: boolean) => void; /** * Gets the current shadow intensity in Studio mode. * @returns The shadow intensity (0-1). 0 means shadows are off. * @public */ getStudioShadowIntensity: () => number; /** * Sets the shadow softness in Studio mode. * Controls PCSS penumbra width (virtual light source size). * @param value - The shadow softness (0-1). * @param notify - Whether to notify about the changes. * @public */ setStudioShadowSoftness: (value: number, notify?: boolean) => void; /** * Gets the current shadow softness in Studio mode. * @returns The shadow softness (0-1). * @public */ getStudioShadowSoftness: () => number; /** * Sets the ambient occlusion intensity in Studio mode. * A value of 0 disables AO; values > 0 enable it at that intensity. * @param value - The AO intensity (0-3.0). * @param notify - Whether to notify about the changes. * @public */ setStudioAOIntensity: (value: number, notify?: boolean) => void; /** * Gets the current ambient occlusion intensity in Studio mode. * @returns The AO intensity value (0.5-3.0). * @public */ getStudioAOIntensity: () => number; /** * Returns whether Studio mode is currently active. * @returns True if Studio mode is active and the viewer has rendered content. * @public */ get isStudioActive(): boolean; /** * Get the ObjectGroup and path for the currently selected object in Studio mode. * Returns null if nothing is selected, Studio mode is inactive, or the * selection is a CompoundGroup (assembly node) rather than a leaf object. */ getSelectedObjectGroup(): { object: ObjectGroup; path: string; } | null; /** Enter Studio mode. Called by display.ts switchToTab(). @internal */ enterStudioMode: () => Promise; /** Leave Studio mode. Called by display.ts switchToTab(). @internal */ leaveStudioMode: () => void; /** Reset Studio settings to defaults. @public */ resetStudio: () => void; /** * Get ortho value as property (for ViewerLike interface compatibility). */ get ortho(): boolean; /** * Get camera property. Throws if not rendered. */ get camera(): Camera; /** * Get nestedGroup property. Throws if not rendered. */ get nestedGroup(): NestedGroup; /** * Get clipping property. Throws if not rendered. */ get clipping(): Clipping; /** * Get treeview property. Returns null if not rendered. */ get treeview(): TreeView | null; /** * Get orientationMarker property. Throws if not rendered. */ get orientationMarker(): OrientationMarker; /** * Get gridHelper property. Throws if not rendered. */ get gridHelper(): Grid; /** * Get axesHelper property. Throws if not rendered. */ get axesHelper(): AxesHelper; /** * Get scene property. Throws if not rendered. */ get scene(): THREE.Scene; /** * Get controls property. Throws if not rendered. */ get controls(): Controls; /** * Get ambientLight property. Throws if not rendered. */ get ambientLight(): THREE.AmbientLight; /** * Get directLight property. Throws if not rendered. */ get directLight(): THREE.DirectionalLight; /** * Get ortho value. * @returns ortho value. */ getOrtho(): boolean; /** * Set/unset camera's orthographic mode. * @param flag - whether to set orthographic mode or not. * @param notify - whether to send notification or not. */ setOrtho(flag: boolean, notify?: boolean): void; /** * Set zscaling value. * @param value - scale factor. */ setZscaleValue(value: number): void; /** * Get zoom value. * @returns zoom value. * @public */ getCameraZoom(): number; /** * Set zoom value. * @param val - float zoom value. * @param notify - whether to send notification or not. * @public */ setCameraZoom(val: number, notify?: boolean): void; /** * Get the current camera position. * @returns camera position as 3 dim array [x,y,z]. * @public */ getCameraPosition(): number[]; /** * Set camera position. * @param position - camera position as 3 dim Array [x,y,z]. * @param relative - flag whether the position is a relative (e.g. [1,1,1] for iso) or absolute point. * @param notify - whether to send notification or not. * @public */ setCameraPosition(position: Vector3Tuple, relative?: boolean, notify?: boolean): void; /** * Get the current camera rotation as quaternion. * @returns camera rotation as 4 dim quaternion array [x,y,z,w]. * @public */ getCameraQuaternion(): QuaternionTuple; /** * Set camera rotation via quaternion. * @param quaternion - camera rotation as 4 dim quaternion array [x,y,z,w]. * @param notify - whether to send notification or not. * @public */ setCameraQuaternion(quaternion: QuaternionTuple, notify?: boolean): void; /** * Get the current camera target. * @returns camera target as 3 dim array array [x,y,z]. * @public */ getCameraTarget(): Vector3Tuple; /** * Set camera target. * @param target - camera target as THREE.Vector3 or [x, y, z] tuple. * @param notify - whether to send notification or not. * @public */ setCameraTarget(target: THREE.Vector3 | Vector3Tuple, notify?: boolean): void; getCameraLocationSettings(): CameraLocationSettings; setCameraLocationSettings(position?: Vector3Tuple | null, quaternion?: QuaternionTuple | null, target?: Vector3Tuple | null, zoom?: number | null, notify?: boolean): void; /** * Get states of all treeview leaves. * @returns object mapping paths to visibility states. * @public */ getStates(): Record; /** * Get state of a treeview leaf for a path. * separator can be / or | * @param path - path of the object * @returns state value in the form of [mesh, edges] = [0/1, 0/1] * @public */ getState(path: string): VisibilityState | null; /** * Set states of treeview leaves. * @param states - states object mapping paths to visibility states. * @public */ setStates: (states: Record) => void; /** * Build tree data from a Shapes object. * Mirrors ShapeRenderer._getTree() logic. */ private _buildTreeData; /** * Find the parent Shapes node and the parent's parts array for a given path. * @param path - Absolute path like "/root/group/part" * @returns The parent Shapes node, or null if not found. */ private _findShapesParent; /** * Rebuild the treeview from the current shapes data. * Preserves visibility states across the rebuild. */ private _rebuildTreeView; /** * Apply current material/rendering settings to new objects in the group. * @param paths - The paths of the newly added objects. */ private _applyCurrentSettings; /** * Add a part (leaf or subtree) to the scene under an existing parent. * * For a **leaf**, pass a Shapes object with `shape` set and `name` * as a plain name (no leading slash). The absolute path is built as * `parentPath + "/" + partData.name`. * * For a **subtree**, pass a Shapes object with `parts` set and `id` * as a slash-prefixed relative tree (e.g. `"/shelf"`). All `id` * fields in the tree are prefixed with `parentPath` before rendering. * * When adding many parts in a batch, pass `{ skipBounds: true }` to * defer the expensive bounds/clipping/treeview recomputation, then call * `updateBounds()` once after the loop. * * @param parentPath - Absolute path of the parent group * (e.g. "/assembly"). Must already exist as a CompoundGroup. * @param partData - A Shapes object describing the part to add. * @param options - Optional settings. * @param options.skipBounds - When true, skip bounds/clipping/treeview * update and re-render. Caller must call `updateBounds()` afterwards. * @returns The absolute path of the added root element. * @throws If the viewer is not rendered, the parent doesn't exist, * or the name/id already exists at that level. * @public */ addPart(parentPath: string, partData: Shapes, options?: { skipBounds?: boolean; }): string; /** * Recursively prefix all `id` fields in a Shapes tree. */ private _prefixIds; /** * Remove a part (leaf or subtree) from the scene by path. * * When removing many parts in a batch, pass `{ skipBounds: true }` to * defer the expensive bounds/clipping/treeview recomputation, then call * `updateBounds()` once after the loop. * * @param path - The absolute path of the part to remove * (e.g., "/assembly/shelf_5"). * @param options - Optional settings. * @param options.skipBounds - When true, skip bounds/clipping/treeview * update and re-render. Caller must call `updateBounds()` afterwards. * @throws If the viewer is not rendered or the path doesn't exist. * @public */ removePart(path: string, options?: { skipBounds?: boolean; }): void; /** * Update an existing part's geometry. * * When the mesh topology is unchanged (same number of vertices, triangles, * and edge segments), buffers are updated in-place — no Three.js objects * are disposed or recreated. When topology differs the method * automatically falls back to a batched `removePart` + `addPart`. * * Only leaf parts (ObjectGroups with `shapeGeometry`) are supported. * The part must already exist in the scene. * * When updating many parts in a batch, pass `{ skipBounds: true }` to * defer the expensive bounds/clipping recomputation, then call * `updateBounds()` once after the loop: * * ```ts * for (const p of parts) { * viewer.updatePart(path, data, { skipBounds: true }); * } * viewer.updateBounds(); * ``` * * @param path - The absolute path of the part to update * (e.g., "/assembly/part"). * @param partData - A Shapes object with the new `shape` data. * The `shape.vertices`, `shape.normals`, `shape.triangles`, and * `shape.edges` fields are used to update the geometry. * Optionally `color`, `alpha`, and `loc` are synced into `this.shapes`. * @param options - Optional settings. * @param options.skipBounds - When true, skip bounds/clipping/explode-cache * update and re-render. Caller must call `updateBounds()` afterwards. * @throws If the viewer is not rendered, the path doesn't exist, * or the target is not a leaf ObjectGroup with shape geometry. * @public */ updatePart(path: string, partData: Shapes, options?: { skipBounds?: boolean; }): void; /** * Recompute scene bounds, camera far plane, clipping stencils, and * re-render. Call this once after a batch of * `addPart`, `removePart`, or `updatePart` calls that used * `{ skipBounds: true }`. * * If parts were added or removed in the batch, the navigation treeview * is also rebuilt automatically. * * @public */ updateBounds(): void; /** * Pre-size the clipping stencil region so that all future `updatePart` / * `updateBounds` calls whose geometry stays within `bb` will never trigger * an expensive `rebuildStencils`. * * Call this once before a series of updates when the maximum extent of the * geometry is known upfront (e.g. the parameter range of a slider). * * @param bb - The maximum bounding box that geometry will ever occupy. */ ensureStencilSize(bb: BoundingBoxFlat): void; /** * Get zoom speed. * @returns zoomSpeed value. */ getZoomSpeed(): number; /** * Set zoom speed. * @param val - the new zoom speed * @param notify - whether to send notification or not. */ setZoomSpeed: (val: number, notify?: boolean) => void; /** * Get panning speed. * @returns pan speed value. */ getPanSpeed(): number; /** * Set pan speed. * @param val - the new pan speed * @param notify - whether to send notification or not. */ setPanSpeed: (val: number, notify?: boolean) => void; /** * Get rotation speed. * @returns rotation speed value. */ getRotateSpeed(): number; /** * Set rotation speed. * @param val - the new rotation speed. * @param notify - whether to send notification or not. */ setRotateSpeed: (val: number, notify?: boolean) => void; /** * Get holroyd (non-tumbling) trackball mode. * @returns holroyd flag. */ getHolroyd(): boolean; /** * Set holroyd (non-tumbling) trackball mode. * When false, uses standard Three.js TrackballControls behavior. * @param flag - whether to enable holroyd mode. * @param notify - whether to send notification or not. */ setHolroyd: (flag: boolean, notify?: boolean) => void; /** * Get intersection mode. * @returns clip intersection value. */ getClipIntersection(): boolean; /** * Set the clipping mode to intersection mode * @param flag - whether to use intersection mode * @param notify - whether to send notification or not. */ setClipIntersection: (flag: boolean, notify?: boolean) => void; /** * Get whether the clipping caps color status * @returns color caps value (object color (true) or RGB (false)). */ getObjectColorCaps: () => boolean; /** * Toggle the clipping caps color between object color and RGB * @param flag - whether to use intersection mode * @param notify - whether to send notification or not. */ setClipObjectColorCaps: (flag: boolean, notify?: boolean) => void; /** * Get clipping plane state. * @returns clip plane visibility value. */ getClipPlaneHelpers(): boolean; /** * Show/hide clip plane helpers * @param flag - whether to show clip plane helpers * @param notify - whether to send notification or not. */ setClipPlaneHelpers: (flag: boolean, notify?: boolean) => void; /** * Get clipping plane state. * @param index - index of the normal: 0, 1 ,2 * @returns clip plane visibility value. */ getClipNormal(index: ClipIndex): Vector3Tuple; /** * Set the normal at index to a given normal * @param index - index of the normal: 0, 1 ,2 * @param normal - 3 dim array representing the normal * @param value - value of the slider, if given * @param notify - whether to send notification or not. */ setClipNormal(index: ClipIndex, normal: Vector3Tuple | null, value?: number | null, notify?: boolean): void; /** * Set the normal at index to the current viewing direction * @param index - index of the normal: 0, 1 ,2 * @param notify - whether to send notification or not. */ setClipNormalFromPosition: (index: ClipIndex, notify?: boolean) => void; /** * Get clipping slider value. * @param index - index of the normal: 0, 1 ,2 * @returns clip slider value. */ getClipSlider: (index: 0 | 1 | 2) => number; /** * Set clipping slider value and update the clipping plane. * @param index - index of the normal: 0, 1 ,2 * @param value - value for the clipping slider * @param notify - whether to send notification or not. */ setClipSlider: (index: 0 | 1 | 2, value: number, notify?: boolean) => void; /** * Resets clip planes to default normals and slider positions. * Normals reset to -X, -Y, -Z; sliders to gridSize/2; checkboxes unchecked. */ resetClip: () => void; /** * Replace CadView with an inline png image of the canvas. * * Note: Only the canvas will be shown, no tools and orientation marker */ pinAsPng: () => void; /** * Get the current canvas as png data. * @param taskId - an id to identify the screenshot * @returns Promise resolving to task ID and data URL * Note: Only the canvas will be shown, no tools and orientation marker * @public */ getImage: (taskId: string) => Promise; /** * Calculate explode trajectories and initiate the animation. * * @param duration - duration of animation. * @param speed - speed of animation. * @param multiplier - multiplier for length of trajectories. * @public */ explode(duration?: number, speed?: number, multiplier?: number): void; /** * Toggle explode mode on/off. * @param flag - whether to enable or disable explode mode * @param notify - whether to send notification or not. * @public */ setExplode(flag: boolean, notify?: boolean): void; /** * Activate or deactivate a measurement/selection tool. * This is the single entry point for tool state changes - Display should call this * rather than mutating state directly. * @param name - Tool name ("distance", "properties", "select") * @param flag - Whether to activate (true) or deactivate (false) the tool */ activateTool(name: string, flag: boolean): void; /** * Set modifiers and action shortcuts for keymap * * @param config - keymap e.g. {"shift": "shiftKey", "ctrl": "ctrlKey", "meta": "altKey", "axes": "a", ...} */ setKeyMap(config: Keymap): void; /** * Get the current CAD view width. * @public */ get cadWidth(): number; /** * Get the current tree width. * @public */ get treeWidth(): number; /** * Get the current view height. * @public */ get height(): number; /** * Get the current glass mode state. * @public */ get glass(): boolean; /** * Resize UI and renderer. * * @param cadWidth - new width of CAD View * @param treeWidth - new width of navigation tree * @param height - new height of CAD View * @param glass - Whether to use glass mode or not * @public */ resizeCadView(cadWidth: number, treeWidth: number, height: number, glass?: boolean): void; /** * Set camera to a predefined view direction. * @param direction - "iso", "front", "rear", "left", "right", "top", or "bottom" * @param focus - whether to focus/center on visible objects * @public */ setView: (direction: string, focus?: boolean) => void; /** * Enable/disable glass mode (transparent overlay UI). * @param flag - whether to enable glass mode * @param notify - whether to send notification or not. * @public */ glassMode: (flag: boolean, notify?: boolean) => void; /** * Collapse or expand tree nodes. * @param value - CollapseState enum value * @param notify - whether to send notification or not. * @public */ collapseNodes: (value: CollapseState, notify?: boolean) => void; /** * Set the UI theme. * @param theme - "light", "dark", or "browser" for auto-detection * @returns The resolved theme ("light" or "dark") * @public */ setTheme: (theme: ThemeInput) => string; /** * Show/hide the help dialog. * @param flag - whether to show the help dialog * @public */ showHelp: (flag: boolean) => void; /** * Collapse or expand the info panel in glass mode. * @param flag - true to show, false to collapse * @public */ showInfoPanel: (flag: boolean) => void; /** * @deprecated Use showInfoPanel() instead. */ showInfo: (flag: boolean) => void; /** * Collapse or expand the tools panel (tabs + content) in glass mode. * @param flag - true to show, false to collapse * @public */ showToolsPanel: (flag: boolean) => void; /** * Show/hide the pinning button. * @param flag - whether to show the pinning button * @public */ showPinning: (flag: boolean) => void; /** * Show/hide the measure tools. * @param flag - whether to show the measure tools * @public */ showMeasureTools: (flag: boolean) => void; /** * Show/hide the select tool. * @param flag - whether to show the select tool * @public */ showSelectTool: (flag: boolean) => void; /** * Show/hide the explode tool. * @param flag - whether to show the explode tool * @public */ showExplodeTool: (flag: boolean) => void; /** * Show/hide the z-scale tool. * @param flag - whether to show the z-scale tool * @public */ showZScaleTool: (flag: boolean) => void; /** * Get the canvas DOM element. * @returns The canvas element * @public */ getCanvas: () => Element; vector3(x?: number, y?: number, z?: number): THREE.Vector3; quaternion(x?: number, y?: number, z?: number, w?: number): THREE.Quaternion; } export { Viewer };