UNPKG

molstar

Version:

A comprehensive macromolecular library.

334 lines (333 loc) 17.9 kB
/** * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { Loci, isEmptyLoci, isEveryLoci, EveryLoci } from '../mol-model/loci'; import { applyMarkerAction, getMarkerInfo, setMarkerValue, getPartialMarkerAverage, MarkerActions } from '../mol-util/marker-action'; import { Mat4 } from '../mol-math/linear-algebra'; import { updateTransformData, fillIdentityTransform } from '../mol-geo/geometry/transform-data'; import { calculateTransformBoundingSphere } from '../mol-gl/renderable/util'; import { ValueCell } from '../mol-util'; import { createOverpaint, clearOverpaint, applyOverpaintColor } from '../mol-geo/geometry/overpaint-data'; import { Interval } from '../mol-data/int'; import { createTransparency, clearTransparency, applyTransparencyValue, getTransparencyAverage } from '../mol-geo/geometry/transparency-data'; import { createClipping, applyClippingGroups, clearClipping } from '../mol-geo/geometry/clipping-data'; import { getMarkersAverage } from '../mol-geo/geometry/marker-data'; import { getColorSmoothingProps, hasColorSmoothingProp } from '../mol-geo/geometry/base'; import { applyMeshOverpaintSmoothing, applyMeshSubstanceSmoothing, applyMeshTransparencySmoothing } from '../mol-geo/geometry/mesh/color-smoothing'; import { applyTextureMeshOverpaintSmoothing, applyTextureMeshSubstanceSmoothing, applyTextureMeshTransparencySmoothing } from '../mol-geo/geometry/texture-mesh/color-smoothing'; import { applySubstanceMaterial, clearSubstance, createSubstance } from '../mol-geo/geometry/substance-data'; export { Visual }; var Visual; (function (Visual) { function setVisibility(renderObject, visible) { if (renderObject) renderObject.state.visible = visible; } Visual.setVisibility = setVisibility; function setAlphaFactor(renderObject, alphaFactor) { if (renderObject) renderObject.state.alphaFactor = alphaFactor; } Visual.setAlphaFactor = setAlphaFactor; function setPickable(renderObject, pickable) { if (renderObject) renderObject.state.pickable = pickable; } Visual.setPickable = setPickable; function setColorOnly(renderObject, colorOnly) { if (renderObject) renderObject.state.colorOnly = colorOnly; } Visual.setColorOnly = setColorOnly; function mark(renderObject, loci, action, lociApply, previous) { if (!renderObject || isEmptyLoci(loci)) return false; var _a = renderObject.values, tMarker = _a.tMarker, uMarker = _a.uMarker, markerAverage = _a.markerAverage, markerStatus = _a.markerStatus, uGroupCount = _a.uGroupCount, instanceCount = _a.instanceCount, instanceGranularity = _a.instanceGranularity; var count = instanceGranularity.ref.value ? instanceCount.ref.value : uGroupCount.ref.value * instanceCount.ref.value; var array = tMarker.ref.value.array; var currentStatus = markerStatus.ref.value; if (!isEveryLoci(loci)) { // assume that all interval are non-overlapping var intervalSize_1 = 0; lociApply(loci, function (interval) { intervalSize_1 += Interval.size(interval); return true; }, true); if (intervalSize_1 === 0) return false; if (intervalSize_1 === count) loci = EveryLoci; } var changed = false; var average = -1; var status = -1; if (isEveryLoci(loci)) { var info = getMarkerInfo(action, currentStatus); if (info.status !== -1) { changed = currentStatus !== info.status; if (changed) setMarkerValue(array, info.status, count); } else { changed = applyMarkerAction(array, Interval.ofLength(count), action); } average = info.average; status = info.status; } else { changed = lociApply(loci, function (interval) { return applyMarkerAction(array, interval, action); }, true); if (changed) { average = getPartialMarkerAverage(action, currentStatus); if (previous && previous.status !== -1 && average === -1 && MarkerActions.isReverse(previous.action, action) && Loci.areEqual(loci, previous.loci)) { status = previous.status; average = status === 0 ? 0 : 0.5; } } } if (changed) { if (average === -1) { average = getMarkersAverage(array, count); if (average === 0) status = 0; } if (previous) { previous.action = action; previous.loci = loci; previous.status = currentStatus; } ValueCell.updateIfChanged(uMarker, status); if (status === -1) ValueCell.update(tMarker, tMarker.ref.value); ValueCell.updateIfChanged(markerAverage, average); ValueCell.updateIfChanged(markerStatus, status); } return changed; } Visual.mark = mark; function setOverpaint(renderObject, overpaint, lociApply, clear, smoothing) { if (!renderObject) return; var _a = renderObject.values, tOverpaint = _a.tOverpaint, dOverpaintType = _a.dOverpaintType, dOverpaint = _a.dOverpaint, uGroupCount = _a.uGroupCount, instanceCount = _a.instanceCount, instanceGranularity = _a.instanceGranularity; var count = instanceGranularity.ref.value ? instanceCount.ref.value : uGroupCount.ref.value * instanceCount.ref.value; // ensure texture has right size and type var type = instanceGranularity.ref.value ? 'instance' : 'groupInstance'; createOverpaint(overpaint.layers.length ? count : 0, type, renderObject.values); var array = tOverpaint.ref.value.array; // clear all if requested if (clear) clearOverpaint(array, 0, count); var _loop_1 = function (i, il) { var _d = overpaint.layers[i], loci = _d.loci, color = _d.color, clear_1 = _d.clear; var apply = function (interval) { var start = Interval.start(interval); var end = Interval.end(interval); return clear_1 ? clearOverpaint(array, start, end) : applyOverpaintColor(array, start, end, color); }; lociApply(loci, apply, false); }; for (var i = 0, il = overpaint.layers.length; i < il; ++i) { _loop_1(i, il); } ValueCell.update(tOverpaint, tOverpaint.ref.value); ValueCell.updateIfChanged(dOverpaintType, type); ValueCell.updateIfChanged(dOverpaint, overpaint.layers.length > 0); if (overpaint.layers.length === 0) return; if (type === 'instance') return; if (smoothing && hasColorSmoothingProp(smoothing.props)) { var geometry = smoothing.geometry, props = smoothing.props, webgl = smoothing.webgl; if (geometry.kind === 'mesh') { var _b = geometry.meta, resolution = _b.resolution, overpaintTexture = _b.overpaintTexture; var csp = getColorSmoothingProps(props.smoothColors, true, resolution); if (csp) { applyMeshOverpaintSmoothing(renderObject.values, csp.resolution, csp.stride, webgl, overpaintTexture); geometry.meta.overpaintTexture = renderObject.values.tOverpaintGrid.ref.value; } } else if (webgl && geometry.kind === 'texture-mesh') { var _c = geometry.meta, resolution = _c.resolution, overpaintTexture = _c.overpaintTexture; var csp = getColorSmoothingProps(props.smoothColors, true, resolution); if (csp) { applyTextureMeshOverpaintSmoothing(renderObject.values, csp.resolution, csp.stride, webgl, overpaintTexture); geometry.meta.overpaintTexture = renderObject.values.tOverpaintGrid.ref.value; } } } } Visual.setOverpaint = setOverpaint; function setTransparency(renderObject, transparency, lociApply, clear, smoothing) { if (!renderObject) return; var _a = renderObject.values, tTransparency = _a.tTransparency, dTransparencyType = _a.dTransparencyType, transparencyAverage = _a.transparencyAverage, dTransparency = _a.dTransparency, uGroupCount = _a.uGroupCount, instanceCount = _a.instanceCount, instanceGranularity = _a.instanceGranularity; var count = instanceGranularity.ref.value ? instanceCount.ref.value : uGroupCount.ref.value * instanceCount.ref.value; // ensure texture has right size and type var type = instanceGranularity.ref.value ? 'instance' : 'groupInstance'; createTransparency(transparency.layers.length ? count : 0, type, renderObject.values); var array = tTransparency.ref.value.array; // clear if requested if (clear) clearTransparency(array, 0, count); var _loop_2 = function (i, il) { var _d = transparency.layers[i], loci = _d.loci, value = _d.value; var apply = function (interval) { var start = Interval.start(interval); var end = Interval.end(interval); return applyTransparencyValue(array, start, end, value); }; lociApply(loci, apply, false); }; for (var i = 0, il = transparency.layers.length; i < il; ++i) { _loop_2(i, il); } ValueCell.update(tTransparency, tTransparency.ref.value); ValueCell.updateIfChanged(transparencyAverage, getTransparencyAverage(array, count)); ValueCell.updateIfChanged(dTransparencyType, type); ValueCell.updateIfChanged(dTransparency, transparency.layers.length > 0); if (transparency.layers.length === 0) return; if (type === 'instance') return; if (smoothing && hasColorSmoothingProp(smoothing.props)) { var geometry = smoothing.geometry, props = smoothing.props, webgl = smoothing.webgl; if (geometry.kind === 'mesh') { var _b = geometry.meta, resolution = _b.resolution, transparencyTexture = _b.transparencyTexture; var csp = getColorSmoothingProps(props.smoothColors, true, resolution); if (csp) { applyMeshTransparencySmoothing(renderObject.values, csp.resolution, csp.stride, webgl, transparencyTexture); geometry.meta.transparencyTexture = renderObject.values.tTransparencyGrid.ref.value; } } else if (webgl && geometry.kind === 'texture-mesh') { var _c = geometry.meta, resolution = _c.resolution, transparencyTexture = _c.transparencyTexture; var csp = getColorSmoothingProps(props.smoothColors, true, resolution); if (csp) { applyTextureMeshTransparencySmoothing(renderObject.values, csp.resolution, csp.stride, webgl, transparencyTexture); geometry.meta.transparencyTexture = renderObject.values.tTransparencyGrid.ref.value; } } } } Visual.setTransparency = setTransparency; function setSubstance(renderObject, substance, lociApply, clear, smoothing) { if (!renderObject) return; var _a = renderObject.values, tSubstance = _a.tSubstance, dSubstanceType = _a.dSubstanceType, dSubstance = _a.dSubstance, uGroupCount = _a.uGroupCount, instanceCount = _a.instanceCount, instanceGranularity = _a.instanceGranularity; var count = instanceGranularity.ref.value ? instanceCount.ref.value : uGroupCount.ref.value * instanceCount.ref.value; // ensure texture has right size and type var type = instanceGranularity.ref.value ? 'instance' : 'groupInstance'; createSubstance(substance.layers.length ? count : 0, type, renderObject.values); var array = tSubstance.ref.value.array; // clear all if requested if (clear) clearSubstance(array, 0, count); var _loop_3 = function (i, il) { var _d = substance.layers[i], loci = _d.loci, material = _d.material, clear_2 = _d.clear; var apply = function (interval) { var start = Interval.start(interval); var end = Interval.end(interval); return clear_2 ? clearSubstance(array, start, end) : applySubstanceMaterial(array, start, end, material); }; lociApply(loci, apply, false); }; for (var i = 0, il = substance.layers.length; i < il; ++i) { _loop_3(i, il); } ValueCell.update(tSubstance, tSubstance.ref.value); ValueCell.updateIfChanged(dSubstanceType, type); ValueCell.updateIfChanged(dSubstance, substance.layers.length > 0); if (substance.layers.length === 0) return; if (type === 'instance') return; if (smoothing && hasColorSmoothingProp(smoothing.props)) { var geometry = smoothing.geometry, props = smoothing.props, webgl = smoothing.webgl; if (geometry.kind === 'mesh') { var _b = geometry.meta, resolution = _b.resolution, substanceTexture = _b.substanceTexture; var csp = getColorSmoothingProps(props.smoothColors, true, resolution); if (csp) { applyMeshSubstanceSmoothing(renderObject.values, csp.resolution, csp.stride, webgl, substanceTexture); geometry.meta.substanceTexture = renderObject.values.tSubstanceGrid.ref.value; } } else if (webgl && geometry.kind === 'texture-mesh') { var _c = geometry.meta, resolution = _c.resolution, substanceTexture = _c.substanceTexture; var csp = getColorSmoothingProps(props.smoothColors, true, resolution); if (csp) { applyTextureMeshSubstanceSmoothing(renderObject.values, csp.resolution, csp.stride, webgl, substanceTexture); geometry.meta.substanceTexture = renderObject.values.tSubstanceGrid.ref.value; } } } } Visual.setSubstance = setSubstance; function setClipping(renderObject, clipping, lociApply, clear) { if (!renderObject) return; var _a = renderObject.values, tClipping = _a.tClipping, dClippingType = _a.dClippingType, dClipping = _a.dClipping, uGroupCount = _a.uGroupCount, instanceCount = _a.instanceCount, instanceGranularity = _a.instanceGranularity; var count = instanceGranularity.ref.value ? instanceCount.ref.value : uGroupCount.ref.value * instanceCount.ref.value; var layers = clipping.layers; // ensure texture has right size and type var type = instanceGranularity.ref.value ? 'instance' : 'groupInstance'; createClipping(layers.length ? count : 0, type, renderObject.values); var array = tClipping.ref.value.array; // clear if requested if (clear) clearClipping(array, 0, count); var _loop_4 = function (i, il) { var _b = clipping.layers[i], loci = _b.loci, groups = _b.groups; var apply = function (interval) { var start = Interval.start(interval); var end = Interval.end(interval); return applyClippingGroups(array, start, end, groups); }; lociApply(loci, apply, false); }; for (var i = 0, il = clipping.layers.length; i < il; ++i) { _loop_4(i, il); } ValueCell.update(tClipping, tClipping.ref.value); ValueCell.updateIfChanged(dClippingType, type); ValueCell.updateIfChanged(dClipping, clipping.layers.length > 0); } Visual.setClipping = setClipping; function setTransform(renderObject, transform, instanceTransforms) { if (!renderObject || (!transform && !instanceTransforms)) return; var values = renderObject.values; if (transform) { Mat4.copy(values.matrix.ref.value, transform); ValueCell.update(values.matrix, values.matrix.ref.value); } if (instanceTransforms) { values.extraTransform.ref.value.set(instanceTransforms); ValueCell.update(values.extraTransform, values.extraTransform.ref.value); } else if (instanceTransforms === null) { fillIdentityTransform(values.extraTransform.ref.value, values.instanceCount.ref.value); ValueCell.update(values.extraTransform, values.extraTransform.ref.value); } updateTransformData(values); var boundingSphere = calculateTransformBoundingSphere(values.invariantBoundingSphere.ref.value, values.aTransform.ref.value, values.instanceCount.ref.value); ValueCell.update(values.boundingSphere, boundingSphere); } Visual.setTransform = setTransform; })(Visual || (Visual = {}));