molstar
Version:
A comprehensive macromolecular library.
219 lines (218 loc) • 12.7 kB
JavaScript
"use strict";
/**
* Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.CarbohydrateSymbolVisual = exports.CarbohydrateSymbolParams = void 0;
var tslib_1 = require("tslib");
var linear_algebra_1 = require("../../../mol-math/linear-algebra");
var box_1 = require("../../../mol-geo/primitive/box");
var pyramid_1 = require("../../../mol-geo/primitive/pyramid");
var star_1 = require("../../../mol-geo/primitive/star");
var octahedron_1 = require("../../../mol-geo/primitive/octahedron");
var prism_1 = require("../../../mol-geo/primitive/prism");
var structure_1 = require("../../../mol-model/structure");
var mesh_builder_1 = require("../../../mol-geo/geometry/mesh/mesh-builder");
var constants_1 = require("../../../mol-model/structure/structure/carbohydrates/constants");
var sphere_1 = require("../../../mol-geo/geometry/mesh/builder/sphere");
var complex_visual_1 = require("../complex-visual");
var param_definition_1 = require("../../../mol-util/param-definition");
var location_iterator_1 = require("../../../mol-geo/util/location-iterator");
var int_1 = require("../../../mol-data/int");
var loci_1 = require("../../../mol-model/loci");
var common_1 = require("./util/common");
var base_1 = require("../../../mol-geo/geometry/base");
var t = linear_algebra_1.Mat4.identity();
var sVec = (0, linear_algebra_1.Vec3)();
var pd = (0, linear_algebra_1.Vec3)();
var SideFactor = 2 * 0.806; // 0.806 == Math.cos(Math.PI / 4)
var box = (0, box_1.Box)();
var perforatedBox = (0, box_1.PerforatedBox)();
var octagonalPyramid = (0, pyramid_1.OctagonalPyramid)();
var perforatedOctagonalPyramid = (0, pyramid_1.PerforatedOctagonalPyramid)();
var star = (0, star_1.Star)({ outerRadius: 1, innerRadius: 0.5, thickness: 0.5, pointCount: 5 });
var octahedron = (0, octahedron_1.Octahedron)();
var perforatedOctahedron = (0, octahedron_1.PerforatedOctahedron)();
var diamondPrism = (0, prism_1.DiamondPrism)();
var pentagonalPrism = (0, prism_1.PentagonalPrism)();
var hexagonalPrism = (0, prism_1.HexagonalPrism)();
var shiftedHexagonalPrism = (0, prism_1.ShiftedHexagonalPrism)();
var heptagonalPrism = (0, prism_1.HeptagonalPrism)();
function createCarbohydrateSymbolMesh(ctx, structure, theme, props, mesh) {
var builderState = mesh_builder_1.MeshBuilder.createState(256, 128, mesh);
var detail = props.detail, sizeFactor = props.sizeFactor;
var carbohydrates = structure.carbohydrates;
var n = carbohydrates.elements.length;
var l = structure_1.StructureElement.Location.create(structure);
for (var i = 0; i < n; ++i) {
var c = carbohydrates.elements[i];
var ring = c.unit.rings.all[c.ringIndex];
var shapeType = (0, constants_1.getSaccharideShape)(c.component.type, ring.length);
l.unit = c.unit;
l.element = c.unit.elements[ring[0]];
var size = theme.size.size(l);
var radius = size * sizeFactor;
var side = size * sizeFactor * SideFactor;
var _a = c.geometry, center = _a.center, normal = _a.normal, direction = _a.direction;
linear_algebra_1.Vec3.add(pd, center, direction);
linear_algebra_1.Mat4.targetTo(t, center, pd, normal);
linear_algebra_1.Mat4.setTranslation(t, center);
builderState.currentGroup = i * 2;
switch (shapeType) {
case 0 /* SaccharideShape.FilledSphere */:
(0, sphere_1.addSphere)(builderState, center, radius, detail);
break;
case 1 /* SaccharideShape.FilledCube */:
linear_algebra_1.Mat4.scaleUniformly(t, t, side);
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, box);
break;
case 2 /* SaccharideShape.CrossedCube */:
linear_algebra_1.Mat4.scaleUniformly(t, t, side);
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, perforatedBox);
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZ90X180);
builderState.currentGroup += 1;
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, perforatedBox);
break;
case 4 /* SaccharideShape.FilledCone */:
linear_algebra_1.Mat4.scaleUniformly(t, t, side * 1.2);
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, octagonalPyramid);
break;
case 5 /* SaccharideShape.DevidedCone */:
linear_algebra_1.Mat4.scaleUniformly(t, t, side * 1.2);
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, perforatedOctagonalPyramid);
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZ90);
builderState.currentGroup += 1;
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, perforatedOctagonalPyramid);
break;
case 6 /* SaccharideShape.FlatBox */:
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZY90);
linear_algebra_1.Mat4.scale(t, t, linear_algebra_1.Vec3.set(sVec, side, side, side / 2));
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, box);
break;
case 7 /* SaccharideShape.FilledStar */:
linear_algebra_1.Mat4.scaleUniformly(t, t, side);
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZY90);
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, star);
break;
case 8 /* SaccharideShape.FilledDiamond */:
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZY90);
linear_algebra_1.Mat4.scale(t, t, linear_algebra_1.Vec3.set(sVec, side * 1.4, side * 1.4, side * 1.4));
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, octahedron);
break;
case 3 /* SaccharideShape.DividedDiamond */:
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZY90);
linear_algebra_1.Mat4.scale(t, t, linear_algebra_1.Vec3.set(sVec, side * 1.4, side * 1.4, side * 1.4));
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, perforatedOctahedron);
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotY90);
builderState.currentGroup += 1;
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, perforatedOctahedron);
break;
case 9 /* SaccharideShape.FlatDiamond */:
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZY90);
linear_algebra_1.Mat4.scale(t, t, linear_algebra_1.Vec3.set(sVec, side, side / 2, side / 2));
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, diamondPrism);
break;
case 12 /* SaccharideShape.DiamondPrism */:
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZY90);
linear_algebra_1.Mat4.scale(t, t, linear_algebra_1.Vec3.set(sVec, side, side, side / 2));
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, diamondPrism);
break;
case 13 /* SaccharideShape.PentagonalPrism */:
case 11 /* SaccharideShape.Pentagon */:
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZY90);
linear_algebra_1.Mat4.scale(t, t, linear_algebra_1.Vec3.set(sVec, side, side, side / 2));
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, pentagonalPrism);
break;
case 14 /* SaccharideShape.HexagonalPrism */:
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZY90);
linear_algebra_1.Mat4.scale(t, t, linear_algebra_1.Vec3.set(sVec, side, side, side / 2));
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, hexagonalPrism);
break;
case 15 /* SaccharideShape.HeptagonalPrism */:
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZY90);
linear_algebra_1.Mat4.scale(t, t, linear_algebra_1.Vec3.set(sVec, side, side, side / 2));
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, heptagonalPrism);
break;
case 10 /* SaccharideShape.FlatHexagon */:
default:
linear_algebra_1.Mat4.mul(t, t, linear_algebra_1.Mat4.rotZYZ90);
linear_algebra_1.Mat4.scale(t, t, linear_algebra_1.Vec3.set(sVec, side / 1.5, side, side / 2));
mesh_builder_1.MeshBuilder.addPrimitive(builderState, t, shiftedHexagonalPrism);
break;
}
}
return mesh_builder_1.MeshBuilder.getMesh(builderState);
}
exports.CarbohydrateSymbolParams = tslib_1.__assign(tslib_1.__assign({}, complex_visual_1.ComplexMeshParams), { detail: param_definition_1.ParamDefinition.Numeric(0, { min: 0, max: 3, step: 1 }, base_1.BaseGeometry.CustomQualityParamInfo), sizeFactor: param_definition_1.ParamDefinition.Numeric(1.75, { min: 0, max: 10, step: 0.01 }) });
function CarbohydrateSymbolVisual(materialId) {
return (0, complex_visual_1.ComplexMeshVisual)({
defaultProps: param_definition_1.ParamDefinition.getDefaultValues(exports.CarbohydrateSymbolParams),
createGeometry: createCarbohydrateSymbolMesh,
createLocationIterator: CarbohydrateElementIterator,
getLoci: getCarbohydrateLoci,
eachLocation: eachCarbohydrate,
setUpdateState: function (state, newProps, currentProps) {
state.createGeometry = (newProps.sizeFactor !== currentProps.sizeFactor ||
newProps.detail !== currentProps.detail);
}
}, materialId);
}
exports.CarbohydrateSymbolVisual = CarbohydrateSymbolVisual;
function CarbohydrateElementIterator(structure) {
var carbElements = structure.carbohydrates.elements;
var groupCount = carbElements.length * 2;
var instanceCount = 1;
var location = structure_1.StructureElement.Location.create(structure);
function getLocation(groupIndex, instanceIndex) {
var carb = carbElements[Math.floor(groupIndex / 2)];
var ring = carb.unit.rings.all[carb.ringIndex];
location.unit = carb.unit;
location.element = carb.unit.elements[ring[0]];
return location;
}
function isSecondary(elementIndex, instanceIndex) {
return (elementIndex % 2) === 1;
}
return (0, location_iterator_1.LocationIterator)(groupCount, instanceCount, 1, getLocation, true, isSecondary);
}
/** Return a Loci for the elements of the whole residue of a carbohydrate. */
function getCarbohydrateLoci(pickingId, structure, id) {
var objectId = pickingId.objectId, groupId = pickingId.groupId;
if (id === objectId) {
var carb = structure.carbohydrates.elements[Math.floor(groupId / 2)];
return (0, common_1.getAltResidueLociFromId)(structure, carb.unit, carb.residueIndex, carb.altId);
}
return loci_1.EmptyLoci;
}
var __elementIndicesSet = new Set();
/** For each carbohydrate (usually a monosaccharide) when all its residue's elements are in a loci. */
function eachCarbohydrate(loci, structure, apply) {
var getElementIndices = structure.carbohydrates.getElementIndices;
var changed = false;
if (!structure_1.StructureElement.Loci.is(loci))
return false;
if (!structure_1.Structure.areEquivalent(loci.structure, structure))
return false;
var _loop_1 = function (unit, indices) {
if (!structure_1.Unit.isAtomic(unit))
return "continue";
__elementIndicesSet.clear();
int_1.OrderedSet.forEach(indices, function (v) {
var elementIndices = getElementIndices(unit, unit.elements[v]);
for (var i = 0, il = elementIndices.length; i < il; ++i) {
if (!__elementIndicesSet.has(elementIndices[i])) {
__elementIndicesSet.add(elementIndices[i]);
if (apply(int_1.Interval.ofSingleton(elementIndices[i] * 2)))
changed = true;
}
}
});
};
for (var _i = 0, _a = loci.elements; _i < _a.length; _i++) {
var _b = _a[_i], unit = _b.unit, indices = _b.indices;
_loop_1(unit, indices);
}
return changed;
}