UNPKG

molstar

Version:

A comprehensive macromolecular library.

131 lines (130 loc) 7.58 kB
"use strict"; /** * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.MembraneOrientationRepresentationProvider = exports.MembraneOrientationParams = void 0; exports.getMembraneOrientationParams = getMembraneOrientationParams; exports.MembraneOrientationRepresentation = MembraneOrientationRepresentation; const param_definition_1 = require("../../mol-util/param-definition"); const linear_algebra_1 = require("../../mol-math/linear-algebra"); const representation_1 = require("../../mol-repr/representation"); const structure_1 = require("../../mol-model/structure"); const representation_2 = require("../../mol-repr/structure/representation"); const representation_3 = require("../../mol-repr/shape/representation"); const shape_1 = require("../../mol-model/shape"); const lines_1 = require("../../mol-geo/geometry/lines/lines"); const mesh_1 = require("../../mol-geo/geometry/mesh/mesh"); const lines_builder_1 = require("../../mol-geo/geometry/lines/lines-builder"); const circle_1 = require("../../mol-geo/primitive/circle"); const primitive_1 = require("../../mol-geo/primitive/primitive"); const mesh_builder_1 = require("../../mol-geo/geometry/mesh/mesh-builder"); const prop_1 = require("./prop"); const marker_action_1 = require("../../mol-util/marker-action"); const label_1 = require("../../mol-theme/label"); const names_1 = require("../../mol-util/color/names"); const SharedParams = { color: param_definition_1.ParamDefinition.Color(names_1.ColorNames.lightgrey), radiusFactor: param_definition_1.ParamDefinition.Numeric(1.2, { min: 0.1, max: 3.0, step: 0.01 }, { description: 'Scale the radius of the membrane layer' }) }; const BilayerPlanesParams = { ...mesh_1.Mesh.Params, ...SharedParams, sectorOpacity: param_definition_1.ParamDefinition.Numeric(0.5, { min: 0, max: 1, step: 0.01 }), }; const BilayerRimsParams = { ...lines_1.Lines.Params, ...SharedParams, lineSizeAttenuation: param_definition_1.ParamDefinition.Boolean(false), linesSize: param_definition_1.ParamDefinition.Numeric(0.5, { min: 0.01, max: 50, step: 0.01 }), dashedLines: param_definition_1.ParamDefinition.Boolean(false), }; const MembraneOrientationVisuals = { 'bilayer-planes': (ctx, getParams) => (0, representation_3.ShapeRepresentation)(getBilayerPlanes, mesh_1.Mesh.Utils, { modifyState: s => ({ ...s, markerActions: marker_action_1.MarkerActions.Highlighting }), modifyProps: p => ({ ...p, alpha: p.sectorOpacity, ignoreLight: true, doubleSided: false }) }), 'bilayer-rims': (ctx, getParams) => (0, representation_3.ShapeRepresentation)(getBilayerRims, lines_1.Lines.Utils, { modifyState: s => ({ ...s, markerActions: marker_action_1.MarkerActions.Highlighting }) }) }; exports.MembraneOrientationParams = { ...BilayerPlanesParams, ...BilayerRimsParams, visuals: param_definition_1.ParamDefinition.MultiSelect(['bilayer-planes', 'bilayer-rims'], param_definition_1.ParamDefinition.objectToOptions(MembraneOrientationVisuals)), }; function getMembraneOrientationParams(ctx, structure) { return param_definition_1.ParamDefinition.clone(exports.MembraneOrientationParams); } function MembraneOrientationRepresentation(ctx, getParams) { return representation_1.Representation.createMulti('Membrane Orientation', ctx, getParams, representation_2.StructureRepresentationStateBuilder, MembraneOrientationVisuals); } exports.MembraneOrientationRepresentationProvider = (0, representation_2.StructureRepresentationProvider)({ name: 'membrane-orientation', label: 'Membrane Orientation', description: 'Displays a grid of points representing membrane layers.', factory: MembraneOrientationRepresentation, getParams: getMembraneOrientationParams, defaultValues: param_definition_1.ParamDefinition.getDefaultValues(exports.MembraneOrientationParams), defaultColorTheme: { name: 'shape-group' }, defaultSizeTheme: { name: 'shape-group' }, isApplicable(structure) { return prop_1.MembraneOrientationProvider.isApplicable(structure); }, ensureCustomProperties: { attach: (ctx, structure) => prop_1.MembraneOrientationProvider.attach(ctx, structure, void 0, true), detach: (data) => prop_1.MembraneOrientationProvider.ref(data, false) } }); function membraneLabel(data) { return `${(0, label_1.lociLabel)(structure_1.Structure.Loci(data))} | Membrane Orientation`; } function getBilayerRims(ctx, data, props, shape) { const { planePoint1: p1, planePoint2: p2, centroid, radius } = prop_1.MembraneOrientationProvider.get(data).value; const scaledRadius = props.radiusFactor * radius; const builder = lines_builder_1.LinesBuilder.create(128, 64, shape === null || shape === void 0 ? void 0 : shape.geometry); getLayerCircle(builder, p1, centroid, scaledRadius, props); getLayerCircle(builder, p2, centroid, scaledRadius, props); return shape_1.Shape.create('Bilayer rims', data, builder.getLines(), () => props.color, () => props.linesSize, () => membraneLabel(data)); } function getLayerCircle(builder, p, centroid, radius, props, shape) { const circle = getCircle(p, centroid, radius); const { indices, vertices } = circle; for (let j = 0, jl = indices.length; j < jl; j += 3) { if (props.dashedLines && j % 2 === 1) continue; // draw every other segment to get dashes const start = indices[j] * 3; const end = indices[j + 1] * 3; const startX = vertices[start]; const startY = vertices[start + 1]; const startZ = vertices[start + 2]; const endX = vertices[end]; const endY = vertices[end + 1]; const endZ = vertices[end + 2]; builder.add(startX, startY, startZ, endX, endY, endZ, 0); } } const tmpMat = (0, linear_algebra_1.Mat4)(); const tmpV = (0, linear_algebra_1.Vec3)(); function getCircle(p, centroid, radius) { if (linear_algebra_1.Vec3.dot(linear_algebra_1.Vec3.unitY, linear_algebra_1.Vec3.sub(tmpV, p, centroid)) === 0) { linear_algebra_1.Mat4.targetTo(tmpMat, p, centroid, linear_algebra_1.Vec3.unitY); } else { linear_algebra_1.Mat4.targetTo(tmpMat, p, centroid, linear_algebra_1.Vec3.unitX); } linear_algebra_1.Mat4.setTranslation(tmpMat, p); linear_algebra_1.Mat4.mul(tmpMat, tmpMat, linear_algebra_1.Mat4.rotX90); const circle = (0, circle_1.Circle)({ radius, segments: 64 }); return (0, primitive_1.transformPrimitive)(circle, tmpMat); } function getBilayerPlanes(ctx, data, props, shape) { const { planePoint1: p1, planePoint2: p2, centroid, radius } = prop_1.MembraneOrientationProvider.get(data).value; const state = mesh_builder_1.MeshBuilder.createState(128, 64, shape && shape.geometry); const scaledRadius = props.radiusFactor * radius; getLayerPlane(state, p1, centroid, scaledRadius); getLayerPlane(state, p2, centroid, scaledRadius); return shape_1.Shape.create('Bilayer planes', data, mesh_builder_1.MeshBuilder.getMesh(state), () => props.color, () => 1, () => membraneLabel(data)); } function getLayerPlane(state, p, centroid, radius) { const circle = getCircle(p, centroid, radius); state.currentGroup = 0; mesh_builder_1.MeshBuilder.addPrimitive(state, linear_algebra_1.Mat4.id, circle); mesh_builder_1.MeshBuilder.addPrimitiveFlipped(state, linear_algebra_1.Mat4.id, circle); }