UNPKG

@sauskylark/potree

Version:

WebGL point cloud viewer

932 lines (753 loc) 29.2 kB
import * as THREE from "../../../libs/three.js/build/three.module.js"; import {Utils} from "../../utils.js"; import {PointCloudTree} from "../../PointCloudTree.js"; import {Annotation} from "../../Annotation.js"; import {Measure} from "../../utils/Measure.js"; import {Profile} from "../../utils/Profile.js"; import {Volume, BoxVolume, SphereVolume} from "../../utils/Volume.js"; import {CameraAnimation} from "../../modules/CameraAnimation/CameraAnimation.js"; import {PointSizeType, PointShape, ElevationGradientRepeat} from "../../defines.js"; import {Gradients} from "../../materials/Gradients.js"; import {MeasurePanel} from "./MeasurePanel.js"; import {DistancePanel} from "./DistancePanel.js"; import {PointPanel} from "./PointPanel.js"; import {AreaPanel} from "./AreaPanel.js"; import {AnglePanel} from "./AnglePanel.js"; import {CirclePanel} from "./CirclePanel.js"; import {HeightPanel} from "./HeightPanel.js"; import {VolumePanel} from "./VolumePanel.js"; import {ProfilePanel} from "./ProfilePanel.js"; import {CameraPanel} from "./CameraPanel.js"; import {AnnotationPanel} from "./AnnotationPanel.js"; import { CameraAnimationPanel } from "./CameraAnimationPanel.js"; export class PropertiesPanel{ constructor(container, viewer){ this.container = container; this.viewer = viewer; this.object = null; this.cleanupTasks = []; this.scene = null; } setScene(scene){ this.scene = scene; } set(object){ if(this.object === object){ return; } this.object = object; for(let task of this.cleanupTasks){ task(); } this.cleanupTasks = []; this.container.empty(); if(object instanceof PointCloudTree){ this.setPointCloud(object); }else if(object instanceof Measure || object instanceof Profile || object instanceof Volume){ this.setMeasurement(object); }else if(object instanceof THREE.Camera){ this.setCamera(object); }else if(object instanceof Annotation){ this.setAnnotation(object); }else if(object instanceof CameraAnimation){ this.setCameraAnimation(object); } } // // Used for events that should be removed when the property object changes. // This is for listening to materials, scene, point clouds, etc. // not required for DOM listeners, since they are automatically cleared by removing the DOM subtree. // addVolatileListener(target, type, callback){ target.addEventListener(type, callback); this.cleanupTasks.push(() => { target.removeEventListener(type, callback); }); } setPointCloud(pointcloud){ let material = pointcloud.material; let panel = $(` <div class="scene_content selectable"> <ul class="pv-menu-list"> <li> <span data-i18n="appearance.point_size"></span>:&nbsp;<span id="lblPointSize"></span> <div id="sldPointSize"></div> </li> <li> <span data-i18n="appearance.min_point_size"></span>:&nbsp;<span id="lblMinPointSize"></span> <div id="sldMinPointSize"></div> </li> <!-- SIZE TYPE --> <li> <label for="optPointSizing" class="pv-select-label" data-i18n="appearance.point_size_type">Point Sizing </label> <select id="optPointSizing" name="optPointSizing"> <option>FIXED</option> <option>ATTENUATED</option> <option>ADAPTIVE</option> </select> </li> <!-- SHAPE --> <li> <label for="optShape" class="pv-select-label" data-i18n="appearance.point_shape"></label><br> <select id="optShape" name="optShape"> <option>SQUARE</option> <option>CIRCLE</option> <option>PARABOLOID</option> </select> </li> <li id="materials_backface_container"> <label><input id="set_backface_culling" type="checkbox" /><span data-i18n="appearance.backface_culling"></span></label> </li> <!-- OPACITY --> <li><span data-i18n="appearance.point_opacity"></span>:<span id="lblOpacity"></span><div id="sldOpacity"></div></li> <div class="divider"> <span>Attribute</span> </div> <li> <select id="optMaterial" name="optMaterial"></select> </li> <div id="materials.composite_weight_container"> <div class="divider"> <span>Attribute Weights</span> </div> <li>RGB: <span id="lblWeightRGB"></span> <div id="sldWeightRGB"></div> </li> <li>Intensity: <span id="lblWeightIntensity"></span> <div id="sldWeightIntensity"></div> </li> <li>Elevation: <span id="lblWeightElevation"></span> <div id="sldWeightElevation"></div> </li> <li>Classification: <span id="lblWeightClassification"></span> <div id="sldWeightClassification"></div> </li> <li>Return Number: <span id="lblWeightReturnNumber"></span> <div id="sldWeightReturnNumber"></div> </li> <li>Source ID: <span id="lblWeightSourceID"></span> <div id="sldWeightSourceID"></div> </li> </div> <div id="materials.rgb_container"> <div class="divider"> <span>RGB</span> </div> <li>Gamma: <span id="lblRGBGamma"></span> <div id="sldRGBGamma"></div> </li> <li>Brightness: <span id="lblRGBBrightness"></span> <div id="sldRGBBrightness"></div> </li> <li>Contrast: <span id="lblRGBContrast"></span> <div id="sldRGBContrast"></div> </li> </div> <div id="materials.extra_container"> <div class="divider"> <span>Extra Attribute</span> </div> <li><span data-i18n="appearance.extra_range"></span>: <span id="lblExtraRange"></span> <div id="sldExtraRange"></div></li> <li>Gamma: <span id="lblExtraGamma"></span> <div id="sldExtraGamma"></div></li> <li>Brightness: <span id="lblExtraBrightness"></span> <div id="sldExtraBrightness"></div></li> <li>Contrast: <span id="lblExtraContrast"></span> <div id="sldExtraContrast"></div></li> </div> <div id="materials.matcap_container"> <div class="divider"> <span>MATCAP</span> </div> <li> <div id="matcap_scheme_selection" style="display: flex; flex-wrap: wrap;"> </div> </li> </div> <div id="materials.color_container"> <div class="divider"> <span>Color</span> </div> <input id="materials.color.picker" /> </div> <div id="materials.elevation_container"> <div class="divider"> <span>Elevation</span> </div> <li><span data-i18n="appearance.elevation_range"></span>: <span id="lblHeightRange"></span> <div id="sldHeightRange"></div> </li> <li> <selectgroup id="gradient_repeat_option"> <option id="gradient_repeat_clamp" value="CLAMP">Clamp</option> <option id="gradient_repeat_repeat" value="REPEAT">Repeat</option> <option id="gradient_repeat_mirrored_repeat" value="MIRRORED_REPEAT">Mirrored Repeat</option> </selectgroup> </li> <li> <span>Gradient Scheme:</span> <div id="elevation_gradient_scheme_selection" style="display: flex; padding: 1em 0em"> </div> </li> </div> <div id="materials.transition_container"> <div class="divider"> <span>Transition</span> </div> <li>transition: <span id="lblTransition"></span> <div id="sldTransition"></div> </li> </div> <div id="materials.intensity_container"> <div class="divider"> <span>Intensity</span> </div> <li>Range: <span id="lblIntensityRange"></span> <div id="sldIntensityRange"></div> </li> <li>Gamma: <span id="lblIntensityGamma"></span> <div id="sldIntensityGamma"></div> </li> <li>Brightness: <span id="lblIntensityBrightness"></span> <div id="sldIntensityBrightness"></div> </li> <li>Contrast: <span id="lblIntensityContrast"></span> <div id="sldIntensityContrast"></div> </li> </div> <div id="materials.gpstime_container"> <div class="divider"> <span>GPS Time</span> </div> </div> <div id="materials.index_container"> <div class="divider"> <span>Indices</span> </div> </div> </ul> </div> `); panel.i18n(); this.container.append(panel); { // POINT SIZE let sldPointSize = panel.find(`#sldPointSize`); let lblPointSize = panel.find(`#lblPointSize`); sldPointSize.slider({ value: material.size, min: 0, max: 3, step: 0.01, slide: function (event, ui) { material.size = ui.value; } }); let update = (e) => { lblPointSize.html(material.size.toFixed(2)); sldPointSize.slider({value: material.size}); }; this.addVolatileListener(material, "point_size_changed", update); update(); } { // MINIMUM POINT SIZE let sldMinPointSize = panel.find(`#sldMinPointSize`); let lblMinPointSize = panel.find(`#lblMinPointSize`); sldMinPointSize.slider({ value: material.size, min: 0, max: 3, step: 0.01, slide: function (event, ui) { material.minSize = ui.value; } }); let update = (e) => { lblMinPointSize.html(material.minSize.toFixed(2)); sldMinPointSize.slider({value: material.minSize}); }; this.addVolatileListener(material, "point_size_changed", update); update(); } { // POINT SIZING let strSizeType = Object.keys(PointSizeType)[material.pointSizeType]; let opt = panel.find(`#optPointSizing`); opt.selectmenu(); opt.val(strSizeType).selectmenu('refresh'); opt.selectmenu({ change: (event, ui) => { material.pointSizeType = PointSizeType[ui.item.value]; } }); } { // SHAPE let opt = panel.find(`#optShape`); opt.selectmenu({ change: (event, ui) => { let value = ui.item.value; material.shape = PointShape[value]; } }); let update = () => { let typename = Object.keys(PointShape)[material.shape]; opt.selectmenu().val(typename).selectmenu('refresh'); }; this.addVolatileListener(material, "point_shape_changed", update); update(); } { // BACKFACE CULLING let opt = panel.find(`#set_backface_culling`); opt.click(() => { material.backfaceCulling = opt.prop("checked"); }); let update = () => { let value = material.backfaceCulling; opt.prop("checked", value); }; this.addVolatileListener(material, "backface_changed", update); update(); let blockBackface = $('#materials_backface_container'); blockBackface.css('display', 'none'); const pointAttributes = pointcloud.pcoGeometry.pointAttributes; const hasNormals = pointAttributes.hasNormals ? pointAttributes.hasNormals() : false; if(hasNormals) { blockBackface.css('display', 'block'); } /* opt.checkboxradio({ clicked: (event, ui) => { // let value = ui.item.value; let value = ui.item.checked; console.log(value); material.backfaceCulling = value; // $('#set_freeze').prop("checked"); } }); */ } { // OPACITY let sldOpacity = panel.find(`#sldOpacity`); let lblOpacity = panel.find(`#lblOpacity`); sldOpacity.slider({ value: material.opacity, min: 0, max: 1, step: 0.001, slide: function (event, ui) { material.opacity = ui.value; } }); let update = (e) => { lblOpacity.html(material.opacity.toFixed(2)); sldOpacity.slider({value: material.opacity}); }; this.addVolatileListener(material, "opacity_changed", update); update(); } { const attributes = pointcloud.pcoGeometry.pointAttributes.attributes; let options = []; options.push(...attributes.map(a => a.name)); const intensityIndex = options.indexOf("intensity"); if(intensityIndex >= 0){ options.splice(intensityIndex + 1, 0, "intensity gradient"); } options.push( "elevation", "color", 'matcap', 'indices', 'level of detail', 'composite' ); const blacklist = [ "POSITION_CARTESIAN", "position", ]; options = options.filter(o => !blacklist.includes(o)); let attributeSelection = panel.find('#optMaterial'); for(let option of options){ let elOption = $(`<option>${option}</option>`); attributeSelection.append(elOption); } let updateMaterialPanel = (event, ui) => { let selectedValue = attributeSelection.selectmenu().val(); material.activeAttributeName = selectedValue; let attribute = pointcloud.getAttribute(selectedValue); if(selectedValue === "intensity gradient"){ attribute = pointcloud.getAttribute("intensity"); } const isIntensity = attribute ? ["intensity", "intensity gradient"].includes(attribute.name) : false; if(isIntensity){ if(pointcloud.material.intensityRange[0] === Infinity){ pointcloud.material.intensityRange = attribute.range; } const [min, max] = attribute.range; panel.find('#sldIntensityRange').slider({ range: true, min: min, max: max, step: 0.01, values: [min, max], slide: (event, ui) => { let min = ui.values[0]; let max = ui.values[1]; material.intensityRange = [min, max]; } }); } else if(attribute){ const [min, max] = attribute.range; let selectedRange = material.getRange(attribute.name); if(!selectedRange){ selectedRange = [...attribute.range]; } let minMaxAreNumbers = typeof min === "number" && typeof max === "number"; if(minMaxAreNumbers){ panel.find('#sldExtraRange').slider({ range: true, min: min, max: max, step: 0.01, values: selectedRange, slide: (event, ui) => { let [a, b] = ui.values; material.setRange(attribute.name, [a, b]); } }); } } let blockWeights = $('#materials\\.composite_weight_container'); let blockElevation = $('#materials\\.elevation_container'); let blockRGB = $('#materials\\.rgb_container'); let blockExtra = $('#materials\\.extra_container'); let blockColor = $('#materials\\.color_container'); let blockIntensity = $('#materials\\.intensity_container'); let blockIndex = $('#materials\\.index_container'); let blockTransition = $('#materials\\.transition_container'); let blockGps = $('#materials\\.gpstime_container'); let blockMatcap = $('#materials\\.matcap_container'); blockIndex.css('display', 'none'); blockIntensity.css('display', 'none'); blockElevation.css('display', 'none'); blockRGB.css('display', 'none'); blockExtra.css('display', 'none'); blockColor.css('display', 'none'); blockWeights.css('display', 'none'); blockTransition.css('display', 'none'); blockMatcap.css('display', 'none'); blockGps.css('display', 'none'); if (selectedValue === 'composite') { blockWeights.css('display', 'block'); blockElevation.css('display', 'block'); blockRGB.css('display', 'block'); blockIntensity.css('display', 'block'); } else if (selectedValue === 'elevation') { blockElevation.css('display', 'block'); } else if (selectedValue === 'RGB and Elevation') { blockRGB.css('display', 'block'); blockElevation.css('display', 'block'); } else if (selectedValue === 'rgba') { blockRGB.css('display', 'block'); } else if (selectedValue === 'color') { blockColor.css('display', 'block'); } else if (selectedValue === 'intensity') { blockIntensity.css('display', 'block'); } else if (selectedValue === 'intensity gradient') { blockIntensity.css('display', 'block'); } else if (selectedValue === "indices" ){ blockIndex.css('display', 'block'); } else if (selectedValue === "matcap" ){ blockMatcap.css('display', 'block'); } else if (selectedValue === "classification" ){ // add classification color selctor? } else if (selectedValue === "gps-time" ){ blockGps.css('display', 'block'); } else if(selectedValue === "number of returns"){ } else if(selectedValue === "return number"){ } else if(["source id", "point source id"].includes(selectedValue)){ } else{ blockExtra.css('display', 'block'); } }; attributeSelection.selectmenu({change: updateMaterialPanel}); let update = () => { attributeSelection.val(material.activeAttributeName).selectmenu('refresh'); }; this.addVolatileListener(material, "point_color_type_changed", update); this.addVolatileListener(material, "active_attribute_changed", update); update(); updateMaterialPanel(); } { const schemes = Object.keys(Potree.Gradients).map(name => ({name: name, values: Gradients[name]})); let elSchemeContainer = panel.find("#elevation_gradient_scheme_selection"); for(let scheme of schemes){ let elScheme = $(` <span style="flex-grow: 1;"> </span> `); const svg = Potree.Utils.createSvgGradient(scheme.values); svg.setAttributeNS(null, "class", `button-icon`); elScheme.append($(svg)); elScheme.click( () => { material.gradient = Gradients[scheme.name]; }); elSchemeContainer.append(elScheme); } } { let matcaps = [ {name: "Normals", icon: `${Potree.resourcePath}/icons/matcap/check_normal+y.jpg`}, {name: "Basic 1", icon: `${Potree.resourcePath}/icons/matcap/basic_1.jpg`}, {name: "Basic 2", icon: `${Potree.resourcePath}/icons/matcap/basic_2.jpg`}, {name: "Basic Dark", icon: `${Potree.resourcePath}/icons/matcap/basic_dark.jpg`}, {name: "Basic Side", icon: `${Potree.resourcePath}/icons/matcap/basic_side.jpg`}, {name: "Ceramic Dark", icon: `${Potree.resourcePath}/icons/matcap/ceramic_dark.jpg`}, {name: "Ceramic Lightbulb", icon: `${Potree.resourcePath}/icons/matcap/ceramic_lightbulb.jpg`}, {name: "Clay Brown", icon: `${Potree.resourcePath}/icons/matcap/clay_brown.jpg`}, {name: "Clay Muddy", icon: `${Potree.resourcePath}/icons/matcap/clay_muddy.jpg`}, {name: "Clay Studio", icon: `${Potree.resourcePath}/icons/matcap/clay_studio.jpg`}, {name: "Resin", icon: `${Potree.resourcePath}/icons/matcap/resin.jpg`}, {name: "Skin", icon: `${Potree.resourcePath}/icons/matcap/skin.jpg`}, {name: "Jade", icon: `${Potree.resourcePath}/icons/matcap/jade.jpg`}, {name: "Metal_ Anisotropic", icon: `${Potree.resourcePath}/icons/matcap/metal_anisotropic.jpg`}, {name: "Metal Carpaint", icon: `${Potree.resourcePath}/icons/matcap/metal_carpaint.jpg`}, {name: "Metal Lead", icon: `${Potree.resourcePath}/icons/matcap/metal_lead.jpg`}, {name: "Metal Shiny", icon: `${Potree.resourcePath}/icons/matcap/metal_shiny.jpg`}, {name: "Pearl", icon: `${Potree.resourcePath}/icons/matcap/pearl.jpg`}, {name: "Toon", icon: `${Potree.resourcePath}/icons/matcap/toon.jpg`}, {name: "Check Rim Light", icon: `${Potree.resourcePath}/icons/matcap/check_rim_light.jpg`}, {name: "Check Rim Dark", icon: `${Potree.resourcePath}/icons/matcap/check_rim_dark.jpg`}, {name: "Contours 1", icon: `${Potree.resourcePath}/icons/matcap/contours_1.jpg`}, {name: "Contours 2", icon: `${Potree.resourcePath}/icons/matcap/contours_2.jpg`}, {name: "Contours 3", icon: `${Potree.resourcePath}/icons/matcap/contours_3.jpg`}, {name: "Reflection Check Horizontal", icon: `${Potree.resourcePath}/icons/matcap/reflection_check_horizontal.jpg`}, {name: "Reflection Check Vertical", icon: `${Potree.resourcePath}/icons/matcap/reflection_check_vertical.jpg`}, ]; let elMatcapContainer = panel.find("#matcap_scheme_selection"); for(let matcap of matcaps){ let elMatcap = $(` <img src="${matcap.icon}" class="button-icon" style="width: 25%;" /> `); elMatcap.click( () => { material.matcap = matcap.icon.substring(matcap.icon.lastIndexOf('/')); }); elMatcapContainer.append(elMatcap); } } { panel.find('#sldRGBGamma').slider({ value: material.rgbGamma, min: 0, max: 4, step: 0.01, slide: (event, ui) => {material.rgbGamma = ui.value} }); panel.find('#sldRGBContrast').slider({ value: material.rgbContrast, min: -1, max: 1, step: 0.01, slide: (event, ui) => {material.rgbContrast = ui.value} }); panel.find('#sldRGBBrightness').slider({ value: material.rgbBrightness, min: -1, max: 1, step: 0.01, slide: (event, ui) => {material.rgbBrightness = ui.value} }); panel.find('#sldExtraGamma').slider({ value: material.extraGamma, min: 0, max: 4, step: 0.01, slide: (event, ui) => {material.extraGamma = ui.value} }); panel.find('#sldExtraBrightness').slider({ value: material.extraBrightness, min: -1, max: 1, step: 0.01, slide: (event, ui) => {material.extraBrightness = ui.value} }); panel.find('#sldExtraContrast').slider({ value: material.extraContrast, min: -1, max: 1, step: 0.01, slide: (event, ui) => {material.extraContrast = ui.value} }); panel.find('#sldHeightRange').slider({ range: true, min: 0, max: 1000, step: 0.01, values: [0, 1000], slide: (event, ui) => { material.heightMin = ui.values[0]; material.heightMax = ui.values[1]; } }); panel.find('#sldIntensityGamma').slider({ value: material.intensityGamma, min: 0, max: 4, step: 0.01, slide: (event, ui) => {material.intensityGamma = ui.value} }); panel.find('#sldIntensityContrast').slider({ value: material.intensityContrast, min: -1, max: 1, step: 0.01, slide: (event, ui) => {material.intensityContrast = ui.value} }); panel.find('#sldIntensityBrightness').slider({ value: material.intensityBrightness, min: -1, max: 1, step: 0.01, slide: (event, ui) => {material.intensityBrightness = ui.value} }); panel.find('#sldWeightRGB').slider({ value: material.weightRGB, min: 0, max: 1, step: 0.01, slide: (event, ui) => {material.weightRGB = ui.value} }); panel.find('#sldWeightIntensity').slider({ value: material.weightIntensity, min: 0, max: 1, step: 0.01, slide: (event, ui) => {material.weightIntensity = ui.value} }); panel.find('#sldWeightElevation').slider({ value: material.weightElevation, min: 0, max: 1, step: 0.01, slide: (event, ui) => {material.weightElevation = ui.value} }); panel.find('#sldWeightClassification').slider({ value: material.weightClassification, min: 0, max: 1, step: 0.01, slide: (event, ui) => {material.weightClassification = ui.value} }); panel.find('#sldWeightReturnNumber').slider({ value: material.weightReturnNumber, min: 0, max: 1, step: 0.01, slide: (event, ui) => {material.weightReturnNumber = ui.value} }); panel.find('#sldWeightSourceID').slider({ value: material.weightSourceID, min: 0, max: 1, step: 0.01, slide: (event, ui) => {material.weightSourceID = ui.value} }); panel.find(`#materials\\.color\\.picker`).spectrum({ flat: true, showInput: true, preferredFormat: 'rgb', cancelText: '', chooseText: 'Apply', color: `#${material.color.getHexString()}`, move: color => { let cRGB = color.toRgb(); let tc = new THREE.Color().setRGB(cRGB.r / 255, cRGB.g / 255, cRGB.b / 255); material.color = tc; }, change: color => { let cRGB = color.toRgb(); let tc = new THREE.Color().setRGB(cRGB.r / 255, cRGB.g / 255, cRGB.b / 255); material.color = tc; } }); this.addVolatileListener(material, "color_changed", () => { panel.find(`#materials\\.color\\.picker`) .spectrum('set', `#${material.color.getHexString()}`); }); let updateHeightRange = function () { let aPosition = pointcloud.getAttribute("position"); let bMin, bMax; if(aPosition){ // for new format 2.0 and loader that contain precomputed min/max of attributes let min = aPosition.range[0][2]; let max = aPosition.range[1][2]; let width = max - min; bMin = min - 0.2 * width; bMax = max + 0.2 * width; }else{ // for format up until exlusive 2.0 let box = [pointcloud.pcoGeometry.tightBoundingBox, pointcloud.getBoundingBoxWorld()] .find(v => v !== undefined); pointcloud.updateMatrixWorld(true); box = Utils.computeTransformedBoundingBox(box, pointcloud.matrixWorld); let bWidth = box.max.z - box.min.z; bMin = box.min.z - 0.2 * bWidth; bMax = box.max.z + 0.2 * bWidth; } let range = material.elevationRange; panel.find('#lblHeightRange').html(`${range[0].toFixed(2)} to ${range[1].toFixed(2)}`); panel.find('#sldHeightRange').slider({min: bMin, max: bMax, values: range}); }; let updateExtraRange = function () { let attributeName = material.activeAttributeName; let attribute = pointcloud.getAttribute(attributeName); if(attribute == null){ return; } let range = material.getRange(attributeName); if(range == null){ range = attribute.range; } // currently only supporting scalar ranges. // rgba, normals, positions, etc have vector ranges, however let isValidRange = (typeof range[0] === "number") && (typeof range[1] === "number"); if(!isValidRange){ return; } if(range){ let msg = `${range[0].toFixed(2)} to ${range[1].toFixed(2)}`; panel.find('#lblExtraRange').html(msg); }else{ panel.find("could not deduce range"); } }; let updateIntensityRange = function () { let range = material.intensityRange; panel.find('#lblIntensityRange').html(`${parseInt(range[0])} to ${parseInt(range[1])}`); }; { updateHeightRange(); panel.find(`#sldHeightRange`).slider('option', 'min'); panel.find(`#sldHeightRange`).slider('option', 'max'); } { let elGradientRepeat = panel.find("#gradient_repeat_option"); elGradientRepeat.selectgroup({title: "Gradient"}); elGradientRepeat.find("input").click( (e) => { this.viewer.setElevationGradientRepeat(ElevationGradientRepeat[e.target.value]); }); let current = Object.keys(ElevationGradientRepeat) .filter(key => ElevationGradientRepeat[key] === this.viewer.elevationGradientRepeat); elGradientRepeat.find(`input[value=${current}]`).trigger("click"); } let onIntensityChange = () => { let gamma = material.intensityGamma; let contrast = material.intensityContrast; let brightness = material.intensityBrightness; updateIntensityRange(); panel.find('#lblIntensityGamma').html(gamma.toFixed(2)); panel.find('#lblIntensityContrast').html(contrast.toFixed(2)); panel.find('#lblIntensityBrightness').html(brightness.toFixed(2)); panel.find('#sldIntensityGamma').slider({value: gamma}); panel.find('#sldIntensityContrast').slider({value: contrast}); panel.find('#sldIntensityBrightness').slider({value: brightness}); }; let onRGBChange = () => { let gamma = material.rgbGamma; let contrast = material.rgbContrast; let brightness = material.rgbBrightness; panel.find('#lblRGBGamma').html(gamma.toFixed(2)); panel.find('#lblRGBContrast').html(contrast.toFixed(2)); panel.find('#lblRGBBrightness').html(brightness.toFixed(2)); panel.find('#sldRGBGamma').slider({value: gamma}); panel.find('#sldRGBContrast').slider({value: contrast}); panel.find('#sldRGBBrightness').slider({value: brightness}); }; this.addVolatileListener(material, "material_property_changed", updateExtraRange); this.addVolatileListener(material, "material_property_changed", updateHeightRange); this.addVolatileListener(material, "material_property_changed", onIntensityChange); this.addVolatileListener(material, "material_property_changed", onRGBChange); updateExtraRange(); updateHeightRange(); onIntensityChange(); onRGBChange(); } } setMeasurement(object){ let TYPE = { DISTANCE: {panel: DistancePanel}, AREA: {panel: AreaPanel}, POINT: {panel: PointPanel}, ANGLE: {panel: AnglePanel}, HEIGHT: {panel: HeightPanel}, PROFILE: {panel: ProfilePanel}, VOLUME: {panel: VolumePanel}, CIRCLE: {panel: CirclePanel}, OTHER: {panel: PointPanel}, }; let getType = (measurement) => { if (measurement instanceof Measure) { if (measurement.showDistances && !measurement.showArea && !measurement.showAngles) { return TYPE.DISTANCE; } else if (measurement.showDistances && measurement.showArea && !measurement.showAngles) { return TYPE.AREA; } else if (measurement.maxMarkers === 1) { return TYPE.POINT; } else if (!measurement.showDistances && !measurement.showArea && measurement.showAngles) { return TYPE.ANGLE; } else if (measurement.showHeight) { return TYPE.HEIGHT; } else if (measurement.showCircle) { return TYPE.CIRCLE; } else { return TYPE.OTHER; } } else if (measurement instanceof Profile) { return TYPE.PROFILE; } else if (measurement instanceof Volume) { return TYPE.VOLUME; } }; //this.container.html("measurement"); let type = getType(object); let Panel = type.panel; let panel = new Panel(this.viewer, object, this); this.container.append(panel.elContent); } setCamera(camera){ let panel = new CameraPanel(this.viewer, this); this.container.append(panel.elContent); } setAnnotation(annotation){ let panel = new AnnotationPanel(this.viewer, this, annotation); this.container.append(panel.elContent); } setCameraAnimation(animation){ let panel = new CameraAnimationPanel(this.viewer, this, animation) this.container.append(panel.elContent); } }