import { CameraState } from "./ThreeJsPanel.js"; import VolumeDrawable from "./VolumeDrawable.js"; import { Light } from "./Light.js"; import Volume from "./Volume.js"; import { type VolumeChannelDisplayOptions, type VolumeDisplayOptions, ViewportCorner, RenderMode } from "./types.js"; import { PerChannelCallback } from "./loaders/IVolumeLoader.js"; import VolumeLoaderContext from "./workers/VolumeLoaderContext.js"; export declare const RENDERMODE_RAYMARCH = RenderMode.RAYMARCH; export declare const RENDERMODE_PATHTRACE = RenderMode.PATHTRACE; export interface View3dOptions { parentElement?: HTMLElement; useWebGL2?: boolean; } /** * @class */ export declare class View3d { loaderContext?: VolumeLoaderContext; private canvas3d; private scene; private backgroundColor; private pixelSamplingRate; private exposure; private volumeRenderMode; private renderUpdateListener?; private loadErrorHandler?; private image?; private lights; private lightContainer; private ambientLight; private spotLight; private reflectedLight; private fillLight; private tweakpane; /** * @param {Object} options Optional options. * @param {boolean} options.useWebGL2 Default true * @param {HTMLElement} options.parentElement An optional element to which to append the viewer element on creation. * The viewer will attempt to fill this element if provided. */ constructor(options?: View3dOptions); preRender(): void; private updateOrthoScaleBar; private updatePerspectiveScaleBar; private updateTimestepIndicator; /** * Capture the contents of this canvas to a data url * @param {Object} dataurlcallback function to call when data url is ready; function accepts dataurl as string arg */ capture(dataurlcallback: (name: string) => void): void; getDOMElement(): HTMLDivElement; getCameraState(): CameraState; setCameraState(transform: Partial): void; /** * Force a redraw. */ redraw(): void; unsetImage(): VolumeDrawable | undefined; /** * Add a new volume image to the viewer. (The viewer currently only supports a single image at a time - adding repeatedly, without removing in between, is a potential resource leak) * @param {Volume} volume * @param {VolumeDisplayOptions} options */ addVolume(volume: Volume, options?: VolumeDisplayOptions): void; /** * Apply a set of display options to a given channel of a volume * @param {Volume} volume * @param {number} channelIndex the channel index * @param {VolumeChannelDisplayOptions} options */ setVolumeChannelOptions(volume: Volume, channelIndex: number, options: VolumeChannelDisplayOptions): void; /** * Apply a set of display options to the given volume * @param {Volume} volume * @param {VolumeDisplayOptions} options */ setVolumeDisplayOptions(volume: Volume, options: VolumeDisplayOptions): void; /** * Remove a volume image from the viewer. This will clean up the View3D's resources for the current volume * @param {Volume} volume */ removeVolume(volume: Volume): void; /** * Remove all volume images from the viewer. */ removeAllVolumes(): void; /** * @param {function} callback a function that will receive the number of render iterations when it changes */ setRenderUpdateListener(callback: (iteration: number) => void): void; onVolumeData(volume: Volume, channels: number[]): void; onVolumeChannelAdded(volume: Volume, newChannelIndex: number): void; onVolumeLoadError(volume: Volume, error: unknown): void; setLoadErrorHandler(handler: ((volume: Volume, error: unknown) => void) | undefined): void; setTime(volume: Volume, time: number, onChannelLoaded?: PerChannelCallback): void; /** * Nudge the scale level loaded into this volume off the one chosen by the loader. * E.g. a bias of `1` will load 1 scale level lower than "ideal." */ setScaleLevelBias(volume: Volume, scaleLevelBias: number): void; /** * Assign a channel index as a mask channel (will multiply its color against the entire visible volume) * @param {Object} volume * @param {number} maskChannelIndex */ setVolumeChannelAsMask(volume: Volume, maskChannelIndex: number): void; /** * Set voxel dimensions - controls volume scaling. For example, the physical measurements of the voxels from a biological data set * @param {Object} volume * @param {number} values Array of x,y,z floating point values for the physical voxel size scaling * @param {string} unit The unit of `values`, if different than previous */ setVoxelSize(volume: Volume, values: number[], unit?: string): void; setRayStepSizes(volume: Volume, primary: number, secondary: number): void; setShowBoundingBox(volume: Volume, showBoundingBox: boolean): void; setBoundingBoxColor(volume: Volume, color: [number, number, number]): void; setBackgroundColor(color: [number, number, number]): void; /** * Is an isosurface already created for this channel? * @param {Object} volume * @param {number} channel * @return true if there is currently a mesh isosurface for this channel */ hasIsosurface(volume: Volume, channel: number): boolean; /** * Save a channel's isosurface as a triangle mesh to either STL or GLTF2 format. File will be named automatically, using image name and channel name. * @param {Object} volume * @param {number} channelIndex * @param {string} type Either 'GLTF' or 'STL' */ saveChannelIsosurface(volume: Volume, channelIndex: number, type: string): void; setImage(img: VolumeDrawable): VolumeDrawable | undefined; onStartControls(): void; onChangeControls(): void; onEndControls(): void; buildScene(): void; /** * Change the camera projection to look along an axis, or to view in a 3d perspective camera. * @param {string} mode Mode can be "3D", or "XY" or "Z", or "YZ" or "X", or "XZ" or "Y". 3D is a perspective view, and all the others are orthographic projections */ setCameraMode(mode: string): void; setZSlice(volume: Volume, slice: number): boolean; /** * Enable or disable 3d axis display at lower left. * @param {boolean} showAxis */ setShowAxis(showAxis: boolean): void; /** * Enable or disable scale indicators. * @param showScaleBar */ setShowScaleBar(showScaleBar: boolean): void; /** * Enable or disable time indicator. * @param showTimestepIndicator */ setShowTimestepIndicator(showIndicator: boolean): void; /** * Set the position of the axis indicator, as a corner of the viewport and horizontal and vertical margins from the * edge of the viewport. * @param {number} marginX * @param {number} marginY * @param {string} [corner] The corner of the viewport in which the axis appears. Default: `"bottom_left"`. * TypeScript users should use the `ViewportCorner` enum. Otherwise, corner is one of: `"top_left"`, `"top_right"`, * `"bottom_left"`, `"bottom_right"`. */ setAxisPosition(marginX: number, marginY: number, corner?: ViewportCorner): void; /** * Set the position of the scale bar, as a corner of the viewport and horizontal and vertical margins from the edge * of the viewport. * @param {number} marginX * @param {number} marginY * @param {string} [corner] The corner of the viewport in which the scale bar appears. Default: `"bottom_right"`. * TypeScript users should use the `ViewportCorner` enum. Otherwise, corner is one of: `"top_left"`, `"top_right"`, * `"bottom_left"`, `"bottom_right"`. */ setScaleBarPosition(marginX: number, marginY: number, corner?: ViewportCorner): void; /** * Set the position of the time step indicator, as a corner of the viewport and horizontal and vertical margins from * the edge of the viewport. * @param {number} marginX * @param {number} marginY * @param {string} [corner] The corner of the viewport in which the scale bar appears. Default: `"bottom_right"`. * TypeScript users should use the `ViewportCorner` enum. Otherwise, corner is one of: `"top_left"`, `"top_right"`, * `"bottom_left"`, `"bottom_right"`. */ setTimestepIndicatorPosition(marginX: number, marginY: number, corner?: ViewportCorner): void; /** * Enable or disable a turntable rotation mode. The display will continuously spin about the vertical screen axis. * @param {boolean} autorotate */ setAutoRotate(autorotate: boolean): void; /** * Set the unit symbol for the scale bar (e.g. µm) * @param {string} unit */ setScaleUnit(unit: string): void; /** * Invert axes of volume. -1 to invert, +1 NOT to invert. * @param {Object} volume * @param {number} flipX x axis sense * @param {number} flipY y axis sense * @param {number} flipZ z axis sense */ setFlipVolume(volume: Volume, flipX: -1 | 1, flipY: -1 | 1, flipZ: -1 | 1): void; setInterpolationEnabled(volume: Volume, active: boolean): void; /** * Notify the view that it has been resized. This will automatically be connected to the window when the View3d is created. * @param {HTMLElement=} comp Ignored. * @param {number=} w Width, or parent element's offsetWidth if not specified. * @param {number=} h Height, or parent element's offsetHeight if not specified. * @param {number=} ow Ignored. * @param {number=} oh Ignored. * @param {Object=} eOpts Ignored. */ resize(comp: HTMLElement | null, w?: number, h?: number, ow?: number, oh?: number, eOpts?: unknown): void; /** * Set the volume scattering density * @param {Object} volume * @param {number} density 0..1 UI slider value */ updateDensity(volume: Volume, density: number): void; /** * Set the shading method - applies to pathtraced render mode only * @param {Object} volume * @param {number} isbrdf 0: brdf, 1: isotropic phase function, 2: mixed */ updateShadingMethod(volume: Volume, isbrdf: boolean): void; /** * Set gamma levels: this affects the transparency and brightness of the single pass ray march volume render * @param {Object} volume * @param {number} gmin * @param {number} glevel * @param {number} gmax */ setGamma(volume: Volume, gmin: number, glevel: number, gmax: number): void; /** * Set max projection on or off - applies to single pass raymarch render mode only * @param {Object} volume * @param {boolean} isMaxProject true for max project, false for regular volume ray march integration */ setMaxProjectMode(volume: Volume, isMaxProject: boolean): void; /** * Notify the view that the set of active volume channels has been modified. * @param {Object} volume */ updateActiveChannels(_volume: Volume): void; /** * Notify the view that transfer function lookup table data has been modified. * @param {Object} volume */ updateLuts(_volume: Volume): void; /** * Notify the view that color and appearance settings have been modified. * @param {Object} volume */ updateMaterial(_volume: Volume): void; /** * Increase or decrease the overall brightness of the rendered image * @param {number} e 0..1 */ updateExposure(e: number): void; /** * Set camera focus properties. * @param {number} fov Vertical field of view in degrees * @param {number} focalDistance view-space units for center of focus * @param {number} apertureSize view-space units for radius of camera aperture */ updateCamera(fov: number, focalDistance: number, apertureSize: number): void; /** * Set clipping range (between 0 and 1, relative to bounds) for the current volume. * @param {Object} volume * @param {number} xmin 0..1, should be less than xmax * @param {number} xmax 0..1, should be greater than xmin * @param {number} ymin 0..1, should be less than ymax * @param {number} ymax 0..1, should be greater than ymin * @param {number} zmin 0..1, should be less than zmax * @param {number} zmax 0..1, should be greater than zmin */ updateClipRegion(volume: Volume, xmin: number, xmax: number, ymin: number, ymax: number, zmin: number, zmax: number): void; /** * Set clipping range (between 0 and 1) for a given axis. * Calling this allows the rendering to compensate for changes in thickness in orthographic views that affect how bright the volume is. * @param {Object} volume * @param {string} axis x, y, or z axis * @param {number} minval 0..1, should be less than maxval * @param {number} maxval 0..1, should be greater than minval * @param {boolean} isOrthoAxis is this an orthographic projection or just a clipping of the range for perspective view */ setAxisClip(volume: Volume, axis: "x" | "y" | "z", minval: number, maxval: number, isOrthoAxis: boolean): void; /** * Update lights * @param {Array} state array of Lights */ updateLights(state: Light[]): void; /** * Set a sampling rate to trade performance for quality. * @param {number} value (+epsilon..1) 1 is max quality, ~0.1 for lowest quality and highest speed */ updatePixelSamplingRate(value: number): void; /** * Set the opacity of the mask channel * @param {Object} volume * @param {number} value (0..1) 0 for full transparent, 1 for fully opaque */ updateMaskAlpha(volume: Volume, value: number): void; /** * Show / hide volume channels * @param {Object} volume * @param {number} channel * @param {boolean} enabled */ setVolumeChannelEnabled(volume: Volume, channel: number, enabled: boolean): void; /** * Set the material for a channel * @param {Object} volume * @param {number} channelIndex * @param {Array.} colorrgb [r,g,b] * @param {Array.} specularrgb [r,g,b] * @param {Array.} emissivergb [r,g,b] * @param {number} glossiness */ updateChannelMaterial(volume: Volume, channelIndex: number, colorrgb: [number, number, number], specularrgb: [number, number, number], emissivergb: [number, number, number], glossiness: number): void; /** * Set the color for a channel * @param {Object} volume * @param {number} channelIndex * @param {Array.} colorrgb [r,g,b] */ updateChannelColor(volume: Volume, channelIndex: number, colorrgb: [number, number, number]): void; /** * Switch between single pass ray-marched volume rendering and progressive path traced rendering. * @param {RenderMode} mode RAYMARCH for single pass ray march, PATHTRACE for progressive path trace */ setVolumeRenderMode(mode: RenderMode.PATHTRACE | RenderMode.RAYMARCH): void; /** * * @param {Object} volume * @param {Array.} xyz */ setVolumeTranslation(volume: Volume, xyz: [number, number, number]): void; /** * * @param {Object} volume * @param {Array.} eulerXYZ */ setVolumeRotation(volume: Volume, eulerXYZ: [number, number, number]): void; setVolumeScale(volume: Volume, xyz: [number, number, number]): void; /** * Reset the camera to its default position */ resetCamera(): void; hasWebGL2(): boolean; handleKeydown: (event: KeyboardEvent) => void; removeEventListeners(): void; private setupGui; }