Compare commits

...

12 Commits

Author SHA1 Message Date
dsehnal
f5ecf5648e 3.7.0 2022-04-13 20:04:01 +02:00
dsehnal
821f82fc3f changelog 2022-04-13 20:01:04 +02:00
David Sehnal
92305fe628 Merge pull request #420 from molstar/transparentBackfaces
improve transparentBackfaces handling
2022-04-13 19:57:29 +02:00
David Sehnal
17fe57b8a5 Merge pull request #423 from jpattle/option-to-disable-drag-overlay
Added an option to disable the drag overlay
2022-04-13 16:31:21 +02:00
Jason Pattle
47433a51d3 Added an option to the components spec to allow disabling of the drag-and-drop overlap for Molstar that loads files into the viewer. By default the drag overlay is enabled, just as it was before 2022-04-13 15:00:03 +01:00
Alexander Rose
e090827ced Merge branch 'master' of https://github.com/molstar/molstar into transparentBackfaces 2022-04-10 13:20:22 -07:00
dsehnal
98afc27442 fix react typing 2022-04-09 21:24:14 +02:00
Alexander Rose
9d4f28a395 fix type deps 2022-04-09 11:36:17 -07:00
Alexander Rose
50266d9a56 package updates 2022-04-09 11:20:28 -07:00
Alexander Rose
b23d610c94 improve transparentBackfaces handling
- off: don't show (default)
- on: show with transparency
- opaque: show fully opaque
2022-04-09 10:17:41 -07:00
Alexander Rose
119c43d527 fix xrayShaded for texture-mesh geometries 2022-04-09 10:04:06 -07:00
Alexander Rose
124feeb790 color theme tweaks
- add optional grid property
- handle dColorType_direct for non direct-volume shaders
2022-04-09 09:57:31 -07:00
24 changed files with 1630 additions and 1140 deletions

View File

@@ -6,6 +6,15 @@ Note that since we don't clearly distinguish between a public and private interf
## [Unreleased]
## [v3.7.0] - 2022-04-13
- Fix ``xrayShaded`` for texture-mesh geometries
- [Breaking] Change ``allowTransparentBackfaces`` to ``transparentBackfaces`` with options ``off``, ``on``, ``opaque``. This was only added in 3.6.0, so allowing a breaking change here.
- ``off``: don't show (default)
- ``on``: show with transparency
- ``opaque``: show fully opaque
- Add option to disable file drop overlay.
## [v3.6.2] - 2022-04-05
- ModelServer ligand queries: fixes for alternate locations, additional atoms & UNL ligand
@@ -27,8 +36,8 @@ Note that since we don't clearly distinguish between a public and private interf
- Fix handling of case insensitive mmCIF enumeration fields (including entity.type)
- Fix ``disable-wboit`` Viewer GET param
- Add support for React 18.
- Used by importing ``createPluginUI`` from ``mol-plugin-ui/react18``;
- In Mol* 4.0, React 18 will become the default option.
- Used by importing ``createPluginUI`` from ``mol-plugin-ui/react18``;
- In Mol* 4.0, React 18 will become the default option.
## [v3.5.0] - 2022-03-25

2531
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "molstar",
"version": "3.6.2",
"version": "3.7.0",
"description": "A comprehensive macromolecular library.",
"homepage": "https://github.com/molstar/molstar#readme",
"repository": {
@@ -94,23 +94,23 @@
"@graphql-codegen/add": "^3.1.1",
"@graphql-codegen/cli": "^2.6.2",
"@graphql-codegen/time": "^3.1.1",
"@graphql-codegen/typescript": "^2.4.7",
"@graphql-codegen/typescript": "^2.4.8",
"@graphql-codegen/typescript-graphql-files-modules": "^2.1.1",
"@graphql-codegen/typescript-graphql-request": "^4.4.2",
"@graphql-codegen/typescript-operations": "^2.3.4",
"@graphql-codegen/typescript-graphql-request": "^4.4.5",
"@graphql-codegen/typescript-operations": "^2.3.5",
"@types/cors": "^2.8.12",
"@types/gl": "^4.1.0",
"@types/jest": "^27.4.1",
"@types/react": "^17.0.43",
"@types/react-dom": "^17.0.14",
"@typescript-eslint/eslint-plugin": "^5.14.0",
"@typescript-eslint/parser": "^5.14.0",
"@types/react": "^18.0.1",
"@types/react-dom": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.18.0",
"@typescript-eslint/parser": "^5.18.0",
"benchmark": "^2.1.4",
"concurrently": "^7.0.0",
"concurrently": "^7.1.0",
"cpx2": "^4.2.0",
"crypto-browserify": "^3.12.0",
"css-loader": "^6.7.1",
"eslint": "^8.11.0",
"eslint": "^8.13.0",
"extra-watch-webpack-plugin": "^1.0.3",
"file-loader": "^6.2.0",
"fs-extra": "^10.0.1",
@@ -122,14 +122,14 @@
"raw-loader": "^4.0.2",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"sass": "^1.49.9",
"sass": "^1.50.0",
"sass-loader": "^12.6.0",
"simple-git": "^3.3.0",
"simple-git": "^3.5.0",
"stream-browserify": "^3.0.0",
"style-loader": "^3.3.1",
"ts-jest": "^27.1.3",
"ts-jest": "^27.1.4",
"typescript": "^4.6.3",
"webpack": "^5.70.0",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2"
},
"dependencies": {
@@ -141,7 +141,7 @@
"@types/node-fetch": "^2.6.1",
"@types/swagger-ui-dist": "3.30.1",
"argparse": "^2.0.1",
"body-parser": "^1.19.2",
"body-parser": "^1.20.0",
"compression": "^1.7.4",
"cors": "^2.8.5",
"express": "^4.17.3",
@@ -150,7 +150,7 @@
"immutable": "^4.0.0",
"node-fetch": "^2.6.7",
"rxjs": "^7.5.5",
"swagger-ui-dist": "^4.6.2",
"swagger-ui-dist": "^4.10.3",
"tslib": "^2.3.1",
"util.promisify": "^1.1.1",
"xhr2": "^0.2.1"

View File

@@ -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 Alexander Rose <alexander.rose@weirdbyte.de>
* @author David Sehnal <david.sehnal@gmail.com>
@@ -11,7 +11,7 @@ import { Color } from '../../mol-util/color';
import { Vec2, Vec3, Vec4 } from '../../mol-math/linear-algebra';
import { LocationIterator } from '../util/location-iterator';
import { NullLocation } from '../../mol-model/location';
import { LocationColor, ColorTheme } from '../../mol-theme/color';
import { LocationColor, ColorTheme, ColorVolume } from '../../mol-theme/color';
import { Geometry } from './geometry';
import { createNullTexture, Texture } from '../../mol-gl/webgl/texture';
@@ -48,8 +48,18 @@ function _createColors(locationIt: LocationIterator, positionIt: LocationIterato
case 'groupInstance': return createGroupInstanceColor(locationIt, colorTheme.color, colorData);
case 'vertex': return createVertexColor(positionIt, colorTheme.color, colorData);
case 'vertexInstance': return createVertexInstanceColor(positionIt, colorTheme.color, colorData);
case 'volume': return createGridColor((colorTheme as any).grid, 'volume', colorData);
case 'volumeInstance': return createGridColor((colorTheme as any).grid, 'volumeInstance', colorData);
case 'volume':
if (colorTheme.grid) {
return createGridColor(colorTheme.grid, 'volume', colorData);
} else {
throw new Error('Grid missing for "volume" color theme');
}
case 'volumeInstance':
if (colorTheme.grid) {
return createGridColor(colorTheme.grid, 'volumeInstance', colorData);
} else {
throw new Error('Grid missing for "volume" color theme');
}
case 'direct': return createDirectColor(colorData);
}
}
@@ -207,12 +217,6 @@ function createVertexInstanceColor(locationIt: LocationIterator, color: Location
//
interface ColorVolume {
colors: Texture
dimension: Vec3
transform: Vec4
}
export function createGridColor(grid: ColorVolume, type: ColorType, colorData?: ColorData): ColorData {
const { colors, dimension, transform } = grid;
const width = colors.getWidth();

View File

@@ -157,7 +157,7 @@ export namespace Cylinders {
doubleSided: PD.Boolean(false, BaseGeometry.CustomQualityParamInfo),
ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
allowTransparentBackfaces: PD.Boolean(false, BaseGeometry.ShadingCategory),
transparentBackfaces: PD.Select('off', PD.arrayToOptions(['off', 'on', 'opaque']), BaseGeometry.ShadingCategory),
bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
};
@@ -242,6 +242,7 @@ export namespace Cylinders {
uDoubleSided: ValueCell.create(props.doubleSided),
dIgnoreLight: ValueCell.create(props.ignoreLight),
dXrayShaded: ValueCell.create(props.xrayShaded),
dOpaqueBackfaces: ValueCell.create(props.transparentBackfaces === 'opaque'),
uBumpFrequency: ValueCell.create(props.bumpFrequency),
uBumpAmplitude: ValueCell.create(props.bumpAmplitude),
};
@@ -259,6 +260,7 @@ export namespace Cylinders {
ValueCell.updateIfChanged(values.uDoubleSided, props.doubleSided);
ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
ValueCell.updateIfChanged(values.dOpaqueBackfaces, props.transparentBackfaces === 'opaque');
ValueCell.updateIfChanged(values.uBumpFrequency, props.bumpFrequency);
ValueCell.updateIfChanged(values.uBumpAmplitude, props.bumpAmplitude);
}

View File

@@ -625,7 +625,7 @@ export namespace Mesh {
flatShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
allowTransparentBackfaces: PD.Boolean(false, BaseGeometry.ShadingCategory),
transparentBackfaces: PD.Select('off', PD.arrayToOptions(['off', 'on', 'opaque']), BaseGeometry.ShadingCategory),
bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
};
@@ -701,6 +701,7 @@ export namespace Mesh {
dFlipSided: ValueCell.create(props.flipSided),
dIgnoreLight: ValueCell.create(props.ignoreLight),
dXrayShaded: ValueCell.create(props.xrayShaded),
dOpaqueBackfaces: ValueCell.create(props.transparentBackfaces === 'opaque'),
uBumpFrequency: ValueCell.create(props.bumpFrequency),
uBumpAmplitude: ValueCell.create(props.bumpAmplitude),
@@ -721,6 +722,7 @@ export namespace Mesh {
ValueCell.updateIfChanged(values.dFlipSided, props.flipSided);
ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
ValueCell.updateIfChanged(values.dOpaqueBackfaces, props.transparentBackfaces === 'opaque');
ValueCell.updateIfChanged(values.uBumpFrequency, props.bumpFrequency);
ValueCell.updateIfChanged(values.uBumpAmplitude, props.bumpAmplitude);
}

View File

@@ -129,7 +129,7 @@ export namespace Spheres {
doubleSided: PD.Boolean(false, BaseGeometry.CustomQualityParamInfo),
ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
allowTransparentBackfaces: PD.Boolean(false, BaseGeometry.ShadingCategory),
transparentBackfaces: PD.Select('off', PD.arrayToOptions(['off', 'on', 'opaque']), BaseGeometry.ShadingCategory),
bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
};
@@ -209,6 +209,7 @@ export namespace Spheres {
uDoubleSided: ValueCell.create(props.doubleSided),
dIgnoreLight: ValueCell.create(props.ignoreLight),
dXrayShaded: ValueCell.create(props.xrayShaded),
dOpaqueBackfaces: ValueCell.create(props.transparentBackfaces === 'opaque'),
uBumpFrequency: ValueCell.create(props.bumpFrequency),
uBumpAmplitude: ValueCell.create(props.bumpAmplitude),
};
@@ -226,6 +227,7 @@ export namespace Spheres {
ValueCell.updateIfChanged(values.uDoubleSided, props.doubleSided);
ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
ValueCell.updateIfChanged(values.dOpaqueBackfaces, props.transparentBackfaces === 'opaque');
ValueCell.updateIfChanged(values.uBumpFrequency, props.bumpFrequency);
ValueCell.updateIfChanged(values.uBumpAmplitude, props.bumpAmplitude);
}

View File

@@ -24,6 +24,7 @@ import { Vec2, Vec4 } from '../../../mol-math/linear-algebra';
import { createEmptyClipping } from '../clipping-data';
import { NullLocation } from '../../../mol-model/location';
import { createEmptySubstance } from '../substance-data';
import { RenderableState } from '../../../mol-gl/renderable';
export interface TextureMesh {
readonly kind: 'texture-mesh',
@@ -113,7 +114,7 @@ export namespace TextureMesh {
flatShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
ignoreLight: PD.Boolean(false, BaseGeometry.ShadingCategory),
xrayShaded: PD.Boolean(false, BaseGeometry.ShadingCategory),
allowTransparentBackfaces: PD.Boolean(false, BaseGeometry.ShadingCategory),
transparentBackfaces: PD.Select('off', PD.arrayToOptions(['off', 'on', 'opaque']), BaseGeometry.ShadingCategory),
bumpFrequency: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }, BaseGeometry.ShadingCategory),
bumpAmplitude: PD.Numeric(1, { min: 0, max: 5, step: 0.1 }, BaseGeometry.ShadingCategory),
};
@@ -126,8 +127,8 @@ export namespace TextureMesh {
createValuesSimple,
updateValues,
updateBoundingSphere,
createRenderableState: BaseGeometry.createRenderableState,
updateRenderableState: BaseGeometry.updateRenderableState,
createRenderableState,
updateRenderableState,
createPositionIterator: () => LocationIterator(1, 1, 1, () => NullLocation)
};
@@ -173,6 +174,7 @@ export namespace TextureMesh {
dFlipSided: ValueCell.create(props.flipSided),
dIgnoreLight: ValueCell.create(props.ignoreLight),
dXrayShaded: ValueCell.create(props.xrayShaded),
dOpaqueBackfaces: ValueCell.create(props.transparentBackfaces === 'opaque'),
uBumpFrequency: ValueCell.create(props.bumpFrequency),
uBumpAmplitude: ValueCell.create(props.bumpAmplitude),
@@ -193,6 +195,7 @@ export namespace TextureMesh {
ValueCell.updateIfChanged(values.dFlipSided, props.flipSided);
ValueCell.updateIfChanged(values.dIgnoreLight, props.ignoreLight);
ValueCell.updateIfChanged(values.dXrayShaded, props.xrayShaded);
ValueCell.updateIfChanged(values.dOpaqueBackfaces, props.transparentBackfaces === 'opaque');
ValueCell.updateIfChanged(values.uBumpFrequency, props.bumpFrequency);
ValueCell.updateIfChanged(values.uBumpAmplitude, props.bumpAmplitude);
}
@@ -209,4 +212,16 @@ export namespace TextureMesh {
ValueCell.update(values.uInvariantBoundingSphere, Vec4.fromSphere(values.uInvariantBoundingSphere.ref.value, invariantBoundingSphere));
}
}
function createRenderableState(props: PD.Values<Params>): RenderableState {
const state = BaseGeometry.createRenderableState(props);
updateRenderableState(state, props);
return state;
}
function updateRenderableState(state: RenderableState, props: PD.Values<Params>) {
BaseGeometry.updateRenderableState(state, props);
state.opaque = state.opaque && !props.xrayShaded;
state.writeDepth = state.opaque;
}
}

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -26,6 +26,7 @@ export const CylindersSchema = {
uDoubleSided: UniformSpec('b'),
dIgnoreLight: DefineSpec('boolean'),
dXrayShaded: DefineSpec('boolean'),
dOpaqueBackfaces: DefineSpec('boolean'),
uBumpFrequency: UniformSpec('f'),
uBumpAmplitude: UniformSpec('f'),
};

View File

@@ -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 Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -22,6 +22,7 @@ export const MeshSchema = {
dFlipSided: DefineSpec('boolean'),
dIgnoreLight: DefineSpec('boolean'),
dXrayShaded: DefineSpec('boolean'),
dOpaqueBackfaces: DefineSpec('boolean'),
uBumpFrequency: UniformSpec('f'),
uBumpAmplitude: UniformSpec('f'),
meta: ValueSpec('unknown')

View File

@@ -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>
*/
@@ -23,6 +23,7 @@ export const SpheresSchema = {
uDoubleSided: UniformSpec('b'),
dIgnoreLight: DefineSpec('boolean'),
dXrayShaded: DefineSpec('boolean'),
dOpaqueBackfaces: DefineSpec('boolean'),
uBumpFrequency: UniformSpec('f'),
uBumpAmplitude: UniformSpec('f'),
};

View File

@@ -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>
*/
@@ -23,6 +23,7 @@ export const TextureMeshSchema = {
dFlipSided: DefineSpec('boolean'),
dIgnoreLight: DefineSpec('boolean'),
dXrayShaded: DefineSpec('boolean'),
dOpaqueBackfaces: DefineSpec('boolean'),
uBumpFrequency: UniformSpec('f'),
uBumpAmplitude: UniformSpec('f'),
meta: ValueSpec('unknown')

View File

@@ -135,6 +135,12 @@ function getLight(props: RendererProps['light'], light?: Light): Light {
}
namespace Renderer {
const enum Flag {
None = 0,
BlendedFront = 1,
BlendedBack = 2
}
export function create(ctx: WebGLContext, props: Partial<RendererProps> = {}): Renderer {
const { gl, state, stats } = ctx;
const p = PD.merge(RendererParams, PD.getDefaultValues(RendererParams), props);
@@ -220,7 +226,7 @@ namespace Renderer {
let globalUniformsNeedUpdate = true;
const renderObject = (r: GraphicsRenderable, variant: GraphicsRenderVariant) => {
const renderObject = (r: GraphicsRenderable, variant: GraphicsRenderVariant, flag: Flag) => {
if (r.state.disposed || !r.state.visible || (!r.state.pickable && variant === 'pick')) {
return;
}
@@ -259,6 +265,24 @@ namespace Renderer {
state.disable(gl.DEPTH_TEST);
state.depthMask(false);
}
} else if (flag === Flag.BlendedFront) {
state.enable(gl.CULL_FACE);
if (r.values.dFlipSided?.ref.value) {
state.frontFace(gl.CW);
state.cullFace(gl.FRONT);
} else {
state.frontFace(gl.CCW);
state.cullFace(gl.BACK);
}
} else if (flag === Flag.BlendedBack) {
state.enable(gl.CULL_FACE);
if (r.values.dFlipSided?.ref.value) {
state.frontFace(gl.CW);
state.cullFace(gl.BACK);
} else {
state.frontFace(gl.CCW);
state.cullFace(gl.FRONT);
}
} else {
if (r.values.uDoubleSided) {
if (r.values.uDoubleSided.ref.value || r.values.hasReflection.ref.value) {
@@ -271,14 +295,9 @@ namespace Renderer {
state.disable(gl.CULL_FACE);
}
if (r.values.dFlipSided) {
if (r.values.dFlipSided.ref.value) {
state.frontFace(gl.CW);
state.cullFace(gl.FRONT);
} else {
state.frontFace(gl.CCW);
state.cullFace(gl.BACK);
}
if (r.values.dFlipSided?.ref.value) {
state.frontFace(gl.CW);
state.cullFace(gl.FRONT);
} else {
// webgl default
state.frontFace(gl.CCW);
@@ -342,7 +361,7 @@ namespace Renderer {
const { renderables } = group;
for (let i = 0, il = renderables.length; i < il; ++i) {
if (!renderables[i].state.colorOnly) {
renderObject(renderables[i], variant);
renderObject(renderables[i], variant, Flag.None);
}
}
};
@@ -356,7 +375,7 @@ namespace Renderer {
const { renderables } = group;
for (let i = 0, il = renderables.length; i < il; ++i) {
renderObject(renderables[i], 'depth');
renderObject(renderables[i], 'depth', Flag.None);
}
};
@@ -373,7 +392,7 @@ namespace Renderer {
const r = renderables[i];
if (r.values.markerAverage.ref.value !== 1) {
renderObject(renderables[i], 'marking');
renderObject(renderables[i], 'marking', Flag.None);
}
}
};
@@ -391,7 +410,7 @@ namespace Renderer {
const r = renderables[i];
if (r.values.markerAverage.ref.value > 0) {
renderObject(renderables[i], 'marking');
renderObject(renderables[i], 'marking', Flag.None);
}
}
};
@@ -412,7 +431,9 @@ namespace Renderer {
for (let i = 0, il = renderables.length; i < il; ++i) {
const r = renderables[i];
if (r.state.opaque) {
renderObject(r, 'colorBlended');
renderObject(r, 'colorBlended', Flag.None);
} else if (r.values.uDoubleSided?.ref.value && r.values.dOpaqueBackfaces?.ref.value) {
renderObject(r, 'colorBlended', Flag.BlendedBack);
}
}
};
@@ -435,7 +456,7 @@ namespace Renderer {
for (let i = 0, il = renderables.length; i < il; ++i) {
const r = renderables[i];
if (!r.state.opaque && r.state.writeDepth) {
renderObject(r, 'colorBlended');
renderObject(r, 'colorBlended', Flag.None);
}
}
@@ -443,7 +464,15 @@ namespace Renderer {
for (let i = 0, il = renderables.length; i < il; ++i) {
const r = renderables[i];
if (!r.state.opaque && !r.state.writeDepth) {
renderObject(r, 'colorBlended');
if (r.values.uDoubleSided?.ref.value) {
// render frontfaces and backfaces separately to avoid artefacts
if (!r.values.dOpaqueBackfaces?.ref.value) {
renderObject(r, 'colorBlended', Flag.BlendedBack);
}
renderObject(r, 'colorBlended', Flag.BlendedFront);
} else {
renderObject(r, 'colorBlended', Flag.None);
}
}
}
};
@@ -462,7 +491,7 @@ namespace Renderer {
// uAlpha is updated in "render" so we need to recompute it here
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
if (alpha === 1 && r.values.transparencyAverage.ref.value !== 1 && !r.values.dXrayShaded?.ref.value) {
renderObject(r, 'colorBlended');
renderObject(r, 'colorBlended', Flag.None);
}
}
};
@@ -481,7 +510,7 @@ namespace Renderer {
// uAlpha is updated in "render" so we need to recompute it here
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
if (alpha < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dXrayShaded?.ref.value) {
renderObject(r, 'colorBlended');
renderObject(r, 'colorBlended', Flag.None);
}
}
};
@@ -500,8 +529,8 @@ namespace Renderer {
// TODO: simplify, handle in renderable.state???
// uAlpha is updated in "render" so we need to recompute it here
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
if (alpha === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values.dGeometryType.ref.value !== 'directVolume' && r.values.dPointStyle?.ref.value !== 'fuzzy' && !r.values.dXrayShaded?.ref.value) {
renderObject(r, 'colorWboit');
if ((alpha === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values.dGeometryType.ref.value !== 'directVolume' && r.values.dPointStyle?.ref.value !== 'fuzzy' && !r.values.dXrayShaded?.ref.value) || r.values.dOpaqueBackfaces?.ref.value) {
renderObject(r, 'colorWboit', Flag.None);
}
}
};
@@ -517,7 +546,7 @@ namespace Renderer {
// uAlpha is updated in "render" so we need to recompute it here
const alpha = clamp(r.values.alpha.ref.value * r.state.alphaFactor, 0, 1);
if (alpha < 1 || r.values.transparencyAverage.ref.value > 0 || r.values.dGeometryType.ref.value === 'directVolume' || r.values.dPointStyle?.ref.value === 'fuzzy' || !!r.values.uBackgroundColor || r.values.dXrayShaded?.ref.value) {
renderObject(r, 'colorWboit');
renderObject(r, 'colorWboit', Flag.None);
}
}
};

View File

@@ -5,5 +5,9 @@ if (interior) {
} else {
gl_FragColor.rgb *= 1.0 - uInteriorDarkening;
}
#ifdef dOpaqueBackfaces
gl_FragColor.a = 1.0;
#endif
}
`;

View File

@@ -2,6 +2,12 @@ export const check_picking_alpha = `
float viewZ = depthToViewZ(uIsOrtho, fragmentDepth, uNear, uFar);
float fogFactor = smoothstep(uFogNear, uFogFar, abs(viewZ));
float alpha = (1.0 - fogFactor) * uAlpha;
if (uAlpha < uPickingAlphaThreshold || alpha < 0.1)
discard; // ignore so the element below can be picked
// if not opaque enough ignore so the element below can be picked
if (uAlpha < uPickingAlphaThreshold || alpha < 0.1) {
#ifdef dOpaqueBackfaces
if (!interior) discard;
#else
discard;
#endif
}
`;

View File

@@ -19,6 +19,8 @@ uniform float uBumpiness;
uniform vec3 uColorGridDim;
uniform vec4 uColorGridTransform;
uniform sampler2D tColorGrid;
#elif defined(dColorType_direct)
varying vec4 vColor;
#endif
#ifdef dUsePalette

View File

@@ -13,7 +13,7 @@ import { Icon, ArrowRightSvg, ArrowDropDownSvg } from './controls/icons';
export const PluginReactContext = React.createContext(void 0 as any as PluginUIContext);
export abstract class PluginUIComponent<P = {}, S = {}, SS = {}> extends React.Component<P, S, SS> {
export abstract class PluginUIComponent<P = {}, S = {}, SS = {}> extends React.Component<P & { children?: any }, S, SS> {
static contextType = PluginReactContext;
readonly plugin: PluginUIContext;

View File

@@ -92,7 +92,7 @@ export class CombinedColorControl extends React.PureComponent<ParamProps<PD.Colo
}
}
let _colors: React.ReactFragment | undefined = void 0;
let _colors: any = void 0;
export function ColorOptions() {
if (_colors) return _colors;
_colors = <>{DefaultColorSwatch.map(v =>

View File

@@ -21,7 +21,8 @@ export class ControlGroup extends React.Component<{
onHeaderClick?: () => void,
noTopMargin?: boolean,
childrenClassName?: string,
maxHeight?: string
maxHeight?: string,
children?: any
}, { isExpanded: boolean }> {
state = { isExpanded: !!this.props.initialExpanded };
@@ -335,7 +336,7 @@ export class ToggleButton extends React.PureComponent<ToggleButtonProps> {
}
}
export class ExpandGroup extends React.PureComponent<{ header: string, headerStyle?: React.CSSProperties, initiallyExpanded?: boolean, accent?: boolean, noOffset?: boolean, marginTop?: 0 | string, headerLeftMargin?: string }, { isExpanded: boolean }> {
export class ExpandGroup extends React.PureComponent<{ children?: any, header: string, headerStyle?: React.CSSProperties, initiallyExpanded?: boolean, accent?: boolean, noOffset?: boolean, marginTop?: 0 | string, headerLeftMargin?: string }, { isExpanded: boolean }> {
state = { isExpanded: !!this.props.initiallyExpanded };
toggleExpanded = () => this.setState({ isExpanded: !this.state.isExpanded });

View File

@@ -23,7 +23,7 @@ import { Asset } from '../mol-util/assets';
import { BehaviorSubject } from 'rxjs';
import { useBehavior } from './hooks/use-behavior';
export class Plugin extends React.Component<{ plugin: PluginUIContext }, {}> {
export class Plugin extends React.Component<{ plugin: PluginUIContext, children?: any }, {}> {
region(kind: 'left' | 'right' | 'bottom' | 'main', element: JSX.Element) {
return <div className={`msp-layout-region msp-layout-${kind}`}>
<div className='msp-layout-static'>
@@ -39,7 +39,7 @@ export class Plugin extends React.Component<{ plugin: PluginUIContext }, {}> {
}
}
export class PluginContextContainer extends React.Component<{ plugin: PluginUIContext }> {
export class PluginContextContainer extends React.Component<{ plugin: PluginUIContext, children?: any }> {
render() {
return <PluginReactContext.Provider value={this.props.plugin}>
<div className='msp-plugin'>
@@ -159,7 +159,7 @@ class Layout extends PluginUIComponent {
{layout.showControls && controls.bottom !== 'none' && this.region('bottom', controls.bottom || Log)}
</div>
{!this.plugin.spec.components?.hideTaskOverlay && <OverlayTaskProgress />}
<DragOverlay plugin={this.plugin} showDragOverlay={this.showDragOverlay} />
{!this.plugin.spec.components?.disableDragOverlay && <DragOverlay plugin={this.plugin} showDragOverlay={this.showDragOverlay} />}
</div>
</div>;
}

View File

@@ -24,7 +24,8 @@ interface PluginUISpec extends PluginSpec {
view?: React.ComponentClass,
controls?: React.ComponentClass
},
hideTaskOverlay?: boolean
hideTaskOverlay?: boolean,
disableDragOverlay?: boolean,
},
}

View File

@@ -37,7 +37,7 @@ export class BindingsHelp extends React.PureComponent<{ bindings: { [k: string]:
}
}
export class HelpText extends React.PureComponent {
export class HelpText extends React.PureComponent<{ children?: any }> {
render() {
return <div className='msp-help-text'>
<div>{this.props.children}</div>
@@ -45,7 +45,7 @@ export class HelpText extends React.PureComponent {
}
}
export class HelpGroup extends React.PureComponent<{ header: string, initiallyExpanded?: boolean }, { isExpanded: boolean }> {
export class HelpGroup extends React.PureComponent<{ children?: any, header: string, initiallyExpanded?: boolean }, { isExpanded: boolean }> {
state = {
header: this.props.header,
isExpanded: !!this.props.initiallyExpanded

View File

@@ -57,7 +57,7 @@ export interface QualityProps {
doubleSided: boolean
xrayShaded: boolean
alpha: number
allowTransparentBackfaces: boolean
transparentBackfaces: 'off' | 'on' | 'opaque'
}
export const DefaultQualityThresholds = {
@@ -193,7 +193,7 @@ export function getQualityProps(props: Partial<QualityProps>, data?: any) {
resolution = Math.max(resolution, volume / 500_000_000);
resolution = Math.min(resolution, 20);
if (!props.allowTransparentBackfaces && ((props.alpha !== undefined && props.alpha < 1) || !!props.xrayShaded)) {
if (props.transparentBackfaces === 'off' && ((props.alpha !== undefined && props.alpha < 1) || !!props.xrayShaded)) {
doubleSided = false;
}

View File

@@ -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 Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -35,17 +35,25 @@ import { OperatorHklColorThemeProvider } from './color/operator-hkl';
import { PartialChargeColorThemeProvider } from './color/partial-charge';
import { AtomIdColorThemeProvider } from './color/atom-id';
import { EntityIdColorThemeProvider } from './color/entity-id';
import { TextureFilter } from '../mol-gl/webgl/texture';
import { Texture, TextureFilter } from '../mol-gl/webgl/texture';
import { VolumeValueColorThemeProvider } from './color/volume-value';
import { Vec3, Vec4 } from '../mol-math/linear-algebra';
export type LocationColor = (location: Location, isSecondary: boolean) => Color
export interface ColorVolume {
colors: Texture
dimension: Vec3
transform: Vec4
}
export { ColorTheme };
interface ColorTheme<P extends PD.Params> {
readonly factory: ColorTheme.Factory<P>
readonly granularity: ColorType
readonly color: LocationColor
readonly props: Readonly<PD.Values<P>>
readonly grid?: ColorVolume
/**
* if palette is defined, 24bit RGB color value normalized to interval [0, 1]
* is used as index to the colors