molstar
Version:
A comprehensive macromolecular library.
334 lines (333 loc) • 17.9 kB
JavaScript
/**
* 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 = {}));