|
@@ -1,5 +1,5 @@
|
|
|
/**
|
|
|
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
+ * 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>
|
|
@@ -12,11 +12,10 @@ import { Structure } from '../../mol-model/structure';
|
|
|
import { Spheres } from '../../mol-geo/geometry/spheres/spheres';
|
|
|
import { SpheresBuilder } from '../../mol-geo/geometry/spheres/spheres-builder';
|
|
|
import { StructureRepresentationProvider, StructureRepresentation, StructureRepresentationStateBuilder } from '../../mol-repr/structure/representation';
|
|
|
-import { MembraneOrientation } from './membrane-orientation';
|
|
|
+import { MembraneOrientation } from './prop';
|
|
|
import { ThemeRegistryContext } from '../../mol-theme/theme';
|
|
|
import { ShapeRepresentation } from '../../mol-repr/shape/representation';
|
|
|
import { Shape } from '../../mol-model/shape';
|
|
|
-import { ColorNames } from '../../mol-util/color/names';
|
|
|
import { RuntimeContext } from '../../mol-task';
|
|
|
import { Lines } from '../../mol-geo/geometry/lines/lines';
|
|
|
import { Mesh } from '../../mol-geo/geometry/mesh/mesh';
|
|
@@ -24,7 +23,10 @@ import { LinesBuilder } from '../../mol-geo/geometry/lines/lines-builder';
|
|
|
import { Circle } from '../../mol-geo/primitive/circle';
|
|
|
import { transformPrimitive } from '../../mol-geo/primitive/primitive';
|
|
|
import { MeshBuilder } from '../../mol-geo/geometry/mesh/mesh-builder';
|
|
|
-import { MembraneOrientationProvider } from './membrane-orientation';
|
|
|
+import { MembraneOrientationProvider } from './prop';
|
|
|
+import { MarkerActions } from '../../mol-util/marker-action';
|
|
|
+import { lociLabel } from '../../mol-theme/label';
|
|
|
+import { ColorNames } from '../../mol-util/color/names';
|
|
|
|
|
|
const SharedParams = {
|
|
|
color: PD.Color(ColorNames.lightgrey),
|
|
@@ -32,8 +34,8 @@ const SharedParams = {
|
|
|
};
|
|
|
|
|
|
const BilayerSpheresParams = {
|
|
|
- ...SharedParams,
|
|
|
...Spheres.Params,
|
|
|
+ ...SharedParams,
|
|
|
sphereSize: PD.Numeric(1, { min: 0.1, max: 10, step: 0.1 }, { description: 'Size of spheres that represent membrane planes' }),
|
|
|
density: PD.Numeric(1, { min: 0.25, max: 10, step: 0.25 }, { description: 'Distance between spheres'})
|
|
|
};
|
|
@@ -41,27 +43,27 @@ export type BilayerSpheresParams = typeof BilayerSpheresParams
|
|
|
export type BilayerSpheresProps = PD.Values<BilayerSpheresParams>
|
|
|
|
|
|
const BilayerPlanesParams = {
|
|
|
- ...SharedParams,
|
|
|
...Mesh.Params,
|
|
|
- sectorOpacity: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 })
|
|
|
+ ...SharedParams,
|
|
|
+ sectorOpacity: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }),
|
|
|
};
|
|
|
export type BilayerPlanesParams = typeof BilayerPlanesParams
|
|
|
export type BilayerPlanesProps = PD.Values<BilayerPlanesParams>
|
|
|
|
|
|
const BilayerRimsParams = {
|
|
|
- ...SharedParams,
|
|
|
...Lines.Params,
|
|
|
+ ...SharedParams,
|
|
|
lineSizeAttenuation: PD.Boolean(true),
|
|
|
- linesSize: PD.Numeric(0.5, { min: 0.01, max: 50, step: 0.01 }),
|
|
|
- dashedLines: PD.Boolean(true)
|
|
|
+ linesSize: PD.Numeric(0.3, { min: 0.01, max: 50, step: 0.01 }),
|
|
|
+ dashedLines: PD.Boolean(true),
|
|
|
};
|
|
|
export type BilayerRimsParams = typeof BilayerRimsParams
|
|
|
export type BilayerRimsProps = PD.Values<BilayerRimsParams>
|
|
|
|
|
|
const MembraneOrientationVisuals = {
|
|
|
- 'bilayer-spheres': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerSpheresParams>) => ShapeRepresentation(getBilayerSpheres, Spheres.Utils, { modifyState: s => ({ ...s, pickable: false }) }),
|
|
|
- 'bilayer-planes': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerPlanesParams>) => ShapeRepresentation(getBilayerPlanes, Mesh.Utils, { modifyProps: p => ({ ...p, alpha: p.sectorOpacity }), modifyState: s => ({ ...s, pickable: false }) }),
|
|
|
- 'bilayer-rims': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerRimsParams>) => ShapeRepresentation(getBilayerRims, Lines.Utils, { modifyState: s => ({ ...s, pickable: false }) })
|
|
|
+ 'bilayer-spheres': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerSpheresParams>) => ShapeRepresentation(getBilayerSpheres, Spheres.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }) }),
|
|
|
+ 'bilayer-planes': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerPlanesParams>) => ShapeRepresentation(getBilayerPlanes, Mesh.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }), modifyProps: p => ({ ...p, alpha: p.sectorOpacity, ignoreLight: true, doubleSided: false }) }),
|
|
|
+ 'bilayer-rims': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerRimsParams>) => ShapeRepresentation(getBilayerRims, Lines.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }) })
|
|
|
};
|
|
|
|
|
|
export const MembraneOrientationParams = {
|
|
@@ -94,16 +96,20 @@ export const MembraneOrientationRepresentationProvider = StructureRepresentation
|
|
|
isApplicable: (structure: Structure) => structure.elementCount > 0
|
|
|
});
|
|
|
|
|
|
-function getBilayerRims(ctx: RuntimeContext, data: Structure, props: BilayerRimsProps): Shape<Lines> {
|
|
|
+function membraneLabel(data: Structure) {
|
|
|
+ return `${lociLabel(Structure.Loci(data))} | Membrane Orientation`;
|
|
|
+}
|
|
|
+
|
|
|
+function getBilayerRims(ctx: RuntimeContext, data: Structure, props: BilayerRimsProps, shape?: Shape<Lines>): Shape<Lines> {
|
|
|
const { planePoint1: p1, planePoint2: p2, centroid, normalVector: normal, radius } = MembraneOrientationProvider.get(data).value!;
|
|
|
const scaledRadius = props.radiusFactor * radius;
|
|
|
- const builder = LinesBuilder.create(128, 64);
|
|
|
+ const builder = LinesBuilder.create(128, 64, shape?.geometry);
|
|
|
getLayerCircle(builder, p1, centroid, normal, scaledRadius, props);
|
|
|
getLayerCircle(builder, p2, centroid, normal, scaledRadius, props);
|
|
|
- return Shape.create(name, data, builder.getLines(), () => props.color, () => props.linesSize, () => '');
|
|
|
+ return Shape.create(name, data, builder.getLines(), () => props.color, () => props.linesSize, () => membraneLabel(data));
|
|
|
}
|
|
|
|
|
|
-function getLayerCircle(builder: LinesBuilder, p: Vec3, centroid: Vec3, normal: Vec3, radius: number, props: BilayerRimsProps) {
|
|
|
+function getLayerCircle(builder: LinesBuilder, p: Vec3, centroid: Vec3, normal: Vec3, radius: number, props: BilayerRimsProps, shape?: Shape<Lines>) {
|
|
|
const circle = getCircle(p, centroid, normal, radius);
|
|
|
const { indices, vertices } = circle;
|
|
|
for (let j = 0, jl = indices.length; j < jl; j += 3) {
|
|
@@ -126,7 +132,7 @@ function getCircle(p: Vec3, centroid: Vec3, normal: Vec3, radius: number) {
|
|
|
Mat4.setTranslation(tmpMat, p);
|
|
|
Mat4.mul(tmpMat, tmpMat, Mat4.rotX90);
|
|
|
|
|
|
- const circle = Circle({ radius });
|
|
|
+ const circle = Circle({ radius, segments: 64 });
|
|
|
return transformPrimitive(circle, tmpMat);
|
|
|
}
|
|
|
|
|
@@ -136,7 +142,7 @@ function getBilayerPlanes(ctx: RuntimeContext, data: Structure, props: BilayerPl
|
|
|
const scaledRadius = props.radiusFactor * radius;
|
|
|
getLayerPlane(state, p1, centroid, normal, scaledRadius);
|
|
|
getLayerPlane(state, p2, centroid, normal, scaledRadius);
|
|
|
- return Shape.create(name, data, MeshBuilder.getMesh(state), () => props.color, () => 1, () => '');
|
|
|
+ return Shape.create(name, data, MeshBuilder.getMesh(state), () => props.color, () => 1, () => membraneLabel(data));
|
|
|
}
|
|
|
|
|
|
function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, normal: Vec3, radius: number) {
|
|
@@ -146,15 +152,15 @@ function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, normal
|
|
|
MeshBuilder.addPrimitiveFlipped(state, Mat4.id, circle);
|
|
|
}
|
|
|
|
|
|
-function getBilayerSpheres(ctx: RuntimeContext, data: Structure, props: BilayerSpheresProps): Shape<Spheres> {
|
|
|
+function getBilayerSpheres(ctx: RuntimeContext, data: Structure, props: BilayerSpheresProps, shape?: Shape<Spheres>): Shape<Spheres> {
|
|
|
const { density } = props;
|
|
|
const { radius, planePoint1, planePoint2, normalVector } = MembraneOrientationProvider.get(data).value!;
|
|
|
const scaledRadius = (props.radiusFactor * radius) * (props.radiusFactor * radius);
|
|
|
|
|
|
- const spheresBuilder = SpheresBuilder.create();
|
|
|
+ const spheresBuilder = SpheresBuilder.create(256, 128, shape?.geometry);
|
|
|
getLayerSpheres(spheresBuilder, planePoint1, normalVector, density, scaledRadius);
|
|
|
getLayerSpheres(spheresBuilder, planePoint2, normalVector, density, scaledRadius);
|
|
|
- return Shape.create(name, data, spheresBuilder.getSpheres(), () => props.color, () => props.sphereSize, () => '');
|
|
|
+ return Shape.create(name, data, spheresBuilder.getSpheres(), () => props.color, () => props.sphereSize, () => membraneLabel(data));
|
|
|
}
|
|
|
|
|
|
function getLayerSpheres(spheresBuilder: SpheresBuilder, point: Vec3, normalVector: Vec3, density: number, sqRadius: number) {
|