/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2021, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a // license agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2021 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// import { EventEmitter2 } from "./EventEmitter2"; export interface RGB { red: number; green: number; blue: number; } /** * `VisualizeJS` parameters. */ export interface OptionsData { /** * Show WCS * * @defaultValue true */ showWCS?: boolean; /** * Enable camera animation * * @defaultValue true */ cameraAnimation?: boolean; /** * Enable antialiasing use FXAA * * @defaultValue true */ antialiasing?: boolean; /** * Enable ground shadows * * @defaultValue false */ groundShadow?: boolean; /** * Enable shadows * * @defaultValue false */ shadows?: boolean; /** * Camera speed on X axis * * @defaultValue 4 */ cameraAxisXSpeed?: number; /** * Camera speed on Y axis * * @defaultValue 1 */ cameraAxisYSpeed?: number; /** * Ambient occlusion * * @defaultValue false */ ambientOcclusion?: boolean; /** * Enable partial load mode to be able open large drawing If enablePartialMode enabled, then * sceneGraph will be switched off * * @defaultValue false */ enablePartialMode?: boolean; /** * The size of the memory buffer that the Viewer can use for graphics data * * @defaultValue 3294967296 */ memoryLimit?: number; /** * Cutting plane fill color * * @defaultValue { red: 0xff, green: 0x98, blue: 0x00 } */ cuttingPlaneFillColor?: RGB; /** * Outline edges color in RGB format. */ edgesColor?: { r: number; g: number; b: number }; /** * Faces color in the RGB format. */ facesColor?: { r: number; g: number; b: number }; /** * Show or hide edges. */ edgesVisibility?: boolean; /** * Show edges over drawing. */ edgesOverlap?: boolean; /** * Show faces over drawing. */ facesOverlap?: boolean; /** * Faces transparency value from 0 to 255. */ facesTransparancy?: number; /** * Enable custom highlight settings. */ enableCustomHighlight?: boolean; /** * Enable or disable scene graph, it increases perfomance improvement, but consumes memory * Large drawings can take up a lot of memory. If sceneGraph enabled, then enablePartialMode * will be switched off */ sceneGraph: boolean; /** * Edge display models. No edges is usefull for less memory consumption: `false` - no edges * are displayed, `true` - display isolines. */ edgeModel: boolean; /** * Reverse the mouse wheel direction for zooming: false - moving the wheel up zooms in, * moving down zooms out, `true` - moving the wheel up zooms out, moving down zooms in. */ reverseZoomWheel: boolean; /** * Enable mouse wheel zooming. */ enableZoomWheel: boolean; /** * Enable touch gestures. This option will be ignored when enableZoomWheel is disabled, since * gestures contains touch zoom. */ enableGestures: boolean; /** * Default file geometry data type. Can be one of: * * - `vsfx` - `VSFX` (default), for opening a file in `VisualizeJS` viewer. * - `gltf` - `glTF`, for opening a file in `Three.js` viewer. */ geometryType?: string; } export class Options { protected _emitter?: EventEmitter2; protected _data: OptionsData; constructor(emitter?: EventEmitter2) { this._emitter = emitter; this._data = Options.defaults(); this.loadFromStorage(); } static defaults(): OptionsData { return { showWCS: true, cameraAnimation: true, antialiasing: true, groundShadow: false, shadows: false, cameraAxisXSpeed: 4, cameraAxisYSpeed: 1, ambientOcclusion: false, enablePartialMode: false, memoryLimit: 3294967296, cuttingPlaneFillColor: { red: 0xff, green: 0x98, blue: 0x00 }, edgesColor: { r: 0xff, g: 0x98, b: 0x00 }, facesColor: { r: 0xff, g: 0x98, b: 0x00 }, edgesVisibility: true, edgesOverlap: true, facesOverlap: false, facesTransparancy: 200, enableCustomHighlight: true, sceneGraph: false, edgeModel: true, reverseZoomWheel: false, enableZoomWheel: true, enableGestures: true, geometryType: "vsfx", }; } notifierChangeEvent(): void { if (this._emitter !== undefined) { this.saveToStorage(); this._emitter.emit({ type: "optionschange", data: this }); } } saveToStorage(): void { if (typeof window !== "undefined") try { localStorage.setItem("od-client-settings", JSON.stringify(this.data)); } catch (error) { console.error("Cannot save client settings.", error); } } loadFromStorage(): void { if (typeof window !== "undefined") try { const item = localStorage.getItem("od-client-settings"); if (item) { const data = JSON.parse(item); this.data = { ...data }; } } catch (error) { console.error("Cannot load client settings.", error); } } /** * Reset options to default * * @param fields - Name of fields to be reset */ resetToDefaults(fields?: string[]): void { if (fields !== undefined) { const defaults = Options.defaults(); const resetData = fields.reduce((acc, field) => { acc[field] = defaults[field]; return acc; }, {}); this.data = { ...this.data, ...resetData }; } else { this.data = { ...this.data, ...Options.defaults() }; } } get data(): OptionsData { return this._data; } set data(value: OptionsData) { const sceneGraph = value.enablePartialMode ? false : value.sceneGraph; this._data = { ...Options.defaults(), ...this._data, ...value, sceneGraph }; this.notifierChangeEvent(); } get showWCS(): boolean { return this._data.showWCS; } set showWCS(value: boolean) { this._data.showWCS = value; this.notifierChangeEvent(); } get cameraAnimation(): boolean { return this._data.cameraAnimation; } set cameraAnimation(value: boolean) { this._data.cameraAnimation = value; this.notifierChangeEvent(); } get antialiasing(): boolean { return this._data.antialiasing; } set antialiasing(value: boolean) { this._data.antialiasing = value; this.notifierChangeEvent(); } get groundShadow(): boolean { return this._data.groundShadow; } set groundShadow(value: boolean) { this._data.groundShadow = value; this.notifierChangeEvent(); } get shadows(): boolean { return this._data.shadows; } set shadows(value: boolean) { this._data.shadows = value; this.notifierChangeEvent(); } get cameraAxisXSpeed(): number { return this._data.cameraAxisXSpeed; } set cameraAxisXSpeed(value: number) { this._data.cameraAxisXSpeed = value; this.notifierChangeEvent(); } get cameraAxisYSpeed(): number { return this._data.cameraAxisYSpeed; } set cameraAxisYSpeed(value: number) { this.cameraAxisYSpeed = value; this.notifierChangeEvent(); } get ambientOcclusion(): boolean { return this._data.ambientOcclusion; } set ambientOcclusion(value: boolean) { this._data.ambientOcclusion = value; this.notifierChangeEvent(); } get enablePartialMode(): boolean { return this._data.enablePartialMode; } set enablePartialMode(value: boolean) { this._data.enablePartialMode = value; if (value) this._data.sceneGraph = false; this.notifierChangeEvent(); } get memoryLimit(): number { return this._data.memoryLimit; } set memoryLimit(value: number) { this._data.memoryLimit = value; this.notifierChangeEvent(); } get cuttingPlaneFillColor(): RGB { return this._data.cuttingPlaneFillColor; } set cuttingPlaneFillColor(value: RGB) { this._data.cuttingPlaneFillColor = value; this.notifierChangeEvent(); } get edgesColor() { return this._data.edgesColor; } set edgesColor(value) { this._data.edgesColor = value; this.notifierChangeEvent(); } get facesColor() { return this._data.facesColor; } set facesColor(value) { this._data.facesColor = value; this.notifierChangeEvent(); } get edgesVisibility() { return this._data.edgesVisibility; } set edgesVisibility(value) { this._data.edgesVisibility = value; this.notifierChangeEvent(); } get edgesOverlap() { return this._data.edgesOverlap; } set edgesOverlap(value) { this._data.edgesOverlap = value; this.notifierChangeEvent(); } get facesOverlap() { return this._data.facesOverlap; } set facesOverlap(value) { this._data.facesOverlap = value; this.notifierChangeEvent(); } get facesTransparancy() { return this._data.facesTransparancy; } set facesTransparancy(value) { this._data.facesTransparancy = value; this.notifierChangeEvent(); } get enableCustomHighlight() { return this._data.enableCustomHighlight; } set enableCustomHighlight(value) { this._data.enableCustomHighlight = value; this.notifierChangeEvent(); } get sceneGraph() { return this._data.sceneGraph; } set sceneGraph(value) { this._data.sceneGraph = value; if (value) this._data.enablePartialMode = false; this.notifierChangeEvent(); } get edgeModel() { return Boolean(this._data.edgeModel); } set edgeModel(value) { this._data.edgeModel = Boolean(value); this.notifierChangeEvent(); } get reverseZoomWheel() { return this._data.reverseZoomWheel; } set reverseZoomWheel(value: boolean) { this._data.reverseZoomWheel = !!value; this.notifierChangeEvent(); } get enableZoomWheel() { return this._data.enableZoomWheel; } set enableZoomWheel(value: boolean) { this._data.enableZoomWheel = !!value; this.notifierChangeEvent(); } get enableGestures() { return this._data.enableGestures; } set enableGestures(value: boolean) { this._data.enableGestures = !!value; this.notifierChangeEvent(); } get geometryType() { return this._data.geometryType; } set geometryType(value: string) { this._data.geometryType = value; this.notifierChangeEvent(); } }