Skip to content
Snippets Groups Projects
Commit e7a0ba8d authored by Alexander Rose's avatar Alexander Rose
Browse files

wip, better boundary calculation, making use of transformations

parent 33d04f7e
No related branches found
No related tags found
No related merge requests found
......@@ -12,6 +12,13 @@ import { AssemblySymmetry } from 'mol-model-props/rcsb/symmetry';
import { ShapeRepresentation, ShapeProps } from 'mol-geo/representation/shape';
import { getAxesShape } from './assembly-symmetry';
import Viewer from 'mol-view/viewer';
import { CarbohydrateRepresentation } from 'mol-geo/representation/structure/representation/carbohydrate';
import { MeshBuilder } from 'mol-geo/mesh/mesh-builder';
import { addSphere } from 'mol-geo/mesh/builder/sphere';
import { Shape } from 'mol-model/shape';
import { Color } from 'mol-util/color';
import { computeUnitBoundary } from 'mol-model/structure/structure/util/boundary';
import { addBoundingBox } from 'mol-geo/mesh/builder/bounding-box';
export interface StructureView {
readonly label: string
......@@ -21,7 +28,8 @@ export interface StructureView {
readonly cartoon: CartoonRepresentation
readonly ballAndStick: BallAndStickRepresentation
readonly axes: ShapeRepresentation<ShapeProps>
readonly carbohydrate: CarbohydrateRepresentation
readonly symmetryAxes: ShapeRepresentation<ShapeProps>
readonly modelId: number
readonly assemblyId: string
......@@ -45,7 +53,9 @@ interface StructureViewProps {
export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>, props: StructureViewProps = {}): Promise<StructureView> {
const cartoon = CartoonRepresentation()
const ballAndStick = BallAndStickRepresentation()
const axes = ShapeRepresentation()
const carbohydrate = CarbohydrateRepresentation()
const symmetryAxes = ShapeRepresentation()
const polymerSphere = ShapeRepresentation()
let label: string
let model: Model | undefined
......@@ -156,14 +166,46 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
useFog: false // TODO fog not working properly
}, structure).run()
await carbohydrate.createOrUpdate({
colorTheme: { name: 'carbohydrate-symbol' },
sizeTheme: { name: 'uniform', value: 1, factor: 1 },
useFog: false // TODO fog not working properly
}, structure).run()
viewer.center(structure.boundary.sphere.center)
const mb = MeshBuilder.create()
mb.setGroup(0)
addSphere(mb, structure.boundary.sphere.center, structure.boundary.sphere.radius, 3)
addBoundingBox(mb, structure.boundary.box, 1, 2, 8)
for (let i = 0, il = structure.units.length; i < il; ++i) {
mb.setGroup(1)
const u = structure.units[i]
const ci = u.model.atomicHierarchy.chainAtomSegments.index[u.elements[0]]
const ek = u.model.atomicHierarchy.getEntityKey(ci)
if (u.model.entities.data.type.value(ek) === 'water') continue
const boundary = computeUnitBoundary(u)
addSphere(mb, boundary.sphere.center, boundary.sphere.radius, 3)
addBoundingBox(mb, boundary.box, 0.5, 2, 8)
}
const shape = Shape.create('boundary', mb.getMesh(), [Color(0xCC6633), Color(0x3366CC)], ['sphere boundary'])
await polymerSphere.createOrUpdate({
alpha: 0.5,
doubleSided: false,
depthMask: false,
useFog: false // TODO fog not working properly
}, shape).run()
} else {
cartoon.destroy()
ballAndStick.destroy()
carbohydrate.destroy()
polymerSphere.destroy()
}
viewer.add(cartoon)
viewer.add(ballAndStick)
viewer.add(carbohydrate)
viewer.add(polymerSphere)
}
async function createSymmetryRepr() {
......@@ -173,21 +215,21 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
const axesShape = getAxesShape(symmetryFeatureId, assemblySymmetry)
if (axesShape) {
// getClusterColorTheme(symmetryFeatureId, assemblySymmetry)
await axes.createOrUpdate({
await symmetryAxes.createOrUpdate({
colorTheme: { name: 'shape-group' },
// colorTheme: { name: 'uniform', value: Color(0xFFCC22) },
useFog: false // TODO fog not working properly
}, axesShape).run()
} else {
axes.destroy()
symmetryAxes.destroy()
}
} else {
axes.destroy()
symmetryAxes.destroy()
}
} else {
axes.destroy()
symmetryAxes.destroy()
}
viewer.add(axes)
viewer.add(symmetryAxes)
viewer.requestDraw()
}
......@@ -201,7 +243,8 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
cartoon,
ballAndStick,
axes,
carbohydrate,
symmetryAxes,
get modelId() { return modelId },
get assemblyId() { return assemblyId },
......@@ -217,12 +260,13 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
destroy: () => {
viewer.remove(cartoon)
viewer.remove(ballAndStick)
viewer.remove(axes)
viewer.remove(carbohydrate)
viewer.remove(symmetryAxes)
viewer.requestDraw()
cartoon.destroy()
ballAndStick.destroy()
axes.destroy()
symmetryAxes.destroy()
}
}
}
......
......@@ -2,13 +2,115 @@
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import Structure from '../structure'
import { Box3D, Sphere3D } from 'mol-math/geometry';
import Unit from '../unit';
import { Box3D, Sphere3D, SymmetryOperator } from 'mol-math/geometry';
import { Vec3 } from 'mol-math/linear-algebra';
import { SortedArray } from 'mol-data/int';
import { ElementIndex } from '../../model/indexing';
function computeStructureBoundary(s: Structure): { box: Box3D, sphere: Sphere3D } {
export type Boundary = { box: Box3D, sphere: Sphere3D }
function computeElementsPositionBoundary(elements: SortedArray<ElementIndex>, position: SymmetryOperator.CoordinateMapper): Boundary {
const min = Vec3.create(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)
const max = Vec3.create(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE)
const center = Vec3.zero()
let radiusSq = 0
let size = 0
const p = Vec3.zero()
size += elements.length
for (let j = 0, _j = elements.length; j < _j; j++) {
position(elements[j], p)
Vec3.min(min, min, p)
Vec3.max(max, max, p)
Vec3.add(center, center, p)
}
if (size > 0) Vec3.scale(center, center, 1/size)
for (let j = 0, _j = elements.length; j < _j; j++) {
position(elements[j], p)
const d = Vec3.squaredDistance(p, center)
if (d > radiusSq) radiusSq = d;
}
return {
box: { min, max },
sphere: { center, radius: Math.sqrt(radiusSq) }
};
}
function computeInvariantUnitBoundary(u: Unit): Boundary {
return computeElementsPositionBoundary(u.elements, u.conformation.invariantPosition)
}
export function computeUnitBoundary(u: Unit): Boundary {
return computeElementsPositionBoundary(u.elements, u.conformation.position)
}
const tmpBox = Box3D.empty()
const tmpSphere = Sphere3D.zero()
export function computeStructureBoundary(s: Structure): Boundary {
const min = Vec3.create(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)
const max = Vec3.create(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE)
const center = Vec3.zero()
const { units } = s;
const boundaryMap: Map<number, Boundary> = new Map()
function getInvariantBoundary(u: Unit) {
let boundary: Boundary
if (boundaryMap.has(u.invariantId)) {
boundary = boundaryMap.get(u.invariantId)!
} else {
boundary = computeInvariantUnitBoundary(u)
boundaryMap.set(u.invariantId, boundary)
}
return boundary
}
let radiusSq = 0;
let size = 0;
for (let i = 0, _i = units.length; i < _i; i++) {
size += 1
const u = units[i]
const invariantBoundary = getInvariantBoundary(u)
const m = u.conformation.operator.matrix
Box3D.transform(tmpBox, invariantBoundary.box, m)
Vec3.min(min, min, tmpBox.min)
Vec3.max(max, max, tmpBox.max)
Sphere3D.transform(tmpSphere, invariantBoundary.sphere, m)
Vec3.add(center, center, tmpSphere.center)
}
if (size > 0) Vec3.scale(center, center, 1/size)
for (let i = 0, _i = units.length; i < _i; i++) {
const u = units[i]
const invariantBoundary = getInvariantBoundary(u)
const m = u.conformation.operator.matrix
Sphere3D.transform(tmpSphere, invariantBoundary.sphere, m)
const d = Vec3.squaredDistance(tmpSphere.center, center) + (tmpSphere.radius * tmpSphere.radius) * 4
if (d > radiusSq) radiusSq = d
}
const b = {
box: { min, max },
sphere: { center, radius: Math.sqrt(radiusSq) }
};
console.log(b, computeStructureBoundary2(s))
return b
}
export function computeStructureBoundary2(s: Structure): Boundary {
const min = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
const max = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
......@@ -62,6 +164,4 @@ function computeStructureBoundary(s: Structure): { box: Box3D, sphere: Sphere3D
box: { min: Vec3.ofArray(min), max: Vec3.ofArray(max) },
sphere: { center: Vec3.create(cx, cy, cz), radius: Math.sqrt(radiusSq) }
};
}
export { computeStructureBoundary }
\ No newline at end of file
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment