mirror of
https://github.com/molstar/molstar.git
synced 2026-06-05 14:04:36 +08:00
Compare commits
15 Commits
clamp-cube
...
v3.24.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c835c848e | ||
|
|
0f1788f122 | ||
|
|
3d72e700a4 | ||
|
|
a5cf41e65f | ||
|
|
7029bc41d7 | ||
|
|
b87d40c844 | ||
|
|
9e154376d3 | ||
|
|
4a9fdbce57 | ||
|
|
775e335292 | ||
|
|
e553bf4deb | ||
|
|
db0e09ec6e | ||
|
|
ba50760f92 | ||
|
|
524e6d4f81 | ||
|
|
423f5b0502 | ||
|
|
2bc45c25fe |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -6,18 +6,24 @@ Note that since we don't clearly distinguish between a public and private interf
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v3.24.0] - 2022-11-13
|
||||
|
||||
- Make `PluginContext.initContainer` checkered canvas background optional
|
||||
- Store URL of downloaded assets to detect zip/gzip based on extension
|
||||
- Add optional `operator.key`; can be referenced in `IndexPairBonds`
|
||||
- Add overpaint/transparency/substance theme strength to representations
|
||||
- Fix viewport color for transparent background
|
||||
|
||||
## [v3.23.0] - 2022-10-19
|
||||
|
||||
- Add `PluginContext.initContainer/mount/unmount` methods; these should make it easier to reuse a plugin context with both custom and built-in UI
|
||||
- Add `PluginContext.canvas3dInitialized`
|
||||
- `createPluginUI` now resolves after the 3d canvas has been initialized
|
||||
- Change EM Volume Streaming default from `Whote Structure` to `Auto`
|
||||
- Change EM Volume Streaming default from `Whole Structure` to `Auto`
|
||||
|
||||
## [v3.22.0] - 2022-10-17
|
||||
|
||||
- Replace `VolumeIsosurfaceParams.pickingGranularity` param with `Volume.PickingGranuality`
|
||||
- Replace `VolumeIsosurfaceParams.pickingGranularity` param with `Volume.PickingGranuality`
|
||||
|
||||
## [v3.21.0] - 2022-10-17
|
||||
|
||||
|
||||
2208
package-lock.json
generated
2208
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
46
package.json
46
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "molstar",
|
||||
"version": "3.23.0",
|
||||
"version": "3.24.0",
|
||||
"description": "A comprehensive macromolecular library.",
|
||||
"homepage": "https://github.com/molstar/molstar#readme",
|
||||
"repository": {
|
||||
@@ -97,44 +97,44 @@
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/add": "^3.2.1",
|
||||
"@graphql-codegen/cli": "^2.13.7",
|
||||
"@graphql-codegen/cli": "^2.13.11",
|
||||
"@graphql-codegen/time": "^3.2.1",
|
||||
"@graphql-codegen/typescript": "^2.7.4",
|
||||
"@graphql-codegen/typescript": "^2.8.1",
|
||||
"@graphql-codegen/typescript-graphql-files-modules": "^2.2.1",
|
||||
"@graphql-codegen/typescript-graphql-request": "^4.5.6",
|
||||
"@graphql-codegen/typescript-operations": "^2.5.4",
|
||||
"@graphql-codegen/typescript-graphql-request": "^4.5.8",
|
||||
"@graphql-codegen/typescript-operations": "^2.5.6",
|
||||
"@types/cors": "^2.8.12",
|
||||
"@types/gl": "^4.1.1",
|
||||
"@types/jest": "^29.1.2",
|
||||
"@types/react": "^18.0.21",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@typescript-eslint/eslint-plugin": "^5.40.0",
|
||||
"@typescript-eslint/parser": "^5.40.0",
|
||||
"@types/gl": "^6.0.1",
|
||||
"@types/jest": "^29.2.2",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.8",
|
||||
"@typescript-eslint/eslint-plugin": "^5.42.1",
|
||||
"@typescript-eslint/parser": "^5.42.1",
|
||||
"benchmark": "^2.1.4",
|
||||
"concurrently": "^7.4.0",
|
||||
"concurrently": "^7.5.0",
|
||||
"cpx2": "^4.2.0",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"eslint": "^8.25.0",
|
||||
"css-loader": "^6.7.2",
|
||||
"eslint": "^8.27.0",
|
||||
"extra-watch-webpack-plugin": "^1.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"graphql": "^16.6.0",
|
||||
"http-server": "^14.1.1",
|
||||
"jest": "^29.2.0",
|
||||
"jest": "^29.3.1",
|
||||
"mini-css-extract-plugin": "^2.6.1",
|
||||
"path-browserify": "^1.0.1",
|
||||
"raw-loader": "^4.0.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"sass": "^1.55.0",
|
||||
"sass-loader": "^13.1.0",
|
||||
"simple-git": "^3.14.1",
|
||||
"sass": "^1.56.1",
|
||||
"sass-loader": "^13.2.0",
|
||||
"simple-git": "^3.15.0",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"style-loader": "^3.3.1",
|
||||
"ts-jest": "^29.0.3",
|
||||
"typescript": "^4.8.4",
|
||||
"webpack": "^5.74.0",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-cli": "^4.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -142,7 +142,7 @@
|
||||
"@types/benchmark": "^2.1.2",
|
||||
"@types/compression": "1.7.2",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/node": "^16.11.66",
|
||||
"@types/node": "^16.18.3",
|
||||
"@types/node-fetch": "^2.6.2",
|
||||
"@types/swagger-ui-dist": "3.30.1",
|
||||
"argparse": "^2.0.1",
|
||||
@@ -151,12 +151,12 @@
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.18.2",
|
||||
"h264-mp4-encoder": "^1.0.12",
|
||||
"immer": "^9.0.15",
|
||||
"immer": "^9.0.16",
|
||||
"immutable": "^4.1.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"rxjs": "^7.5.7",
|
||||
"swagger-ui-dist": "^4.14.3",
|
||||
"tslib": "^2.4.0",
|
||||
"swagger-ui-dist": "^4.15.5",
|
||||
"tslib": "^2.4.1",
|
||||
"util.promisify": "^1.1.1",
|
||||
"xhr2": "^0.2.1"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -21,6 +21,7 @@ export type OverpaintData = {
|
||||
uOverpaintGridDim: ValueCell<Vec3>,
|
||||
uOverpaintGridTransform: ValueCell<Vec4>,
|
||||
dOverpaintType: ValueCell<string>,
|
||||
uOverpaintStrength: ValueCell<number>,
|
||||
}
|
||||
|
||||
export function applyOverpaintColor(array: Uint8Array, start: number, end: number, color: Color) {
|
||||
@@ -54,6 +55,7 @@ export function createOverpaint(count: number, type: OverpaintType, overpaintDat
|
||||
uOverpaintGridDim: ValueCell.create(Vec3.create(1, 1, 1)),
|
||||
uOverpaintGridTransform: ValueCell.create(Vec4.create(0, 0, 0, 1)),
|
||||
dOverpaintType: ValueCell.create(type),
|
||||
uOverpaintStrength: ValueCell.create(1),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -74,6 +76,7 @@ export function createEmptyOverpaint(overpaintData?: OverpaintData): OverpaintDa
|
||||
uOverpaintGridDim: ValueCell.create(Vec3.create(1, 1, 1)),
|
||||
uOverpaintGridTransform: ValueCell.create(Vec4.create(0, 0, 0, 1)),
|
||||
dOverpaintType: ValueCell.create('groupInstance'),
|
||||
uOverpaintStrength: ValueCell.create(1),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2021-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
@@ -21,6 +21,7 @@ export type SubstanceData = {
|
||||
uSubstanceGridDim: ValueCell<Vec3>,
|
||||
uSubstanceGridTransform: ValueCell<Vec4>,
|
||||
dSubstanceType: ValueCell<string>,
|
||||
uSubstanceStrength: ValueCell<number>,
|
||||
}
|
||||
|
||||
export function applySubstanceMaterial(array: Uint8Array, start: number, end: number, material: Material) {
|
||||
@@ -54,6 +55,7 @@ export function createSubstance(count: number, type: SubstanceType, substanceDat
|
||||
uSubstanceGridDim: ValueCell.create(Vec3.create(1, 1, 1)),
|
||||
uSubstanceGridTransform: ValueCell.create(Vec4.create(0, 0, 0, 1)),
|
||||
dSubstanceType: ValueCell.create(type),
|
||||
uSubstanceStrength: ValueCell.create(1),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -74,6 +76,7 @@ export function createEmptySubstance(substanceData?: SubstanceData): SubstanceDa
|
||||
uSubstanceGridDim: ValueCell.create(Vec3.create(1, 1, 1)),
|
||||
uSubstanceGridTransform: ValueCell.create(Vec4.create(0, 0, 0, 1)),
|
||||
dSubstanceType: ValueCell.create('groupInstance'),
|
||||
uSubstanceStrength: ValueCell.create(1),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ export type TransparencyData = {
|
||||
uTransparencyGridDim: ValueCell<Vec3>,
|
||||
uTransparencyGridTransform: ValueCell<Vec4>,
|
||||
dTransparencyType: ValueCell<string>,
|
||||
uTransparencyStrength: ValueCell<number>,
|
||||
}
|
||||
|
||||
export function applyTransparencyValue(array: Uint8Array, start: number, end: number, value: number) {
|
||||
@@ -63,6 +64,7 @@ export function createTransparency(count: number, type: TransparencyType, transp
|
||||
uTransparencyGridDim: ValueCell.create(Vec3.create(1, 1, 1)),
|
||||
uTransparencyGridTransform: ValueCell.create(Vec4.create(0, 0, 0, 1)),
|
||||
dTransparencyType: ValueCell.create(type),
|
||||
uTransparencyStrength: ValueCell.create(1),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -84,6 +86,7 @@ export function createEmptyTransparency(transparencyData?: TransparencyData): Tr
|
||||
uTransparencyGridDim: ValueCell.create(Vec3.create(1, 1, 1)),
|
||||
uTransparencyGridTransform: ValueCell.create(Vec4.create(0, 0, 0, 1)),
|
||||
dTransparencyType: ValueCell.create('groupInstance'),
|
||||
uTransparencyStrength: ValueCell.create(1),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -229,6 +229,7 @@ export const OverpaintSchema = {
|
||||
uOverpaintGridTransform: UniformSpec('v4'),
|
||||
tOverpaintGrid: TextureSpec('texture', 'rgba', 'ubyte', 'linear'),
|
||||
dOverpaintType: DefineSpec('string', ['instance', 'groupInstance', 'volumeInstance']),
|
||||
uOverpaintStrength: UniformSpec('f', 'material'),
|
||||
} as const;
|
||||
export type OverpaintSchema = typeof OverpaintSchema
|
||||
export type OverpaintValues = Values<OverpaintSchema>
|
||||
@@ -242,7 +243,8 @@ export const TransparencySchema = {
|
||||
uTransparencyGridDim: UniformSpec('v3'),
|
||||
uTransparencyGridTransform: UniformSpec('v4'),
|
||||
tTransparencyGrid: TextureSpec('texture', 'alpha', 'ubyte', 'linear'),
|
||||
dTransparencyType: DefineSpec('string', ['instance', 'groupInstance', 'volumeInstance'])
|
||||
dTransparencyType: DefineSpec('string', ['instance', 'groupInstance', 'volumeInstance']),
|
||||
uTransparencyStrength: UniformSpec('f', 'material'),
|
||||
} as const;
|
||||
export type TransparencySchema = typeof TransparencySchema
|
||||
export type TransparencyValues = Values<TransparencySchema>
|
||||
@@ -256,6 +258,7 @@ export const SubstanceSchema = {
|
||||
uSubstanceGridTransform: UniformSpec('v4'),
|
||||
tSubstanceGrid: TextureSpec('texture', 'rgba', 'ubyte', 'linear'),
|
||||
dSubstanceType: DefineSpec('string', ['instance', 'groupInstance', 'volumeInstance']),
|
||||
uSubstanceStrength: UniformSpec('f', 'material'),
|
||||
} as const;
|
||||
export type SubstanceSchema = typeof SubstanceSchema
|
||||
export type SubstanceValues = Values<SubstanceSchema>
|
||||
|
||||
@@ -42,6 +42,7 @@ export const assign_color_varying = `
|
||||
#else
|
||||
vOverpaint.rgb = mix(vColor.rgb, vOverpaint.rgb, vOverpaint.a);
|
||||
#endif
|
||||
vOverpaint *= uOverpaintStrength;
|
||||
#endif
|
||||
|
||||
#ifdef dSubstance
|
||||
@@ -58,6 +59,7 @@ export const assign_color_varying = `
|
||||
|
||||
// pre-mix to avoid artifacts due to empty substance
|
||||
vSubstance.rgb = mix(vec3(uMetalness, uRoughness, uBumpiness), vSubstance.rgb, vSubstance.a);
|
||||
vSubstance *= uSubstanceStrength;
|
||||
#endif
|
||||
#elif defined(dRenderVariant_pick)
|
||||
#ifdef requiredDrawBuffers
|
||||
@@ -86,5 +88,6 @@ export const assign_color_varying = `
|
||||
vec3 tgridPos = (uTransparencyGridTransform.w * (vModelPosition - uTransparencyGridTransform.xyz)) / uTransparencyGridDim;
|
||||
vTransparency = texture3dFrom2dLinear(tTransparencyGrid, tgridPos, uTransparencyGridDim, uTransparencyTexDim).a;
|
||||
#endif
|
||||
vTransparency *= uTransparencyStrength;
|
||||
#endif
|
||||
`;
|
||||
@@ -39,6 +39,7 @@ uniform float uBumpiness;
|
||||
uniform vec4 uOverpaintGridTransform;
|
||||
uniform sampler2D tOverpaintGrid;
|
||||
#endif
|
||||
uniform float uOverpaintStrength;
|
||||
#endif
|
||||
|
||||
#ifdef dSubstance
|
||||
@@ -53,6 +54,7 @@ uniform float uBumpiness;
|
||||
uniform vec4 uSubstanceGridTransform;
|
||||
uniform sampler2D tSubstanceGrid;
|
||||
#endif
|
||||
uniform float uSubstanceStrength;
|
||||
#endif
|
||||
#elif defined(dRenderVariant_pick)
|
||||
#if __VERSION__ == 100 || !defined(dVaryingGroup)
|
||||
@@ -86,5 +88,6 @@ uniform float uBumpiness;
|
||||
uniform vec4 uTransparencyGridTransform;
|
||||
uniform sampler2D tTransparencyGrid;
|
||||
#endif
|
||||
uniform float uTransparencyStrength;
|
||||
#endif
|
||||
`;
|
||||
@@ -19,6 +19,9 @@ export function isWebGL2(gl: any): gl is WebGL2RenderingContext {
|
||||
return typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/ANGLE_instanced_arrays/
|
||||
*/
|
||||
export interface COMPAT_instanced_arrays {
|
||||
drawArraysInstanced(mode: number, first: number, count: number, primcount: number): void;
|
||||
drawElementsInstanced(mode: number, count: number, type: number, offset: number, primcount: number): void;
|
||||
@@ -46,6 +49,9 @@ export function getInstancedArrays(gl: GLRenderingContext): COMPAT_instanced_arr
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/OES_standard_derivatives/
|
||||
*/
|
||||
export interface COMPAT_standard_derivatives {
|
||||
readonly FRAGMENT_SHADER_DERIVATIVE_HINT: number;
|
||||
}
|
||||
@@ -60,6 +66,9 @@ export function getStandardDerivatives(gl: GLRenderingContext): COMPAT_standard_
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/OES_element_index_uint/
|
||||
*/
|
||||
export interface COMPAT_element_index_uint {
|
||||
}
|
||||
|
||||
@@ -67,6 +76,9 @@ export function getElementIndexUint(gl: GLRenderingContext): COMPAT_element_inde
|
||||
return isWebGL2(gl) ? {} : gl.getExtension('OES_element_index_uint');
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/OES_vertex_array_object/
|
||||
*/
|
||||
export interface COMPAT_vertex_array_object {
|
||||
readonly VERTEX_ARRAY_BINDING: number;
|
||||
bindVertexArray(arrayObject: WebGLVertexArrayObject | null): void;
|
||||
@@ -132,6 +144,9 @@ export function getTextureHalfFloatLinear(gl: GLRenderingContext): COMPAT_textur
|
||||
return gl.getExtension('OES_texture_half_float_linear');
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/EXT_blend_minmax/
|
||||
*/
|
||||
export interface COMPAT_blend_minmax {
|
||||
readonly MIN: number
|
||||
readonly MAX: number
|
||||
@@ -147,6 +162,9 @@ export function getBlendMinMax(gl: GLRenderingContext): COMPAT_blend_minmax | nu
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/EXT_frag_depth/
|
||||
*/
|
||||
export interface COMPAT_frag_depth {
|
||||
}
|
||||
|
||||
@@ -196,6 +214,9 @@ export function getColorBufferHalfFloat(gl: GLRenderingContext): COMPAT_color_bu
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/WEBGL_draw_buffers/
|
||||
*/
|
||||
export interface COMPAT_draw_buffers {
|
||||
drawBuffers(buffers: number[]): void;
|
||||
readonly COLOR_ATTACHMENT0: number;
|
||||
@@ -268,6 +289,73 @@ export function getDrawBuffers(gl: GLRenderingContext): COMPAT_draw_buffers | nu
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/OES_draw_buffers_indexed/
|
||||
*/
|
||||
export interface COMPAT_draw_buffers_indexed {
|
||||
/**
|
||||
* Enables blending for an individual draw buffer.
|
||||
*
|
||||
* @param target must be BLEND.
|
||||
* @param index is an integer i specifying the draw buffer associated with the symbolic constant DRAW_BUFFERi.
|
||||
*/
|
||||
enablei: (target: number, index: number) => void;
|
||||
/**
|
||||
* Disables blending for an individual draw buffer.
|
||||
*
|
||||
* @param target must be BLEND.
|
||||
* @param index is an integer i specifying the draw buffer associated with the symbolic constant DRAW_BUFFERi.
|
||||
*/
|
||||
disablei: (buf: number, mode: number) => void;
|
||||
/**
|
||||
* The buf argument is an integer i that indicates that the blend equations should be modified for DRAW_BUFFERi.
|
||||
*
|
||||
* mode accepts the same tokens as mode in blendEquation.
|
||||
*/
|
||||
blendEquationi: (target: number, index: number) => void;
|
||||
/**
|
||||
* The buf argument is an integer i that indicates that the blend equations should be modified for DRAW_BUFFERi.
|
||||
*
|
||||
* modeRGB and modeAlpha accept the same tokens as modeRGB and modeAlpha in blendEquationSeparate.
|
||||
*/
|
||||
blendEquationSeparatei: (buf: number, modeRGB: number, modeAlpha: number) => void;
|
||||
/**
|
||||
* The buf argument is an integer i that indicates that the blend functions should be modified for DRAW_BUFFERi.
|
||||
*
|
||||
* src and dst accept the same tokens as src and dst in blendFunc.
|
||||
*/
|
||||
blendFunci: (buf: number, src: number, dst: number) => void;
|
||||
/**
|
||||
* The buf argument is an integer i that indicates that the blend functions should be modified for DRAW_BUFFERi.
|
||||
*
|
||||
* srcRGB, dstRGB, srcAlpha, and dstAlpha accept the same tokens as srcRGB, dstRGB, srcAlpha, and dstAlpha parameters in blendEquationSeparate.
|
||||
*/
|
||||
blendFuncSeparatei: (buf: number, srcRGB: number, dstRGB: number, srcAlpha: number, dstAlpha: number) => void;
|
||||
/**
|
||||
* The buf argument is an integer i that indicates that the write mask should be modified for DRAW_BUFFERi.
|
||||
*
|
||||
* r, g, b, and a indicate whether R, G, B, or A values, respectively, are written or not (a value of TRUE means that the corresponding value is written).
|
||||
*/
|
||||
colorMaski: (buf: number, r: boolean, g: boolean, b: boolean, a: boolean) => void;
|
||||
}
|
||||
|
||||
export function getDrawBuffersIndexed(gl: GLRenderingContext): COMPAT_draw_buffers_indexed | null {
|
||||
const ext = gl.getExtension('OES_draw_buffers_indexed');
|
||||
if (ext === null) return null;
|
||||
return {
|
||||
enablei: ext.enableiOES.bind(ext),
|
||||
disablei: ext.disableiOES.bind(ext),
|
||||
blendEquationi: ext.blendEquationiOES.bind(ext),
|
||||
blendEquationSeparatei: ext.blendEquationSeparateiOES.bind(ext),
|
||||
blendFunci: ext.blendFunciOES.bind(ext),
|
||||
blendFuncSeparatei: ext.blendFuncSeparateiOES.bind(ext),
|
||||
colorMaski: ext.colorMaskiOES.bind(ext),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/EXT_shader_texture_lod/
|
||||
*/
|
||||
export interface COMPAT_shader_texture_lod {
|
||||
}
|
||||
|
||||
@@ -275,6 +363,9 @@ export function getShaderTextureLod(gl: GLRenderingContext): COMPAT_shader_textu
|
||||
return isWebGL2(gl) ? {} : gl.getExtension('EXT_shader_texture_lod');
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/WEBGL_depth_texture/
|
||||
*/
|
||||
export interface COMPAT_depth_texture {
|
||||
readonly UNSIGNED_INT_24_8: number;
|
||||
}
|
||||
@@ -293,6 +384,9 @@ export function getDepthTexture(gl: GLRenderingContext): COMPAT_depth_texture |
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/EXT_sRGB/
|
||||
*/
|
||||
export interface COMPAT_sRGB {
|
||||
readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: number;
|
||||
readonly SRGB8_ALPHA8: number;
|
||||
@@ -320,6 +414,9 @@ export function getSRGB(gl: GLRenderingContext): COMPAT_sRGB | null {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/EXT_disjoint_timer_query/ and https://registry.khronos.org/webgl/extensions/EXT_disjoint_timer_query_webgl2/
|
||||
*/
|
||||
export interface COMPAT_disjoint_timer_query {
|
||||
/** A GLint indicating the number of bits used to hold the query result for the given target. */
|
||||
QUERY_COUNTER_BITS: number
|
||||
@@ -401,6 +498,31 @@ export function getDisjointTimerQuery(gl: GLRenderingContext): COMPAT_disjoint_t
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/KHR_parallel_shader_compile/
|
||||
*/
|
||||
export interface COMPAT_parallel_shader_compile {
|
||||
readonly COMPLETION_STATUS: number;
|
||||
}
|
||||
|
||||
export function getParallelShaderCompile(gl: GLRenderingContext): COMPAT_parallel_shader_compile | null {
|
||||
const ext = gl.getExtension('KHR_parallel_shader_compile');
|
||||
if (ext === null) return null;
|
||||
return {
|
||||
COMPLETION_STATUS: ext.COMPLETION_STATUS_KHR,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://registry.khronos.org/webgl/extensions/OES_fbo_render_mipmap/
|
||||
*/
|
||||
export interface COMPAT_fboRenderMipmap {
|
||||
}
|
||||
|
||||
export function getFboRenderMipmap(gl: GLRenderingContext): COMPAT_fboRenderMipmap | null {
|
||||
return isWebGL2(gl) ? {} : gl.getExtension('OES_fbo_render_mipmap');
|
||||
}
|
||||
|
||||
export function getNoNonInstancedActiveAttribs(gl: GLRenderingContext): boolean {
|
||||
if (!isWebGL2(gl)) return false;
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax, getFragDepth, COMPAT_frag_depth, COMPAT_color_buffer_float, getColorBufferFloat, COMPAT_draw_buffers, getDrawBuffers, getShaderTextureLod, COMPAT_shader_texture_lod, getDepthTexture, COMPAT_depth_texture, COMPAT_sRGB, getSRGB, getTextureHalfFloat, getTextureHalfFloatLinear, COMPAT_texture_half_float, COMPAT_texture_half_float_linear, COMPAT_color_buffer_half_float, getColorBufferHalfFloat, getVertexArrayObject, getDisjointTimerQuery, COMPAT_disjoint_timer_query, getNoNonInstancedActiveAttribs } from './compat';
|
||||
import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax, getFragDepth, COMPAT_frag_depth, COMPAT_color_buffer_float, getColorBufferFloat, COMPAT_draw_buffers, getDrawBuffers, getShaderTextureLod, COMPAT_shader_texture_lod, getDepthTexture, COMPAT_depth_texture, COMPAT_sRGB, getSRGB, getTextureHalfFloat, getTextureHalfFloatLinear, COMPAT_texture_half_float, COMPAT_texture_half_float_linear, COMPAT_color_buffer_half_float, getColorBufferHalfFloat, getVertexArrayObject, getDisjointTimerQuery, COMPAT_disjoint_timer_query, getNoNonInstancedActiveAttribs, getDrawBuffersIndexed, COMPAT_draw_buffers_indexed, getParallelShaderCompile, COMPAT_parallel_shader_compile, getFboRenderMipmap, COMPAT_fboRenderMipmap } from './compat';
|
||||
import { isDebugMode } from '../../mol-util/debug';
|
||||
|
||||
export type WebGLExtensions = {
|
||||
instancedArrays: COMPAT_instanced_arrays
|
||||
elementIndexUint: COMPAT_element_index_uint
|
||||
standardDerivatives: COMPAT_standard_derivatives
|
||||
|
||||
standardDerivatives: COMPAT_standard_derivatives | null
|
||||
textureFloat: COMPAT_texture_float | null
|
||||
textureFloatLinear: COMPAT_texture_float_linear | null
|
||||
textureHalfFloat: COMPAT_texture_half_float | null
|
||||
@@ -23,9 +23,12 @@ export type WebGLExtensions = {
|
||||
colorBufferFloat: COMPAT_color_buffer_float | null
|
||||
colorBufferHalfFloat: COMPAT_color_buffer_half_float | null
|
||||
drawBuffers: COMPAT_draw_buffers | null
|
||||
drawBuffersIndexed: COMPAT_draw_buffers_indexed | null
|
||||
shaderTextureLod: COMPAT_shader_texture_lod | null
|
||||
sRGB: COMPAT_sRGB | null
|
||||
disjointTimerQuery: COMPAT_disjoint_timer_query | null
|
||||
parallelShaderCompile: COMPAT_parallel_shader_compile | null
|
||||
fboRenderMipmap: COMPAT_fboRenderMipmap | null
|
||||
|
||||
noNonInstancedActiveAttribs: boolean
|
||||
}
|
||||
@@ -94,6 +97,10 @@ export function createExtensions(gl: GLRenderingContext): WebGLExtensions {
|
||||
if (isDebugMode && drawBuffers === null) {
|
||||
console.log('Could not find support for "draw_buffers"');
|
||||
}
|
||||
const drawBuffersIndexed = getDrawBuffersIndexed(gl);
|
||||
if (isDebugMode && drawBuffersIndexed === null) {
|
||||
console.log('Could not find support for "draw_buffers_indexed"');
|
||||
}
|
||||
const shaderTextureLod = getShaderTextureLod(gl);
|
||||
if (isDebugMode && shaderTextureLod === null) {
|
||||
console.log('Could not find support for "shader_texture_lod"');
|
||||
@@ -106,28 +113,39 @@ export function createExtensions(gl: GLRenderingContext): WebGLExtensions {
|
||||
if (isDebugMode && disjointTimerQuery === null) {
|
||||
console.log('Could not find support for "disjoint_timer_query"');
|
||||
}
|
||||
const parallelShaderCompile = getParallelShaderCompile(gl);
|
||||
if (isDebugMode && parallelShaderCompile === null) {
|
||||
console.log('Could not find support for "parallel_shader_compile"');
|
||||
}
|
||||
const fboRenderMipmap = getFboRenderMipmap(gl);
|
||||
if (isDebugMode && fboRenderMipmap === null) {
|
||||
console.log('Could not find support for "fbo_render_mipmap"');
|
||||
}
|
||||
|
||||
const noNonInstancedActiveAttribs = getNoNonInstancedActiveAttribs(gl);
|
||||
|
||||
return {
|
||||
instancedArrays,
|
||||
standardDerivatives,
|
||||
elementIndexUint,
|
||||
|
||||
textureFloat,
|
||||
textureFloatLinear,
|
||||
textureHalfFloat,
|
||||
textureHalfFloatLinear,
|
||||
elementIndexUint,
|
||||
depthTexture,
|
||||
|
||||
blendMinMax,
|
||||
vertexArrayObject,
|
||||
fragDepth,
|
||||
colorBufferFloat,
|
||||
colorBufferHalfFloat,
|
||||
drawBuffers,
|
||||
drawBuffersIndexed,
|
||||
shaderTextureLod,
|
||||
sRGB,
|
||||
disjointTimerQuery,
|
||||
parallelShaderCompile,
|
||||
fboRenderMipmap,
|
||||
|
||||
noNonInstancedActiveAttribs,
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2017-2022 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 { lerp as scalar_lerp } from '../../mol-math/interpolate';
|
||||
import { defaults } from '../../mol-util';
|
||||
import { Mat3 } from '../linear-algebra/3d/mat3';
|
||||
import { Mat4 } from '../linear-algebra/3d/mat4';
|
||||
import { Quat } from '../linear-algebra/3d/quat';
|
||||
@@ -29,11 +29,13 @@ interface SymmetryOperator {
|
||||
readonly hkl: Vec3,
|
||||
/** spacegroup symmetry operator index, -1 if not applicable */
|
||||
readonly spgrOp: number,
|
||||
/** unique (external) key, -1 if not available */
|
||||
readonly key: number,
|
||||
|
||||
readonly matrix: Mat4,
|
||||
// cache the inverse of the transform
|
||||
/** cache the inverse of the transform */
|
||||
readonly inverse: Mat4,
|
||||
// optimize the identity case
|
||||
/** optimize the identity case */
|
||||
readonly isIdentity: boolean,
|
||||
|
||||
/**
|
||||
@@ -51,19 +53,20 @@ namespace SymmetryOperator {
|
||||
|
||||
export const RotationTranslationEpsilon = 0.005;
|
||||
|
||||
export type CreateInfo = { assembly?: SymmetryOperator['assembly'], ncsId?: number, hkl?: Vec3, spgrOp?: number }
|
||||
export type CreateInfo = { assembly?: SymmetryOperator['assembly'], ncsId?: number, hkl?: Vec3, spgrOp?: number, key?: number }
|
||||
export function create(name: string, matrix: Mat4, info?: CreateInfo | SymmetryOperator): SymmetryOperator {
|
||||
let { assembly, ncsId, hkl, spgrOp } = info || { };
|
||||
let { assembly, ncsId, hkl, spgrOp, key } = info || { };
|
||||
const _hkl = hkl ? Vec3.clone(hkl) : Vec3();
|
||||
spgrOp = defaults(spgrOp, -1);
|
||||
spgrOp = spgrOp ?? -1;
|
||||
key = key ?? -1;
|
||||
ncsId = ncsId || -1;
|
||||
const isIdentity = Mat4.isIdentity(matrix);
|
||||
const suffix = getSuffix(info, isIdentity);
|
||||
if (isIdentity) return { name, assembly, matrix, inverse: Mat4.identity(), isIdentity: true, hkl: _hkl, spgrOp, ncsId, suffix };
|
||||
if (isIdentity) return { name, assembly, matrix, inverse: Mat4.identity(), isIdentity: true, hkl: _hkl, spgrOp, ncsId, suffix, key };
|
||||
if (!Mat4.isRotationAndTranslation(matrix, RotationTranslationEpsilon)) {
|
||||
console.warn(`Symmetry operator (${name}) should be a composition of rotation and translation.`);
|
||||
}
|
||||
return { name, assembly, matrix, inverse: Mat4.invert(Mat4(), matrix), isIdentity: false, hkl: _hkl, spgrOp, ncsId, suffix };
|
||||
return { name, assembly, matrix, inverse: Mat4.invert(Mat4(), matrix), isIdentity: false, hkl: _hkl, spgrOp, key, ncsId, suffix };
|
||||
}
|
||||
|
||||
function isSymmetryOperator(x: any): x is SymmetryOperator {
|
||||
|
||||
@@ -14,6 +14,8 @@ import { ElementIndex } from '../../../../mol-model/structure';
|
||||
|
||||
export type IndexPairsProps = {
|
||||
readonly key: ArrayLike<number>
|
||||
readonly operatorA: ArrayLike<number>
|
||||
readonly operatorB: ArrayLike<number>
|
||||
readonly order: ArrayLike<number>
|
||||
readonly distance: ArrayLike<number>
|
||||
readonly flag: ArrayLike<BondType.Flag>
|
||||
@@ -24,18 +26,22 @@ export type IndexPairBonds = { bonds: IndexPairs, maxDistance: number }
|
||||
function getGraph(indexA: ArrayLike<ElementIndex>, indexB: ArrayLike<ElementIndex>, props: Partial<IndexPairsProps>, count: number): IndexPairs {
|
||||
const builder = new IntAdjacencyGraph.EdgeBuilder(count, indexA, indexB);
|
||||
const key = new Int32Array(builder.slotCount);
|
||||
const operatorA = new Array(builder.slotCount);
|
||||
const operatorB = new Array(builder.slotCount);
|
||||
const order = new Int8Array(builder.slotCount);
|
||||
const distance = new Array(builder.slotCount);
|
||||
const flag = new Array(builder.slotCount);
|
||||
for (let i = 0, _i = builder.edgeCount; i < _i; i++) {
|
||||
builder.addNextEdge();
|
||||
builder.assignProperty(key, props.key ? props.key[i] : -1);
|
||||
builder.assignProperty(operatorA, props.operatorA ? props.operatorA[i] : -1);
|
||||
builder.assignProperty(operatorB, props.operatorB ? props.operatorB[i] : -1);
|
||||
builder.assignProperty(order, props.order ? props.order[i] : 1);
|
||||
builder.assignProperty(distance, props.distance ? props.distance[i] : -1);
|
||||
builder.assignProperty(flag, props.flag ? props.flag[i] : BondType.Flag.Covalent);
|
||||
}
|
||||
|
||||
return builder.createGraph({ key, order, distance, flag });
|
||||
return builder.createGraph({ key, operatorA, operatorB, order, distance, flag });
|
||||
}
|
||||
|
||||
export namespace IndexPairBonds {
|
||||
@@ -50,6 +56,10 @@ export namespace IndexPairBonds {
|
||||
indexA: Column<number>,
|
||||
indexB: Column<number>,
|
||||
key?: Column<number>,
|
||||
/** Operator key for indexA. Used in bond computation. */
|
||||
operatorA?: Column<number>,
|
||||
/** Operator key for indexB. Used in bond computation. */
|
||||
operatorB?: Column<number>,
|
||||
order?: Column<number>,
|
||||
/**
|
||||
* Useful for bonds in periodic cells. That is, only bonds within the given
|
||||
@@ -83,11 +93,13 @@ export namespace IndexPairBonds {
|
||||
const indexA = pairs.indexA.toArray() as ArrayLike<ElementIndex>;
|
||||
const indexB = pairs.indexB.toArray() as ArrayLike<ElementIndex>;
|
||||
const key = pairs.key && pairs.key.toArray();
|
||||
const operatorA = pairs.operatorA && pairs.operatorA.toArray();
|
||||
const operatorB = pairs.operatorB && pairs.operatorB.toArray();
|
||||
const order = pairs.order && pairs.order.toArray();
|
||||
const distance = pairs.distance && pairs.distance.toArray();
|
||||
const flag = pairs.flag && pairs.flag.toArray();
|
||||
return {
|
||||
bonds: getGraph(indexA, indexB, { key, order, distance, flag }, count),
|
||||
bonds: getGraph(indexA, indexB, { key, operatorA, operatorB, order, distance, flag }, count),
|
||||
maxDistance: p.maxDistance
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 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 David Sehnal <david.sehnal@gmail.com>
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
*/
|
||||
|
||||
import { CubeFile } from '../../mol-io/reader/cube/parser';
|
||||
@@ -12,9 +11,8 @@ import { Task } from '../../mol-task';
|
||||
import { arrayMax, arrayMean, arrayMin, arrayRms } from '../../mol-util/array';
|
||||
import { ModelFormat } from '../format';
|
||||
import { CustomProperties } from '../../mol-model/custom-property';
|
||||
import { clamp } from '../../mol-math/interpolate';
|
||||
|
||||
export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number, label?: string, entryId?: string, clamp?: { min: number, max: number } }): Task<Volume> {
|
||||
export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number, label?: string, entryId?: string }): Task<Volume> {
|
||||
return Task.create<Volume>('Create Volume', async () => {
|
||||
const { header, values: sourceValues } = source;
|
||||
const space = Tensor.Space(header.dim, [0, 1, 2], Float64Array);
|
||||
@@ -26,7 +24,6 @@ export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number,
|
||||
// get every nth value from the source values
|
||||
const [h, k, l] = header.dim;
|
||||
const nth = (params?.dataIndex || 0) + 1;
|
||||
const { min, max } = params?.clamp || { min: -Infinity, max: Infinity };
|
||||
|
||||
let o = 0, s = 0;
|
||||
|
||||
@@ -34,7 +31,7 @@ export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number,
|
||||
for (let u = 0; u < h; u++) {
|
||||
for (let v = 0; v < k; v++) {
|
||||
for (let w = 0; w < l; w++) {
|
||||
values[o++] = clamp(sourceValues[s], min, max);
|
||||
values[o++] = sourceValues[s];
|
||||
s += nth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +155,6 @@ class QueryContextBondInfo<U extends Unit = Unit> {
|
||||
}
|
||||
|
||||
get length() {
|
||||
return StructureElement.Location.distance(this.a, this. b);
|
||||
return StructureElement.Location.distance(this.a, this.b);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2017-2022 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>
|
||||
@@ -173,6 +173,7 @@ const unit = {
|
||||
multiChain: p(l => Unit.Traits.is(l.unit.traits, Unit.Trait.MultiChain)),
|
||||
object_primitive: p(l => l.unit.objectPrimitive),
|
||||
operator_name: p(l => l.unit.conformation.operator.name),
|
||||
operator_key: p(l => l.unit.conformation.operator.key),
|
||||
model_index: p(l => l.unit.model.modelNum),
|
||||
model_label: p(l => l.unit.model.label),
|
||||
model_entry_id: p(l => l.unit.model.entryId),
|
||||
|
||||
@@ -71,6 +71,8 @@ function findPairBonds(unitA: Unit.Atomic, unitB: Unit.Atomic, props: BondComput
|
||||
const testDistanceSq = (bRadius + maxRadius) * (bRadius + maxRadius);
|
||||
|
||||
builder.startUnitPair(unitA.id, unitB.id);
|
||||
const opKeyA = unitA.conformation.operator.key;
|
||||
const opKeyB = unitB.conformation.operator.key;
|
||||
|
||||
for (let _aI = 0 as StructureElement.UnitIndex; _aI < atomCount; _aI++) {
|
||||
const aI = atomsA[_aI];
|
||||
@@ -80,7 +82,7 @@ function findPairBonds(unitA: Unit.Atomic, unitB: Unit.Atomic, props: BondComput
|
||||
|
||||
if (!props.forceCompute && indexPairs) {
|
||||
const { maxDistance } = indexPairs;
|
||||
const { offset, b, edgeProps: { order, distance, flag, key } } = indexPairs.bonds;
|
||||
const { offset, b, edgeProps: { order, distance, flag, key, operatorA, operatorB } } = indexPairs.bonds;
|
||||
|
||||
const srcA = sourceIndex.value(aI);
|
||||
const aeI = getElementIdx(type_symbolA.value(aI));
|
||||
@@ -90,6 +92,10 @@ function findPairBonds(unitA: Unit.Atomic, unitB: Unit.Atomic, props: BondComput
|
||||
const _bI = SortedArray.indexOf(unitB.elements, bI) as StructureElement.UnitIndex;
|
||||
if (_bI < 0) continue;
|
||||
|
||||
const opA = operatorA[i];
|
||||
const opB = operatorB[i];
|
||||
if ((opA >= 0 && opA !== opKeyA) || (opB >= 0 && opB !== opKeyB)) continue;
|
||||
|
||||
const beI = getElementIdx(type_symbolA.value(bI));
|
||||
|
||||
const d = distance[i];
|
||||
|
||||
@@ -55,7 +55,7 @@ function findIndexPairBonds(unit: Unit.Atomic) {
|
||||
const { type_symbol } = unit.model.atomicHierarchy.atoms;
|
||||
const atomCount = unit.elements.length;
|
||||
const { maxDistance } = indexPairs;
|
||||
const { offset, b, edgeProps: { order, distance, flag, key } } = indexPairs.bonds;
|
||||
const { offset, b, edgeProps: { order, distance, flag, key, operatorA, operatorB } } = indexPairs.bonds;
|
||||
|
||||
const { atomSourceIndex: sourceIndex } = unit.model.atomicHierarchy;
|
||||
const { invertedIndex } = Model.getInvertedAtomSourceIndex(unit.model);
|
||||
@@ -66,6 +66,8 @@ function findIndexPairBonds(unit: Unit.Atomic) {
|
||||
const orders: number[] = [];
|
||||
const keys: number[] = [];
|
||||
|
||||
const opKey = unit.conformation.operator.key;
|
||||
|
||||
for (let _aI = 0 as StructureElement.UnitIndex; _aI < atomCount; _aI++) {
|
||||
const aI = atoms[_aI];
|
||||
const aeI = getElementIdx(type_symbol.value(aI));
|
||||
@@ -80,6 +82,10 @@ function findIndexPairBonds(unit: Unit.Atomic) {
|
||||
const _bI = SortedArray.indexOf(unit.elements, bI) as StructureElement.UnitIndex;
|
||||
if (_bI < 0) continue;
|
||||
|
||||
const opA = operatorA[i];
|
||||
const opB = operatorB[i];
|
||||
if ((opA >= 0 && opA !== opKey) || (opB >= 0 && opB !== opKey)) continue;
|
||||
|
||||
const beI = getElementIdx(type_symbol.value(bI));
|
||||
|
||||
const d = distance[i];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2018-2022 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>
|
||||
@@ -43,6 +43,7 @@ import { Box3D } from '../../mol-math/geometry';
|
||||
import { PlaneParams, PlaneRepresentation } from '../../mol-repr/shape/loci/plane';
|
||||
import { Substance } from '../../mol-theme/substance';
|
||||
import { Material } from '../../mol-util/material';
|
||||
import { lerp } from '../../mol-math/interpolate';
|
||||
|
||||
export { StructureRepresentation3D };
|
||||
export { ExplodeStructureRepresentation3D };
|
||||
@@ -56,6 +57,7 @@ export { SubstanceStructureRepresentation3DFromScript };
|
||||
export { SubstanceStructureRepresentation3DFromBundle };
|
||||
export { ClippingStructureRepresentation3DFromScript };
|
||||
export { ClippingStructureRepresentation3DFromBundle };
|
||||
export { ThemeStrengthRepresentation3D };
|
||||
export { VolumeRepresentation3D };
|
||||
|
||||
type StructureRepresentation3D = typeof StructureRepresentation3D
|
||||
@@ -745,6 +747,62 @@ const ClippingStructureRepresentation3DFromBundle = PluginStateTransform.BuiltIn
|
||||
}
|
||||
});
|
||||
|
||||
type ThemeStrengthRepresentation3D = typeof ThemeStrengthRepresentation3D
|
||||
const ThemeStrengthRepresentation3D = PluginStateTransform.BuiltIn({
|
||||
name: 'theme-strength-representation-3d',
|
||||
display: 'Theme Strength 3D Representation',
|
||||
from: SO.Molecule.Structure.Representation3D,
|
||||
to: SO.Molecule.Structure.Representation3DState,
|
||||
params: () => ({
|
||||
overpaintStrength: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }),
|
||||
transparencyStrength: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }),
|
||||
substanceStrength: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }),
|
||||
})
|
||||
})({
|
||||
canAutoUpdate() {
|
||||
return true;
|
||||
},
|
||||
apply({ a, params }) {
|
||||
return new SO.Molecule.Structure.Representation3DState({
|
||||
state: {
|
||||
themeStrength: {
|
||||
overpaint: params.overpaintStrength,
|
||||
transparency: params.transparencyStrength,
|
||||
substance: params.substanceStrength
|
||||
},
|
||||
},
|
||||
initialState: {
|
||||
themeStrength: { overpaint: 1, transparency: 1, substance: 1 },
|
||||
},
|
||||
info: { },
|
||||
repr: a.data.repr
|
||||
}, { label: 'Theme Strength', description: `${params.overpaintStrength.toFixed(2)}, ${params.transparencyStrength.toFixed(2)}, ${params.substanceStrength.toFixed(2)}` });
|
||||
},
|
||||
update({ a, b, newParams, oldParams }) {
|
||||
if (newParams.overpaintStrength === b.data.state.themeStrength?.overpaint &&
|
||||
newParams.transparencyStrength === b.data.state.themeStrength?.transparency &&
|
||||
newParams.substanceStrength === b.data.state.themeStrength?.substance
|
||||
) return StateTransformer.UpdateResult.Unchanged;
|
||||
|
||||
b.data.state.themeStrength = {
|
||||
overpaint: newParams.overpaintStrength,
|
||||
transparency: newParams.transparencyStrength,
|
||||
substance: newParams.substanceStrength,
|
||||
};
|
||||
b.data.repr = a.data.repr;
|
||||
b.label = 'Theme Strength';
|
||||
b.description = `${newParams.overpaintStrength.toFixed(2)}, ${newParams.transparencyStrength.toFixed(2)}, ${newParams.substanceStrength.toFixed(2)}`;
|
||||
return StateTransformer.UpdateResult.Updated;
|
||||
},
|
||||
interpolate(src, tar, t) {
|
||||
return {
|
||||
overpaintStrength: lerp(src.overpaintStrength, tar.overpaintStrength, t),
|
||||
transparencyStrength: lerp(src.transparencyStrength, tar.transparencyStrength, t),
|
||||
substanceStrength: lerp(src.substanceStrength, tar.substanceStrength, t),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
export namespace VolumeRepresentation3DHelpers {
|
||||
|
||||
@@ -88,24 +88,12 @@ const VolumeFromCube = PluginStateTransform.BuiltIn({
|
||||
return {
|
||||
dataIndex,
|
||||
entryId: PD.Text(''),
|
||||
clamp: PD.MappedStatic('off', {
|
||||
'off': PD.EmptyGroup(),
|
||||
'on': PD.Group({
|
||||
min: PD.Numeric(-1024),
|
||||
max: PD.Numeric(1024),
|
||||
})
|
||||
}, { cycle: true })
|
||||
};
|
||||
}
|
||||
})({
|
||||
apply({ a, params }) {
|
||||
return Task.create('Create volume from Cube', async ctx => {
|
||||
const volume = await volumeFromCube(a.data, {
|
||||
dataIndex: params.dataIndex,
|
||||
label: a.data.name || a.label,
|
||||
entryId: params.entryId,
|
||||
clamp: params.clamp.name === 'on' ? params.clamp.params : undefined,
|
||||
}).runInContext(ctx);
|
||||
const volume = await volumeFromCube(a.data, { ...params, label: a.data.name || a.label }).runInContext(ctx);
|
||||
const props = { label: volume.label || 'Volume', description: `Volume ${a.data.header.dim[0]}\u00D7${a.data.header.dim[1]}\u00D7${a.data.header.dim[2]}` };
|
||||
return new SO.Volume.Data(volume, props);
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: black;
|
||||
background: $default-background;
|
||||
|
||||
.msp-btn-link {
|
||||
background: rgba(0,0,0,0.2);
|
||||
|
||||
@@ -104,6 +104,7 @@ export const DefaultPluginSpec = (): PluginSpec => ({
|
||||
PluginSpec.Action(StateTransforms.Representation.TransparencyStructureRepresentation3DFromScript),
|
||||
PluginSpec.Action(StateTransforms.Representation.ClippingStructureRepresentation3DFromScript),
|
||||
PluginSpec.Action(StateTransforms.Representation.SubstanceStructureRepresentation3DFromScript),
|
||||
PluginSpec.Action(StateTransforms.Representation.ThemeStrengthRepresentation3D),
|
||||
|
||||
PluginSpec.Action(AssignColorVolume),
|
||||
PluginSpec.Action(StateTransforms.Volume.VolumeFromCcp4),
|
||||
|
||||
@@ -191,6 +191,8 @@ namespace Representation {
|
||||
substance: Substance
|
||||
/** Bit mask of per group clipping applied to the representation's renderobjects */
|
||||
clipping: Clipping
|
||||
/** Strength of the representations overpaint, transparency, substance*/
|
||||
themeStrength: { overpaint: number, transparency: number, substance: number }
|
||||
/** Controls if the representation's renderobjects are synced automatically with GPU or not */
|
||||
syncManually: boolean
|
||||
/** A transformation applied to the representation's renderobjects */
|
||||
@@ -199,7 +201,20 @@ namespace Representation {
|
||||
markerActions: MarkerActions
|
||||
}
|
||||
export function createState(): State {
|
||||
return { visible: true, alphaFactor: 1, pickable: true, colorOnly: false, syncManually: false, transform: Mat4.identity(), overpaint: Overpaint.Empty, transparency: Transparency.Empty, substance: Substance.Empty, clipping: Clipping.Empty, markerActions: MarkerActions.All };
|
||||
return {
|
||||
visible: true,
|
||||
alphaFactor: 1,
|
||||
pickable: true,
|
||||
colorOnly: false,
|
||||
syncManually: false,
|
||||
transform: Mat4.identity(),
|
||||
overpaint: Overpaint.Empty,
|
||||
transparency: Transparency.Empty,
|
||||
substance: Substance.Empty,
|
||||
clipping: Clipping.Empty,
|
||||
themeStrength: { overpaint: 1, transparency: 1, substance: 1 },
|
||||
markerActions: MarkerActions.All
|
||||
};
|
||||
}
|
||||
export function updateState(state: State, update: Partial<State>) {
|
||||
if (update.visible !== undefined) state.visible = update.visible;
|
||||
@@ -210,6 +225,7 @@ namespace Representation {
|
||||
if (update.transparency !== undefined) state.transparency = update.transparency;
|
||||
if (update.substance !== undefined) state.substance = update.substance;
|
||||
if (update.clipping !== undefined) state.clipping = update.clipping;
|
||||
if (update.themeStrength !== undefined) state.themeStrength = update.themeStrength;
|
||||
if (update.syncManually !== undefined) state.syncManually = update.syncManually;
|
||||
if (update.transform !== undefined) Mat4.copy(state.transform, update.transform);
|
||||
if (update.markerActions !== undefined) state.markerActions = update.markerActions;
|
||||
@@ -432,6 +448,7 @@ namespace Representation {
|
||||
if (state.substance !== undefined) {
|
||||
// TODO
|
||||
}
|
||||
if (state.themeStrength !== undefined) Visual.setThemeStrength(renderObject, state.themeStrength);
|
||||
if (state.transform !== undefined) Visual.setTransform(renderObject, state.transform);
|
||||
|
||||
Representation.updateState(currentState, state);
|
||||
|
||||
@@ -127,6 +127,7 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
|
||||
const remappedClipping = Clipping.remap(state.clipping, _structure);
|
||||
visual.setClipping(remappedClipping);
|
||||
}
|
||||
if (state.themeStrength !== undefined && visual) visual.setThemeStrength(state.themeStrength);
|
||||
if (state.transform !== undefined && visual) visual.setTransform(state.transform);
|
||||
if (state.unitTransforms !== undefined && visual) {
|
||||
// Since ComplexVisuals always renders geometries between units, the application
|
||||
|
||||
@@ -299,6 +299,9 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
|
||||
setClipping(clipping: Clipping) {
|
||||
Visual.setClipping(renderObject, clipping, lociApply, true);
|
||||
},
|
||||
setThemeStrength(strength: { overpaint: number, transparency: number, substance: number }) {
|
||||
Visual.setThemeStrength(renderObject, strength);
|
||||
},
|
||||
destroy() {
|
||||
dispose?.(geometry);
|
||||
if (renderObject) {
|
||||
|
||||
@@ -222,7 +222,7 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
|
||||
}
|
||||
|
||||
function setVisualState(visual: UnitsVisual<P>, group: Unit.SymmetryGroup, state: Partial<StructureRepresentationState>) {
|
||||
const { visible, alphaFactor, pickable, overpaint, transparency, substance, clipping, transform, unitTransforms } = state;
|
||||
const { visible, alphaFactor, pickable, overpaint, transparency, substance, clipping, themeStrength, transform, unitTransforms } = state;
|
||||
|
||||
if (visible !== undefined) visual.setVisibility(visible);
|
||||
if (alphaFactor !== undefined) visual.setAlphaFactor(alphaFactor);
|
||||
@@ -231,6 +231,7 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
|
||||
if (transparency !== undefined) visual.setTransparency(transparency, webgl);
|
||||
if (substance !== undefined) visual.setSubstance(substance, webgl);
|
||||
if (clipping !== undefined) visual.setClipping(clipping);
|
||||
if (themeStrength !== undefined) visual.setThemeStrength(themeStrength);
|
||||
if (transform !== undefined) visual.setTransform(transform);
|
||||
if (unitTransforms !== undefined) {
|
||||
if (unitTransforms) {
|
||||
@@ -243,7 +244,7 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
|
||||
}
|
||||
|
||||
function setState(state: Partial<StructureRepresentationState>) {
|
||||
const { visible, alphaFactor, pickable, overpaint, transparency, substance, clipping, transform, unitTransforms, syncManually, markerActions } = state;
|
||||
const { visible, alphaFactor, pickable, overpaint, transparency, substance, clipping, themeStrength, transform, unitTransforms, syncManually, markerActions } = state;
|
||||
const newState: Partial<StructureRepresentationState> = {};
|
||||
|
||||
if (visible !== _state.visible) newState.visible = visible;
|
||||
@@ -261,6 +262,7 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
|
||||
if (clipping !== undefined && _structure) {
|
||||
newState.clipping = Clipping.remap(clipping, _structure);
|
||||
}
|
||||
if (themeStrength !== undefined) newState.themeStrength = themeStrength;
|
||||
if (transform !== undefined && !Mat4.areEqual(transform, _state.transform, EPSILON)) {
|
||||
newState.transform = transform;
|
||||
}
|
||||
|
||||
@@ -381,6 +381,9 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
|
||||
setClipping(clipping: Clipping) {
|
||||
Visual.setClipping(renderObject, clipping, lociApply, true);
|
||||
},
|
||||
setThemeStrength(strength: { overpaint: number, transparency: number, substance: number }) {
|
||||
Visual.setThemeStrength(renderObject, strength);
|
||||
},
|
||||
destroy() {
|
||||
dispose?.(geometry);
|
||||
if (renderObject) {
|
||||
|
||||
@@ -55,6 +55,7 @@ interface Visual<D, P extends PD.Params> {
|
||||
setTransparency: (transparency: Transparency, webgl?: WebGLContext) => void
|
||||
setSubstance: (substance: Substance, webgl?: WebGLContext) => void
|
||||
setClipping: (clipping: Clipping) => void
|
||||
setThemeStrength: (strength: { overpaint: number, transparency: number, substance: number }) => void
|
||||
destroy: () => void
|
||||
mustRecreate?: (data: D, props: PD.Values<P>, webgl?: WebGLContext) => boolean
|
||||
}
|
||||
@@ -349,6 +350,14 @@ namespace Visual {
|
||||
ValueCell.updateIfChanged(dClipping, clipping.layers.length > 0);
|
||||
}
|
||||
|
||||
export function setThemeStrength(renderObject: GraphicsRenderObject | undefined, strength: { overpaint: number, transparency: number, substance: number }) {
|
||||
if (renderObject) {
|
||||
ValueCell.updateIfChanged(renderObject.values.uOverpaintStrength, strength.overpaint);
|
||||
ValueCell.updateIfChanged(renderObject.values.uTransparencyStrength, strength.transparency);
|
||||
ValueCell.updateIfChanged(renderObject.values.uSubstanceStrength, strength.substance);
|
||||
}
|
||||
}
|
||||
|
||||
export function setTransform(renderObject: GraphicsRenderObject | undefined, transform?: Mat4, instanceTransforms?: Float32Array | null) {
|
||||
if (!renderObject || (!transform && !instanceTransforms)) return;
|
||||
|
||||
|
||||
@@ -252,6 +252,9 @@ export function VolumeVisual<G extends Geometry, P extends VolumeParams & Geomet
|
||||
setClipping(clipping: Clipping) {
|
||||
return Visual.setClipping(renderObject, clipping, lociApply, true);
|
||||
},
|
||||
setThemeStrength(strength: { overpaint: number, transparency: number, substance: number }) {
|
||||
Visual.setThemeStrength(renderObject, strength);
|
||||
},
|
||||
destroy() {
|
||||
dispose?.(geometry);
|
||||
if (renderObject) {
|
||||
|
||||
@@ -273,6 +273,7 @@ const atomProperty = {
|
||||
|
||||
sourceIndex: atomProp(Type.Num, 'Index of the atom/element in the input file.'),
|
||||
operatorName: atomProp(Type.Str, 'Name of the symmetry operator applied to this element.'),
|
||||
operatorKey: atomProp(Type.Num, 'Key of the symmetry operator applied to this element.'),
|
||||
modelIndex: atomProp(Type.Num, 'Index of the model in the input file.'),
|
||||
modelLabel: atomProp(Type.Str, 'Label/header of the model in the input file.')
|
||||
},
|
||||
|
||||
@@ -299,6 +299,7 @@ const symbols = [
|
||||
D(MolScript.structureQuery.atomProperty.core.z, atomProp(StructureProperties.atom.z)),
|
||||
D(MolScript.structureQuery.atomProperty.core.sourceIndex, atomProp(StructureProperties.atom.sourceIndex)),
|
||||
D(MolScript.structureQuery.atomProperty.core.operatorName, atomProp(StructureProperties.unit.operator_name)),
|
||||
D(MolScript.structureQuery.atomProperty.core.operatorKey, atomProp(StructureProperties.unit.operator_key)),
|
||||
D(MolScript.structureQuery.atomProperty.core.modelIndex, atomProp(StructureProperties.unit.model_index)),
|
||||
D(MolScript.structureQuery.atomProperty.core.modelLabel, atomProp(StructureProperties.unit.model_label)),
|
||||
D(MolScript.structureQuery.atomProperty.core.atomKey, (ctx, xs) => {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2018 Mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2018-2022 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 { UniqueArray } from '../../../mol-data/generic';
|
||||
@@ -205,6 +206,7 @@ export const SymbolTable = [
|
||||
Alias(MolScript.structureQuery.atomProperty.core.z, 'atom.z'),
|
||||
Alias(MolScript.structureQuery.atomProperty.core.sourceIndex, 'atom.src-index'),
|
||||
Alias(MolScript.structureQuery.atomProperty.core.operatorName, 'atom.op-name'),
|
||||
Alias(MolScript.structureQuery.atomProperty.core.operatorKey, 'atom.op-key'),
|
||||
Alias(MolScript.structureQuery.atomProperty.core.modelIndex, 'atom.model-index'),
|
||||
Alias(MolScript.structureQuery.atomProperty.core.modelLabel, 'atom.model-label'),
|
||||
Alias(MolScript.structureQuery.atomProperty.core.atomKey, 'atom.key'),
|
||||
@@ -253,6 +255,7 @@ export const SymbolTable = [
|
||||
'Bond Properties',
|
||||
Alias(MolScript.structureQuery.bondProperty.order, 'bond.order'),
|
||||
Alias(MolScript.structureQuery.bondProperty.length, 'bond.length'),
|
||||
Alias(MolScript.structureQuery.bondProperty.key, 'bond.key'),
|
||||
Alias(MolScript.structureQuery.bondProperty.atomA, 'bond.atom-a'),
|
||||
Alias(MolScript.structureQuery.bondProperty.atomB, 'bond.atom-b'),
|
||||
Macro(MSymbol('bond.is', Arguments.List(StructureQueryTypes.BondFlag), Type.Bool,
|
||||
|
||||
@@ -100,7 +100,7 @@ class AssetManager {
|
||||
}
|
||||
|
||||
const data = await ajaxGet({ ...asset, type: 'binary' }).runInContext(ctx);
|
||||
const file = new File([data], 'raw-data');
|
||||
const file = new File([data], asset.url);
|
||||
this._assets.set(asset.id, { asset, file, refCount: 1 });
|
||||
return Asset.Wrapper(await readFromFile(file, type).runInContext(ctx), asset, this);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user