diff --git a/package-lock.json b/package-lock.json index 7abd6eeb33cb576c79906f6d1926c2bb5aa6f5bc..827a99ea20dff3ef1aae28cd7b173933e62aa801 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index 8d149012463de799160e12c086b3f8724f97eb26..7157fd480347ed9f35d5e7f5b82f10d92a4c2d0e 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "@types/benchmark": "^1.0.31", "@types/compression": "0.0.36", "@types/express": "^4.16.0", - "@types/jest": "^23.3.1", + "@types/jest": "^23.3.2", "@types/node": "^10.9.4", "@types/node-fetch": "^2.1.2", "@types/react": "^16.4.13", @@ -95,7 +95,7 @@ "mini-css-extract-plugin": "^0.4.2", "node-sass": "^4.9.3", "raw-loader": "^0.5.1", - "resolve-url-loader": "^2.3.0", + "resolve-url-loader": "^2.3.1", "sass-loader": "^7.1.0", "style-loader": "^0.23.0", "ts-jest": "^23.1.4", @@ -103,7 +103,7 @@ "typescript": "^3.0.3", "uglify-js": "^3.4.9", "util.promisify": "^1.0.0", - "webpack": "^4.17.1", + "webpack": "^4.17.2", "webpack-cli": "^3.1.0" }, "dependencies": { @@ -114,8 +114,8 @@ "graphql-request": "^1.8.2", "immutable": "^4.0.0-rc.9", "node-fetch": "^2.2.0", - "react": "^16.4.2", - "react-dom": "^16.4.2", - "rxjs": "^6.3.1" + "react": "^16.5.0", + "react-dom": "^16.5.0", + "rxjs": "^6.3.2" } } diff --git a/src/apps/canvas/component/app.tsx b/src/apps/canvas/component/app.tsx index 6fe5f0872a62a8a5d552767872e1798c8c845426..c1d099b6a7e3e5d77e38a14040e21dbce3ebb4d8 100644 --- a/src/apps/canvas/component/app.tsx +++ b/src/apps/canvas/component/app.tsx @@ -9,17 +9,7 @@ import { StructureView } from '../structure-view'; import { App } from '../app'; import { Viewport } from './viewport'; import { StructureViewComponent } from './structure-view'; - -// export function FileInput (props: { -// accept: string -// onChange: (v: FileList | null) => void, -// }) { -// return <input -// accept={props.accept || '*.*'} -// type='file' -// onChange={e => props.onChange.call(null, e.target.files)} -// /> -// } +import { Examples } from '../examples'; export interface AppProps { app: App @@ -75,6 +65,20 @@ export class AppComponent extends React.Component<AppProps, AppState> { }} /> </div> + <div> + <span>Load example </span> + <select + style={{width: '200px'}} + onChange={e => { + this.props.app.loadPdbId(e.target.value) + }} + > + <option value=''></option> + {Examples.map(({pdbId, description}, i) => { + return <option key={i} value={pdbId}>{`${pdbId} - ${description}`}</option> + })} + </select> + </div> <hr/> <div style={{marginBottom: '10px'}}> {structureView ? <StructureViewComponent structureView={structureView} /> : ''} diff --git a/src/apps/canvas/component/structure-representation.tsx b/src/apps/canvas/component/structure-representation.tsx index 25eb022ae279bbae55b8af05fc50cfc8a369d901..bdc194b701b259a28ff093d15372dcc861b75672 100644 --- a/src/apps/canvas/component/structure-representation.tsx +++ b/src/apps/canvas/component/structure-representation.tsx @@ -19,6 +19,7 @@ export interface StructureRepresentationComponentProps { export interface StructureRepresentationComponentState { label: string visible: boolean + alpha: number quality: VisualQuality colorTheme: ColorThemeProps } @@ -27,6 +28,7 @@ export class StructureRepresentationComponent extends React.Component<StructureR state = { label: this.props.representation.label, visible: this.props.representation.props.visible, + alpha: this.props.representation.props.alpha, quality: this.props.representation.props.quality, colorTheme: this.props.representation.props.colorTheme, } @@ -38,6 +40,7 @@ export class StructureRepresentationComponent extends React.Component<StructureR ...this.state, label: repr.label, visible: repr.props.visible, + alpha: repr.props.alpha, quality: repr.props.quality, colorTheme: repr.props.colorTheme, }) @@ -49,6 +52,7 @@ export class StructureRepresentationComponent extends React.Component<StructureR if (state.visible !== undefined) props.visible = state.visible if (state.quality !== undefined) props.quality = state.quality + if (state.alpha !== undefined) props.alpha = state.alpha if (state.colorTheme !== undefined) props.colorTheme = state.colorTheme await repr.createOrUpdate(props).run() @@ -60,13 +64,14 @@ export class StructureRepresentationComponent extends React.Component<StructureR ...this.state, visible: repr.props.visible, quality: repr.props.quality, + alpha: repr.props.alpha, colorTheme: repr.props.colorTheme, } this.setState(newState) } render() { - const { label, visible, quality, colorTheme } = this.state + const { label, visible, quality, alpha, colorTheme } = this.state const ct = ColorTheme(colorTheme) @@ -91,6 +96,17 @@ export class StructureRepresentationComponent extends React.Component<StructureR {VisualQualityNames.map(name => <option key={name} value={name}>{name}</option>)} </select> </div> + <div> + <span>Opacity </span> + <input type='range' + defaultValue={alpha.toString()} + min='0' + max='1' + step='0.05' + onInput={(e) => this.update({ alpha: parseFloat(e.currentTarget.value) })} + > + </input> + </div> <div> <span>Color Theme </span> <select value={colorTheme.name} onChange={(e) => this.update({ colorTheme: { name: e.target.value as ColorThemeName } }) }> diff --git a/src/apps/canvas/examples.ts b/src/apps/canvas/examples.ts new file mode 100644 index 0000000000000000000000000000000000000000..7fefc15700eaa03921e809617ff396e5873e458a --- /dev/null +++ b/src/apps/canvas/examples.ts @@ -0,0 +1,169 @@ + + +export interface Example { + pdbId: string + description: string +} + +export const Examples: Example[] = [ + { + pdbId: '1jj2', + description: 'ribosome' + }, + { + pdbId: '1grm', + description: 'helix-like sheets' + }, + { + pdbId: '4umt', + description: 'ligand has bond with order 3' + }, + { + pdbId: '1crn', + description: 'small' + }, + { + pdbId: '1hrv', + description: 'viral assembly' + }, + { + pdbId: '1rb8', + description: 'virus' + }, + { + pdbId: '1blu', + description: 'metal coordination' + }, + { + pdbId: '3pqr', + description: 'inter unit bonds, two polymer chains, ligands, water, carbohydrates linked to protein' + }, + { + pdbId: '4v5a', + description: 'ribosome' + }, + { + pdbId: '3j3q', + description: '...' + }, + { + pdbId: '2np2', + description: 'dna' + }, + { + pdbId: '1d66', + description: 'dna' + }, + { + pdbId: '9dna', + description: 'A form dna' + }, + { + pdbId: '1bna', + description: 'B form dna' + }, + { + pdbId: '199d', + description: 'C form dna' + }, + { + pdbId: '4lb6', + description: 'Z form dna' + }, + { + pdbId: '1egk', + description: '4-way dna-rna junction' + }, + { + pdbId: '1y26', + description: 'rna' + }, + { + pdbId: '1xv6', + description: 'rna, modified nucleotides' + }, + { + pdbId: '3bbm', + description: 'rna with linker' + }, + { + pdbId: '1euq', + description: 't-rna' + }, + { + pdbId: '2e2i', + description: 'rna, dna, protein' + }, + { + pdbId: '1gfl', + description: 'GFP, flourophore has carbonyl oxygen removed' + }, + { + pdbId: '1sfi', + description: 'contains cyclic peptid' + }, + { + pdbId: '3sn6', + description: 'discontinuous chains' + }, + { + pdbId: '2zex', + description: 'contains carbohydrate polymer' + }, + { + pdbId: '3sgj', + description: 'contains carbohydrate polymer' + }, + { + pdbId: '3ina', + description: 'contains GlcN and IdoA' + }, + { + pdbId: '1umz', + description: 'contains Xyl (Xyloglucan)' + }, + { + pdbId: '1mfb', + description: 'contains Abe' + }, + { + pdbId: '2gdu', + description: 'contains sucrose' + }, + { + pdbId: '2fnc', + description: 'contains maltotriose' + }, + { + pdbId: '4zs9', + description: 'contains raffinose' + }, + { + pdbId: '2yft', + description: 'contains kestose' + }, + { + pdbId: '2b5t', + description: 'contains large carbohydrate polymer' + }, + { + pdbId: '1b5f', + description: 'contains carbohydrate with alternate locations' + }, + { + pdbId: '5u0q', + description: 'mixed dna/rna in same polymer' + }, + { + pdbId: '1xj9', + description: 'PNA (peptide nucleic acid)' + }, + { + pdbId: '5eme', + description: 'PNA (peptide nucleic acid) and RNA' + }, + { + pdbId: '2X3T', + description: 'temp' + }, +] \ No newline at end of file diff --git a/src/apps/canvas/structure-view.ts b/src/apps/canvas/structure-view.ts index b381ab2f082e2918092e7e695c1de8b82a8ffd45..c5674578f27d99dae9056db73f63464279da2c44 100644 --- a/src/apps/canvas/structure-view.ts +++ b/src/apps/canvas/structure-view.ts @@ -24,6 +24,7 @@ import { StructureRepresentation } from 'mol-geo/representation/structure'; import { BehaviorSubject } from 'rxjs'; import { SpacefillRepresentation } from 'mol-geo/representation/structure/representation/spacefill'; import { DistanceRestraintRepresentation } from 'mol-geo/representation/structure/representation/distance-restraint'; +import { SurfaceRepresentation } from 'mol-geo/representation/structure/representation/surface'; export interface StructureView { readonly viewer: Viewer @@ -66,6 +67,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model> const active: { [k: string]: boolean } = { cartoon: true, point: false, + surface: true, ballAndStick: false, carbohydrate: false, spacefill: false, @@ -76,6 +78,7 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model> const structureRepresentations: { [k: string]: StructureRepresentation<any> } = { cartoon: CartoonRepresentation(), + surface: SurfaceRepresentation(), point: PointRepresentation(), ballAndStick: BallAndStickRepresentation(), carbohydrate: CarbohydrateRepresentation(), diff --git a/src/mol-geo/representation/structure/representation/surface.ts b/src/mol-geo/representation/structure/representation/surface.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e95466e6ffa51421b7973b8436b2a5ef1e9a6d8 --- /dev/null +++ b/src/mol-geo/representation/structure/representation/surface.ts @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { UnitsRepresentation } from '..'; +import { GaussianSurfaceVisual, DefaultGaussianSurfaceProps } from '../visual/gaussian-surface-mesh'; +import { StructureRepresentation } from '../units-representation'; +import { Structure } from 'mol-model/structure'; +import { MarkerAction } from '../../../util/marker-data'; +import { Loci } from 'mol-model/loci'; +import { PickingId } from '../../../util/picking'; + +export const DefaultSurfaceProps = { + ...DefaultGaussianSurfaceProps, +} +export type SurfaceProps = typeof DefaultSurfaceProps + +export type SurfaceRepresentation = StructureRepresentation<SurfaceProps> + +export function SurfaceRepresentation(): SurfaceRepresentation { + let currentProps: SurfaceProps + const gaussianRepr = UnitsRepresentation('Gaussian surface', GaussianSurfaceVisual) + return { + label: 'Surface', + get renderObjects() { + return [ ...gaussianRepr.renderObjects ] + }, + get props() { + return { ...gaussianRepr.props } + }, + createOrUpdate: (props: Partial<SurfaceProps> = {}, structure?: Structure) => { + currentProps = Object.assign({}, DefaultSurfaceProps, currentProps, props) + return gaussianRepr.createOrUpdate(currentProps, structure) + }, + getLoci: (pickingId: PickingId) => { + return gaussianRepr.getLoci(pickingId) + }, + mark: (loci: Loci, action: MarkerAction) => { + return gaussianRepr.mark(loci, action) + }, + destroy() { + gaussianRepr.destroy() + } + } +} \ No newline at end of file diff --git a/src/mol-geo/representation/structure/units-visual.ts b/src/mol-geo/representation/structure/units-visual.ts index 534764f3d57028e1ad33103d4e90125d3c69d4fe..a98620a7f37577c8370be896af55bbbc0213c6a0 100644 --- a/src/mol-geo/representation/structure/units-visual.ts +++ b/src/mol-geo/representation/structure/units-visual.ts @@ -32,7 +32,7 @@ export type UnitsMeshProps = typeof DefaultUnitsMeshProps export interface UnitsMeshVisualBuilder<P extends UnitsMeshProps> { defaultProps: P - createMesh(ctx: RuntimeContext, unit: Unit, props: P, mesh?: Mesh): Promise<Mesh> + createMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: P, mesh?: Mesh): Promise<Mesh> createLocationIterator(group: Unit.SymmetryGroup): LocationIterator getLoci(pickingId: PickingId, group: Unit.SymmetryGroup, id: number): Loci mark(loci: Loci, group: Unit.SymmetryGroup, apply: (interval: Interval) => boolean): boolean @@ -59,7 +59,7 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu const unit = group.units[0] currentConformationId = Unit.conformationId(unit) mesh = currentProps.unitKinds.includes(unit.kind) - ? await createMesh(ctx, unit, currentProps, mesh) + ? await createMesh(ctx, unit, currentStructure, currentProps, mesh) : Mesh.createEmpty(mesh) // TODO create empty location iterator when not in unitKinds @@ -102,7 +102,7 @@ export function UnitsMeshVisual<P extends UnitsMeshProps>(builder: UnitsMeshVisu if (updateState.createMesh) { mesh = newProps.unitKinds.includes(unit.kind) - ? await createMesh(ctx, unit, newProps, mesh) + ? await createMesh(ctx, unit, currentStructure, newProps, mesh) : Mesh.createEmpty(mesh) ValueCell.update(renderObject.values.drawCount, mesh.triangleCount * 3) updateState.updateColor = true diff --git a/src/mol-geo/representation/structure/visual/element-point.ts b/src/mol-geo/representation/structure/visual/element-point.ts index d0b74c089e9f37c81a817f653f54702e4574fabf..eac5fb80226aad8dc30f67570d11f9c7469cdfe2 100644 --- a/src/mol-geo/representation/structure/visual/element-point.ts +++ b/src/mol-geo/representation/structure/visual/element-point.ts @@ -23,7 +23,7 @@ import { SizeThemeProps } from 'mol-view/theme/size'; import { LocationIterator } from '../../../util/location-iterator'; import { createTransforms } from '../../../util/transform-data'; import { StructureGroup } from '../units-visual'; -import { updateRenderableState } from '../../util'; +import { updateRenderableState, updateBaseValues } from '../../util'; export const DefaultElementPointProps = { ...DefaultStructureProps, @@ -130,6 +130,7 @@ export function ElementPointVisual(): UnitsVisual<ElementPointProps> { await createSizes(ctx, locationIt, newProps.sizeTheme, renderObject.values) } + updateBaseValues(renderObject.values, newProps) updateRenderableState(renderObject.state, newProps) currentProps = newProps diff --git a/src/mol-geo/representation/structure/visual/gaussian-surface-mesh.ts b/src/mol-geo/representation/structure/visual/gaussian-surface-mesh.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b894f5a573b51e7f975fa8e5f64cf4340c04caf --- /dev/null +++ b/src/mol-geo/representation/structure/visual/gaussian-surface-mesh.ts @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Unit, Structure } from 'mol-model/structure'; +import { UnitsVisual, MeshUpdateState } from '..'; +import { RuntimeContext } from 'mol-task' +import { Mesh } from '../../../mesh/mesh'; +import { UnitsMeshVisual, DefaultUnitsMeshProps } from '../units-visual'; +import { StructureElementIterator, getElementLoci, markElement } from './util/element'; +import { computeMarchingCubes } from '../../../util/marching-cubes/algorithm'; +import { Tensor, Vec3, Mat4 } from 'mol-math/linear-algebra'; +import { Box3D } from 'mol-math/geometry'; +import { ValueCell } from 'mol-util'; +import { smoothstep } from 'mol-math/interpolate'; + +export interface GaussianSurfaceMeshProps { + +} + +function getDelta(box: Box3D) { + const extent = Vec3.sub(Vec3.zero(), box.max, box.min) + + const n = Math.pow(128, 3) + const f = (extent[0] * extent[1] * extent[2]) / n + const s = Math.pow(f, 1 / 3) + const size = Vec3.zero() + // Vec3.scale(size, extent, s) + Vec3.ceil(size, Vec3.scale(size, extent, s)) + const delta = Vec3.div(Vec3.zero(), extent, size) + return delta +} + +async function createGaussianSurfaceMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianSurfaceMeshProps, mesh?: Mesh): Promise<Mesh> { + + const { elements } = unit; + const elementCount = elements.length; + + const r = 2.5; + + const v = Vec3.zero() + const p = Vec3.zero() + const pos = unit.conformation.invariantPosition + const box = unit.lookup3d.boundary.box + const expandedBox = Box3D.expand(Box3D.empty(), box, Vec3.create(r*3, r*3, r*3)); + const extent = Vec3.sub(Vec3.zero(), expandedBox.max, expandedBox.min) + const min = expandedBox.min + + // const n = Math.pow(128, 3) + // const f = (extent[0] * extent[1] * extent[2]) / n + // const s = Math.pow(f, 1 / 3) + // const size = Vec3.zero() + // // Vec3.scale(size, extent, s) + // Vec3.ceil(size, Vec3.scale(size, extent, s)) + // const delta = Vec3.div(Vec3.zero(), extent, size) + + // console.log('extent', extent) + // console.log('n', n) + // console.log('f', f) + // console.log('s', s) + // console.log('size', size) + // console.log('delta', delta) + const delta = getDelta(Box3D.expand(Box3D.empty(), structure.boundary.box, Vec3.create(r*3, r*3, r*3))) + const dim = Vec3.zero() + Vec3.ceil(dim, Vec3.mul(dim, extent, delta)) + // console.log('dim', dim, dim[0] * dim[1] * dim[2]) + + const space = Tensor.Space(dim, [0, 1, 2], Float32Array) + const data = space.create() + const field = Tensor.create(space, data) + + for (let i = 0; i < elementCount; i++) { + pos(elements[i], v) + + Vec3.mul(v, Vec3.sub(v, v, min), delta) + + const size = r + const radius = size * delta[0] + + const minX = Math.floor(v[0] - radius) + const minY = Math.floor(v[1] - radius) + const minZ = Math.floor(v[2] - radius) + const maxX = Math.floor(v[0] + radius) + const maxY = Math.floor(v[1] + radius) + const maxZ = Math.floor(v[2] + radius) + + for (let x = minX; x <= maxX; ++x) { + for (let y = minY; y <= maxY; ++y) { + for (let z = minZ; z <= maxZ; ++z) { + const dist = Vec3.distance(Vec3.set(p, x, y, z), v) + if (dist <= radius) { + const density = 1.0 - smoothstep(0.0, radius * 1.0, dist) + space.set(data, x, y, z, space.get(data, x, y, z) + density) + } + } + } + } + + if (i % 10000 === 0 && ctx.shouldUpdate) { + await ctx.update({ message: 'Gaussian surface', current: i, max: elementCount }); + } + } + + // console.log('data', data) + + const surface = await computeMarchingCubes({ + isoLevel: 0.1, + scalarField: field, + oldSurface: mesh + + }).runAsChild(ctx); + + const t = Mat4.identity() + Mat4.fromUniformScaling(t, 1 / delta[0]) + Mat4.setTranslation(t, expandedBox.min) + + ValueCell.update(surface.groupBuffer, new Float32Array(surface.vertexCount)) + Mesh.transformImmediate(surface, t) + await Mesh.computeNormals(surface).runAsChild(ctx) + + // console.log('surface', surface) + + // const transform = VolumeData.getGridToCartesianTransform(volume); + // ctx.update({ message: 'Transforming mesh...' }); + // Mesh.transformImmediate(surface, transform); + + return surface; +} + +export const DefaultGaussianSurfaceProps = { + ...DefaultUnitsMeshProps, + linearSegments: 8, + radialSegments: 12, + aspectRatio: 5, + arrowFactor: 1.5, + + flipSided: true, + // flatShaded: true, +} +export type GaussianSurfaceProps = typeof DefaultGaussianSurfaceProps + +export function GaussianSurfaceVisual(): UnitsVisual<GaussianSurfaceProps> { + return UnitsMeshVisual<GaussianSurfaceProps>({ + defaultProps: DefaultGaussianSurfaceProps, + createMesh: createGaussianSurfaceMesh, + createLocationIterator: StructureElementIterator.fromGroup, + getLoci: getElementLoci, + mark: markElement, + setUpdateState: (state: MeshUpdateState, newProps: GaussianSurfaceProps, currentProps: GaussianSurfaceProps) => {} + }) +} \ No newline at end of file diff --git a/src/mol-geo/representation/structure/visual/intra-unit-link-cylinder.ts b/src/mol-geo/representation/structure/visual/intra-unit-link-cylinder.ts index 9b9452a4191d579a07837137b34ccb22082261ae..a3d6dd8687bc1624fd75fb2b45c2a96e383af1c8 100644 --- a/src/mol-geo/representation/structure/visual/intra-unit-link-cylinder.ts +++ b/src/mol-geo/representation/structure/visual/intra-unit-link-cylinder.ts @@ -5,7 +5,7 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import { Unit, Link, StructureElement } from 'mol-model/structure'; +import { Unit, Link, StructureElement, Structure } from 'mol-model/structure'; import { UnitsVisual, MeshUpdateState } from '..'; import { RuntimeContext } from 'mol-task' import { DefaultLinkCylinderProps, LinkCylinderProps, createLinkCylinderMesh, LinkIterator } from './util/link'; @@ -18,7 +18,7 @@ import { Interval } from 'mol-data/int'; import { SizeThemeProps, SizeTheme } from 'mol-view/theme/size'; import { BitFlags } from 'mol-util'; -async function createIntraUnitLinkCylinderMesh(ctx: RuntimeContext, unit: Unit, props: LinkCylinderProps, mesh?: Mesh) { +async function createIntraUnitLinkCylinderMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: LinkCylinderProps, mesh?: Mesh) { if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh) const sizeTheme = SizeTheme(props.sizeTheme) diff --git a/src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts b/src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts index 8b5d893ef85dc1b6ae8b18ea8a651c3427e8872d..dcf176ba3d1fef8188b3b2886be11e7d46beb4c6 100644 --- a/src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts +++ b/src/mol-geo/representation/structure/visual/nucleotide-block-mesh.ts @@ -4,7 +4,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Unit } from 'mol-model/structure'; +import { Unit, Structure } from 'mol-model/structure'; import { UnitsVisual } from '..'; import { RuntimeContext } from 'mol-task' import { Mesh } from '../../../mesh/mesh'; @@ -33,7 +33,7 @@ const sVec = Vec3.zero() const box = Box() // TODO define props, should be scalable -async function createNucleotideBlockMesh(ctx: RuntimeContext, unit: Unit, props: {}, mesh?: Mesh) { +async function createNucleotideBlockMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: {}, mesh?: Mesh) { if (!Unit.isAtomic(unit)) return Mesh.createEmpty(mesh) // TODO better vertex count estimate diff --git a/src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts b/src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts index d975ae940228601a3fd1a833979d28dc2c0dc96e..cd9ca682c0cab90544d44ab88e7958a4858ef956 100644 --- a/src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts +++ b/src/mol-geo/representation/structure/visual/polymer-backbone-cylinder.ts @@ -4,7 +4,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Unit } from 'mol-model/structure'; +import { Unit, Structure } from 'mol-model/structure'; import { UnitsVisual, MeshUpdateState } from '..'; import { RuntimeContext } from 'mol-task' import { Mesh } from '../../../mesh/mesh'; @@ -23,7 +23,7 @@ export interface PolymerBackboneCylinderProps { radialSegments: number } -async function createPolymerBackboneCylinderMesh(ctx: RuntimeContext, unit: Unit, props: PolymerBackboneCylinderProps, mesh?: Mesh) { +async function createPolymerBackboneCylinderMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerBackboneCylinderProps, mesh?: Mesh) { const polymerElementCount = unit.polymerElements.length if (!polymerElementCount) return Mesh.createEmpty(mesh) diff --git a/src/mol-geo/representation/structure/visual/polymer-direction-wedge.ts b/src/mol-geo/representation/structure/visual/polymer-direction-wedge.ts index 1e6b8e42a198d66249becde9ff3219b723a659ee..bf6afd3f8f2c21565851435caa2f10bbe60fa8cb 100644 --- a/src/mol-geo/representation/structure/visual/polymer-direction-wedge.ts +++ b/src/mol-geo/representation/structure/visual/polymer-direction-wedge.ts @@ -4,7 +4,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Unit } from 'mol-model/structure'; +import { Unit, Structure } from 'mol-model/structure'; import { UnitsVisual } from '..'; import { RuntimeContext } from 'mol-task' import { Mesh } from '../../../mesh/mesh'; @@ -32,7 +32,7 @@ export interface PolymerDirectionWedgeProps { sizeTheme: SizeThemeProps } -async function createPolymerDirectionWedgeMesh(ctx: RuntimeContext, unit: Unit, props: PolymerDirectionWedgeProps, mesh?: Mesh) { +async function createPolymerDirectionWedgeMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerDirectionWedgeProps, mesh?: Mesh) { const polymerElementCount = unit.polymerElements.length if (!polymerElementCount) return Mesh.createEmpty(mesh) diff --git a/src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts b/src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts index 24038dfc3182746c74d2ae0336a5556ff00cfcde..21ebafc2d3ffd91d4160defa3e9412568df14d86 100644 --- a/src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts +++ b/src/mol-geo/representation/structure/visual/polymer-gap-cylinder.ts @@ -4,7 +4,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Unit } from 'mol-model/structure'; +import { Unit, Structure } from 'mol-model/structure'; import { UnitsVisual, MeshUpdateState } from '..'; import { RuntimeContext } from 'mol-task' import { Mesh } from '../../../mesh/mesh'; @@ -24,7 +24,7 @@ export interface PolymerGapCylinderProps { radialSegments: number } -async function createPolymerGapCylinderMesh(ctx: RuntimeContext, unit: Unit, props: PolymerGapCylinderProps, mesh?: Mesh) { +async function createPolymerGapCylinderMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerGapCylinderProps, mesh?: Mesh) { const polymerGapCount = unit.gapElements.length if (!polymerGapCount) return Mesh.createEmpty(mesh) diff --git a/src/mol-geo/representation/structure/visual/polymer-trace-mesh.ts b/src/mol-geo/representation/structure/visual/polymer-trace-mesh.ts index 1a37e4d9809fa189a779c2dcb2b969ccc382dcba..685b0d3c4f6889f3d55586505053c00cb5aba739 100644 --- a/src/mol-geo/representation/structure/visual/polymer-trace-mesh.ts +++ b/src/mol-geo/representation/structure/visual/polymer-trace-mesh.ts @@ -4,7 +4,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Unit } from 'mol-model/structure'; +import { Unit, Structure } from 'mol-model/structure'; import { UnitsVisual, MeshUpdateState } from '..'; import { RuntimeContext } from 'mol-task' import { Mesh } from '../../../mesh/mesh'; @@ -26,7 +26,7 @@ export interface PolymerTraceMeshProps { // TODO handle polymer ends properly -async function createPolymerTraceMesh(ctx: RuntimeContext, unit: Unit, props: PolymerTraceMeshProps, mesh?: Mesh) { +async function createPolymerTraceMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: PolymerTraceMeshProps, mesh?: Mesh) { const polymerElementCount = unit.polymerElements.length if (!polymerElementCount) return Mesh.createEmpty(mesh) diff --git a/src/mol-geo/representation/structure/visual/util/element.ts b/src/mol-geo/representation/structure/visual/util/element.ts index 0de1861eefddaeac2d28b8d6e8f20790f4eca963..6887addab337f1956adcb4c1645e2586c9bbd4ab 100644 --- a/src/mol-geo/representation/structure/visual/util/element.ts +++ b/src/mol-geo/representation/structure/visual/util/element.ts @@ -5,7 +5,7 @@ */ import { Vec3 } from 'mol-math/linear-algebra'; -import { Unit, StructureElement } from 'mol-model/structure'; +import { Unit, StructureElement, Structure } from 'mol-model/structure'; import { RuntimeContext } from 'mol-task'; import { sphereVertexCount } from '../../../../primitive/sphere'; import { Mesh } from '../../../../mesh/mesh'; @@ -22,7 +22,7 @@ export interface ElementSphereMeshProps { detail: number, } -export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, props: ElementSphereMeshProps, mesh?: Mesh) { +export async function createElementSphereMesh(ctx: RuntimeContext, unit: Unit, structure: Structure, props: ElementSphereMeshProps, mesh?: Mesh) { const { detail } = props const { elements } = unit; diff --git a/src/mol-gl/shader/chunks/assign-material-color.glsl b/src/mol-gl/shader/chunks/assign-material-color.glsl index 11b1779411269ab223e03cbbc42a90865a286d69..bc56340c25f74d749e9c8cc6377ac9ca265b2035 100644 --- a/src/mol-gl/shader/chunks/assign-material-color.glsl +++ b/src/mol-gl/shader/chunks/assign-material-color.glsl @@ -1,5 +1,7 @@ #if defined(dColorType_uniform) vec4 material = vec4(uColor, uAlpha); -#elif defined(dColorType_attribute) || defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance) || defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking) +#elif defined(dColorType_attribute) || defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance) + vec4 material = vec4(vColor.rgb, uAlpha); +#elif defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking) vec4 material = vColor; #endif \ No newline at end of file diff --git a/src/mol-model/structure/structure/carbohydrates/constants.ts b/src/mol-model/structure/structure/carbohydrates/constants.ts index ed3949f122fb46a6bd1c7de14cce975daf741952..d68c1f81a0eaddfbdf46a2070605caa12e444723 100644 --- a/src/mol-model/structure/structure/carbohydrates/constants.ts +++ b/src/mol-model/structure/structure/carbohydrates/constants.ts @@ -182,7 +182,7 @@ export const MonosaccharidesColorTable: [string, Color][] = [ ['Alt-family', SaccharideColors.Pink], ['All-family', SaccharideColors.Purple], ['Tal-family', SaccharideColors.LightBlue], - ['Ido-family', SaccharideColors.Blue], + ['Ido-family', SaccharideColors.Brown], ['Fuc-family', SaccharideColors.Red], ['Generic/Unknown/Secondary', SaccharideColors.Secondary], ]