@sauskylark/potree
Version:
WebGL point cloud viewer
932 lines (753 loc) • 29.2 kB
JavaScript
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>: <span id="lblPointSize"></span> <div id="sldPointSize"></div>
</li>
<li>
<span data-i18n="appearance.min_point_size"></span>: <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);
}
}