diff --git a/CHANGELOG.md b/CHANGELOG.md index bf25fdbbf75702333693826f711f73fe8d117339..2ee4e47af2c6575b785e6e0fd0d4729ceebc745b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Note that since we don't clearly distinguish between a public and private interf - Show histogram in direct volume control point settings - Add `solidInterior` parameter to sphere/cylinder impostors +- [Breaking] Tweak `ignoreHydrogens` non-polar handling (introduced in 3.27.0) - Add `meshes` and `volumes-and-segmentations` extensions - Fix missing support for info in `ParamDefinition.Converted` - Add support for multi-visual volume representations diff --git a/src/mol-plugin-state/builder/structure/representation-preset.ts b/src/mol-plugin-state/builder/structure/representation-preset.ts index 2f5d6d410c7a7caadaee2844e4c6ae52404f61e9..57568a3ec3b663b7c574ac82d08de3093a69d32c 100644 --- a/src/mol-plugin-state/builder/structure/representation-preset.ts +++ b/src/mol-plugin-state/builder/structure/representation-preset.ts @@ -37,7 +37,7 @@ export namespace StructureRepresentationPresetProvider { export const CommonParams = { ignoreHydrogens: PD.Optional(PD.Boolean(false)), - onlyPolarHydrogens: PD.Optional(PD.Boolean(false)), + ignoreHydrogensVariant: PD.Optional(PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const))), ignoreLight: PD.Optional(PD.Boolean(false)), quality: PD.Optional(PD.Select<VisualQuality>('auto', VisualQualityOptions)), theme: PD.Optional(PD.Group({ @@ -69,15 +69,16 @@ export namespace StructureRepresentationPresetProvider { export function reprBuilder(plugin: PluginContext, params: CommonParams, structure?: Structure) { const update = plugin.state.data.build(); const builder = plugin.builders.structure.representation; + const h = plugin.managers.structure.component.state.options.hydrogens; const typeParams = { quality: plugin.managers.structure.component.state.options.visualQuality, - ignoreHydrogens: plugin.managers.structure.component.state.options.hydrogens === 'hide-all', - onlyPolarHydrogens: plugin.managers.structure.component.state.options.hydrogens === 'only-polar', + ignoreHydrogens: h !== 'all', + ignoreHydrogensVariant: (h === 'only-polar' ? 'non-polar' : 'all') as 'all' | 'non-polar', ignoreLight: plugin.managers.structure.component.state.options.ignoreLight, }; if (params.quality && params.quality !== 'auto') typeParams.quality = params.quality; if (params.ignoreHydrogens !== void 0) typeParams.ignoreHydrogens = !!params.ignoreHydrogens; - if (params.onlyPolarHydrogens !== void 0) typeParams.onlyPolarHydrogens = !!params.onlyPolarHydrogens; + if (params.ignoreHydrogensVariant !== void 0) typeParams.ignoreHydrogensVariant = params.ignoreHydrogensVariant; if (params.ignoreLight !== void 0) typeParams.ignoreLight = !!params.ignoreLight; const color: ColorTheme.BuiltIn | undefined = params.theme?.globalName ? params.theme?.globalName : void 0; const ballAndStickColor: ColorTheme.BuiltInParams<'element-symbol'> = params.theme?.carbonColor !== undefined diff --git a/src/mol-plugin-state/manager/structure/component.ts b/src/mol-plugin-state/manager/structure/component.ts index d8c3f4d4873f0d9f0463067292bf1084e00620b7..5c72786cfd4c3e9fd3f4265100738d4a47889ed0 100644 --- a/src/mol-plugin-state/manager/structure/component.ts +++ b/src/mol-plugin-state/manager/structure/component.ts @@ -70,8 +70,8 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone return this.plugin.dataTransaction(async () => { await update.commit(); await this.plugin.state.updateBehavior(StructureFocusRepresentation, p => { - p.ignoreHydrogens = options.hydrogens === 'hide-all'; - p.onlyPolarHydrogens = options.hydrogens === 'only-polar'; + p.ignoreHydrogens = options.hydrogens !== 'all'; + p.ignoreHydrogensVariant = options.hydrogens === 'only-polar' ? 'non-polar' : 'all'; p.ignoreLight = options.ignoreLight; p.material = options.materialStyle; p.clip = options.clipObjects; @@ -82,16 +82,16 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone private updateReprParams(update: StateBuilder.Root, component: StructureComponentRef) { const { hydrogens, visualQuality: quality, ignoreLight, materialStyle: material, clipObjects: clip } = this.state.options; - const ignoreHydrogens = hydrogens === 'hide-all'; - const onlyPolarHydrogens = hydrogens === 'only-polar'; + const ignoreHydrogens = hydrogens !== 'all'; + const ignoreHydrogensVariant = hydrogens === 'only-polar' ? 'non-polar' : 'all'; for (const r of component.representations) { if (r.cell.transform.transformer !== StructureRepresentation3D) continue; const params = r.cell.transform.params as StateTransformer.Params<StructureRepresentation3D>; - if (!!params.type.params.ignoreHydrogens !== ignoreHydrogens || !!params.type.params.onlyPolarHydrogens !== onlyPolarHydrogens || params.type.params.quality !== quality || params.type.params.ignoreLight !== ignoreLight || !shallowEqual(params.type.params.material, material) || !PD.areEqual(Clip.Params, params.type.params.clip, clip)) { + if (!!params.type.params.ignoreHydrogens !== ignoreHydrogens || params.type.params.ignoreHydrogensVariant !== ignoreHydrogensVariant || params.type.params.quality !== quality || params.type.params.ignoreLight !== ignoreLight || !shallowEqual(params.type.params.material, material) || !PD.areEqual(Clip.Params, params.type.params.clip, clip)) { update.to(r.cell).update(old => { old.type.params.ignoreHydrogens = ignoreHydrogens; - old.type.params.onlyPolarHydrogens = onlyPolarHydrogens; + old.type.params.ignoreHydrogensVariant = ignoreHydrogensVariant; old.type.params.quality = quality; old.type.params.ignoreLight = ignoreLight; old.type.params.material = material; @@ -315,9 +315,9 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone if (components.length === 0) return; const { hydrogens, visualQuality: quality, ignoreLight, materialStyle: material, clipObjects: clip } = this.state.options; - const ignoreHydrogens = hydrogens === 'hide-all'; - const onlyPolarHydrogens = hydrogens === 'only-polar'; - const typeParams = { ignoreHydrogens, onlyPolarHydrogens, quality, ignoreLight, material, clip }; + const ignoreHydrogens = hydrogens !== 'all'; + const ignoreHydrogensVariant = hydrogens === 'only-polar' ? 'non-polar' : 'all'; + const typeParams = { ignoreHydrogens, ignoreHydrogensVariant, quality, ignoreLight, material, clip }; return this.plugin.dataTransaction(async () => { for (const component of components) { @@ -353,9 +353,9 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone if (xs.length === 0) return; const { hydrogens, visualQuality: quality, ignoreLight, materialStyle: material, clipObjects: clip } = this.state.options; - const ignoreHydrogens = hydrogens === 'hide-all'; - const onlyPolarHydrogens = hydrogens === 'only-polar'; - const typeParams = { ignoreHydrogens, onlyPolarHydrogens, quality, ignoreLight, material, clip }; + const ignoreHydrogens = hydrogens !== 'all'; + const ignoreHydrogensVariant = hydrogens === 'only-polar' ? 'non-polar' : 'all'; + const typeParams = { ignoreHydrogens, ignoreHydrogensVariant, quality, ignoreLight, material, clip }; const componentKey = UUID.create22(); for (const s of xs) { diff --git a/src/mol-plugin/behavior/dynamic/selection/structure-focus-representation.ts b/src/mol-plugin/behavior/dynamic/selection/structure-focus-representation.ts index e548d8e8b0117d630ce2bdb6b85d4440e73618e0..344b5b1bbf0b30f65b1e99c2fe3ca860b5c4bf7d 100644 --- a/src/mol-plugin/behavior/dynamic/selection/structure-focus-representation.ts +++ b/src/mol-plugin/behavior/dynamic/selection/structure-focus-representation.ts @@ -52,7 +52,7 @@ const StructureFocusRepresentationParams = (plugin: PluginContext) => { components: PD.MultiSelect(FocusComponents, PD.arrayToOptions(FocusComponents)), excludeTargetFromSurroundings: PD.Boolean(false, { label: 'Exclude Target', description: 'Exclude the focus "target" from the surroudings component.' }), ignoreHydrogens: PD.Boolean(false), - onlyPolarHydrogens: PD.Boolean(false), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), ignoreLight: PD.Boolean(false), material: Material.getParam(), clip: PD.Group(Clip.Params), @@ -81,7 +81,7 @@ class StructureFocusRepresentationBehavior extends PluginBehavior.WithSubscriber ...reprParams, type: { name: reprParams.type.name, - params: { ...reprParams.type.params, ignoreHydrogens: this.params.ignoreHydrogens, onlyPolarHydrogens: this.params.onlyPolarHydrogens, ignoreLight: this.params.ignoreLight, material: this.params.material, clip: this.params.clip } + params: { ...reprParams.type.params, ignoreHydrogens: this.params.ignoreHydrogens, ignoreHydrogensVariant: this.params.ignoreHydrogensVariant, ignoreLight: this.params.ignoreLight, material: this.params.material, clip: this.params.clip } } }; } diff --git a/src/mol-repr/structure/visual/bond-inter-unit-cylinder.ts b/src/mol-repr/structure/visual/bond-inter-unit-cylinder.ts index 0d9476ce3d49cffac7f03538de7c9e25939c18ca..de91c4d9b737618af0d715be2f60409767d184a6 100644 --- a/src/mol-repr/structure/visual/bond-inter-unit-cylinder.ts +++ b/src/mol-repr/structure/visual/bond-inter-unit-cylinder.ts @@ -222,7 +222,7 @@ export function InterUnitBondCylinderImpostorVisual(materialId: number): Complex newProps.linkScale !== currentProps.linkScale || newProps.linkSpacing !== currentProps.linkSpacing || newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || newProps.linkCap !== currentProps.linkCap || newProps.aromaticScale !== currentProps.aromaticScale || newProps.aromaticSpacing !== currentProps.aromaticSpacing || @@ -265,7 +265,7 @@ export function InterUnitBondCylinderMeshVisual(materialId: number): ComplexVisu newProps.linkScale !== currentProps.linkScale || newProps.linkSpacing !== currentProps.linkSpacing || newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || newProps.linkCap !== currentProps.linkCap || newProps.aromaticScale !== currentProps.aromaticScale || newProps.aromaticSpacing !== currentProps.aromaticSpacing || diff --git a/src/mol-repr/structure/visual/bond-inter-unit-line.ts b/src/mol-repr/structure/visual/bond-inter-unit-line.ts index ab6c1436b2bf8e72ea202baf37d17af9fbb73de9..7840e0abbc81bde59f54ea3a134f4382676e7b55 100644 --- a/src/mol-repr/structure/visual/bond-inter-unit-line.ts +++ b/src/mol-repr/structure/visual/bond-inter-unit-line.ts @@ -138,7 +138,7 @@ export function InterUnitBondLineVisual(materialId: number): ComplexVisual<Inter newProps.aromaticDashCount !== currentProps.aromaticDashCount || newProps.dashCount !== currentProps.dashCount || newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || !arrayEqual(newProps.includeTypes, currentProps.includeTypes) || !arrayEqual(newProps.excludeTypes, currentProps.excludeTypes) || newProps.multipleBonds !== currentProps.multipleBonds diff --git a/src/mol-repr/structure/visual/bond-intra-unit-cylinder.ts b/src/mol-repr/structure/visual/bond-intra-unit-cylinder.ts index 5e2e95dadf39197bfeb4ec4078b4712e43187573..3eaaf9b4de773d798fd10cab5acbf7ca0ea4b4ca 100644 --- a/src/mol-repr/structure/visual/bond-intra-unit-cylinder.ts +++ b/src/mol-repr/structure/visual/bond-intra-unit-cylinder.ts @@ -239,7 +239,7 @@ export function IntraUnitBondCylinderImpostorVisual(materialId: number): UnitsVi newProps.linkScale !== currentProps.linkScale || newProps.linkSpacing !== currentProps.linkSpacing || newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || newProps.linkCap !== currentProps.linkCap || newProps.aromaticScale !== currentProps.aromaticScale || newProps.aromaticSpacing !== currentProps.aromaticSpacing || @@ -287,7 +287,7 @@ export function IntraUnitBondCylinderMeshVisual(materialId: number): UnitsVisual newProps.linkScale !== currentProps.linkScale || newProps.linkSpacing !== currentProps.linkSpacing || newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || newProps.linkCap !== currentProps.linkCap || newProps.aromaticScale !== currentProps.aromaticScale || newProps.aromaticSpacing !== currentProps.aromaticSpacing || diff --git a/src/mol-repr/structure/visual/bond-intra-unit-line.ts b/src/mol-repr/structure/visual/bond-intra-unit-line.ts index 640d93cda7384a7e2ba470aacfb29c2a113b4141..64bb78a1678c3483dda9857a7d306944ae4b2eb2 100644 --- a/src/mol-repr/structure/visual/bond-intra-unit-line.ts +++ b/src/mol-repr/structure/visual/bond-intra-unit-line.ts @@ -164,7 +164,7 @@ export function IntraUnitBondLineVisual(materialId: number): UnitsVisual<IntraUn newProps.aromaticDashCount !== currentProps.aromaticDashCount || newProps.dashCount !== currentProps.dashCount || newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || !arrayEqual(newProps.includeTypes, currentProps.includeTypes) || !arrayEqual(newProps.excludeTypes, currentProps.excludeTypes) || newProps.aromaticBonds !== currentProps.aromaticBonds || diff --git a/src/mol-repr/structure/visual/element-cross.ts b/src/mol-repr/structure/visual/element-cross.ts index d69d80ba3a583ffa01dd3c7106ca245b4ce91f5c..7955ab1c6c0ab31aada875d740365ccb8adc88b0 100644 --- a/src/mol-repr/structure/visual/element-cross.ts +++ b/src/mol-repr/structure/visual/element-cross.ts @@ -27,7 +27,7 @@ export const ElementCrossParams = { ...UnitsLinesParams, lineSizeAttenuation: PD.Boolean(false), ignoreHydrogens: PD.Boolean(false), - onlyPolarHydrogens: PD.Boolean(false), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), traceOnly: PD.Boolean(false), crosses: PD.Select('lone', PD.arrayToOptions(['lone', 'all'] as const)), crossSize: PD.Numeric(0.35, { min: 0, max: 2, step: 0.01 }), @@ -86,7 +86,7 @@ export function ElementCrossVisual(materialId: number): UnitsVisual<ElementCross setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementCrossParams>, currentProps: PD.Values<ElementCrossParams>) => { state.createGeometry = ( newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || newProps.traceOnly !== currentProps.traceOnly || newProps.crosses !== currentProps.crosses || newProps.crossSize !== currentProps.crossSize diff --git a/src/mol-repr/structure/visual/element-point.ts b/src/mol-repr/structure/visual/element-point.ts index a50e5fc9cdd5e39f01bccd79b29e7b84dccac7c2..d6e24c3bc1c115a78d62c06f6639cfd62d2702e3 100644 --- a/src/mol-repr/structure/visual/element-point.ts +++ b/src/mol-repr/structure/visual/element-point.ts @@ -23,7 +23,7 @@ export const ElementPointParams = { ...UnitsPointsParams, pointSizeAttenuation: PD.Boolean(false), ignoreHydrogens: PD.Boolean(false), - onlyPolarHydrogens: PD.Boolean(false), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), traceOnly: PD.Boolean(false), }; export type ElementPointParams = typeof ElementPointParams @@ -90,7 +90,7 @@ export function ElementPointVisual(materialId: number): UnitsVisual<ElementPoint setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementPointParams>, currentProps: PD.Values<ElementPointParams>) => { state.createGeometry = ( newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || newProps.traceOnly !== currentProps.traceOnly ); } diff --git a/src/mol-repr/structure/visual/element-sphere.ts b/src/mol-repr/structure/visual/element-sphere.ts index 909934efd8b6e630921ca1e2126b12f7c27e60d4..1e95bbdfdd59d1797cc48a60921ba62ffc167aec 100644 --- a/src/mol-repr/structure/visual/element-sphere.ts +++ b/src/mol-repr/structure/visual/element-sphere.ts @@ -20,7 +20,7 @@ export const ElementSphereParams = { sizeFactor: PD.Numeric(1, { min: 0, max: 10, step: 0.1 }), detail: PD.Numeric(0, { min: 0, max: 3, step: 1 }, BaseGeometry.CustomQualityParamInfo), ignoreHydrogens: PD.Boolean(false), - onlyPolarHydrogens: PD.Boolean(false), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), traceOnly: PD.Boolean(false), tryUseImpostor: PD.Boolean(true), }; @@ -42,7 +42,7 @@ export function ElementSphereImpostorVisual(materialId: number): UnitsVisual<Ele setUpdateState: (state: VisualUpdateState, newProps: PD.Values<ElementSphereParams>, currentProps: PD.Values<ElementSphereParams>) => { state.createGeometry = ( newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || newProps.traceOnly !== currentProps.traceOnly ); }, @@ -64,7 +64,7 @@ export function ElementSphereMeshVisual(materialId: number): UnitsVisual<Element newProps.sizeFactor !== currentProps.sizeFactor || newProps.detail !== currentProps.detail || newProps.ignoreHydrogens !== currentProps.ignoreHydrogens || - newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens || + newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant || newProps.traceOnly !== currentProps.traceOnly ); }, diff --git a/src/mol-repr/structure/visual/gaussian-density-volume.ts b/src/mol-repr/structure/visual/gaussian-density-volume.ts index e347f81433bc9acec7f99bc23a1fb2f9a0d7bd93..b4c9ccaaf71b90c0e5150107cdf54a8ff49e69b2 100644 --- a/src/mol-repr/structure/visual/gaussian-density-volume.ts +++ b/src/mol-repr/structure/visual/gaussian-density-volume.ts @@ -43,7 +43,7 @@ export const GaussianDensityVolumeParams = { ...ComplexDirectVolumeParams, ...GaussianDensityParams, ignoreHydrogens: PD.Boolean(false), - onlyPolarHydrogens: PD.Boolean(false), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), includeParent: PD.Boolean(false, { isHidden: true }), }; export type GaussianDensityVolumeParams = typeof GaussianDensityVolumeParams @@ -60,7 +60,7 @@ export function GaussianDensityVolumeVisual(materialId: number): ComplexVisual<G if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true; if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.traceOnly !== currentProps.traceOnly) state.createGeometry = true; if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true; }, @@ -101,7 +101,7 @@ export const UnitsGaussianDensityVolumeParams = { ...UnitsDirectVolumeParams, ...GaussianDensityParams, ignoreHydrogens: PD.Boolean(false), - onlyPolarHydrogens: PD.Boolean(false), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), includeParent: PD.Boolean(false, { isHidden: true }), }; export type UnitsGaussianDensityVolumeParams = typeof UnitsGaussianDensityVolumeParams @@ -118,7 +118,7 @@ export function UnitsGaussianDensityVolumeVisual(materialId: number): UnitsVisua if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true; if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.traceOnly !== currentProps.traceOnly) state.createGeometry = true; if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true; }, diff --git a/src/mol-repr/structure/visual/gaussian-surface-mesh.ts b/src/mol-repr/structure/visual/gaussian-surface-mesh.ts index 06e2116850896ac4603e87c509e2731448396bd2..76249617a9f321174499d93cbe8213396d151f93 100644 --- a/src/mol-repr/structure/visual/gaussian-surface-mesh.ts +++ b/src/mol-repr/structure/visual/gaussian-surface-mesh.ts @@ -34,7 +34,7 @@ const SharedParams = { ...GaussianDensityParams, ...ColorSmoothingParams, ignoreHydrogens: PD.Boolean(false), - onlyPolarHydrogens: PD.Boolean(false), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), tryUseGpu: PD.Boolean(true), includeParent: PD.Boolean(false, { isHidden: true }), }; @@ -128,7 +128,7 @@ export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<Gauss if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true; if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.traceOnly !== currentProps.traceOnly) state.createGeometry = true; if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true; if (newProps.smoothColors.name !== currentProps.smoothColors.name) { @@ -195,7 +195,7 @@ export function StructureGaussianSurfaceMeshVisual(materialId: number): ComplexV if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true; if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.traceOnly !== currentProps.traceOnly) state.createGeometry = true; if (newProps.smoothColors.name !== currentProps.smoothColors.name) { state.updateColor = true; @@ -267,7 +267,7 @@ export function GaussianSurfaceTextureMeshVisual(materialId: number): UnitsVisua if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true; if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.traceOnly !== currentProps.traceOnly) state.createGeometry = true; if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true; if (newProps.smoothColors.name !== currentProps.smoothColors.name) { @@ -343,7 +343,7 @@ export function StructureGaussianSurfaceTextureMeshVisual(materialId: number): C if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true; if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.traceOnly !== currentProps.traceOnly) state.createGeometry = true; if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true; if (newProps.smoothColors.name !== currentProps.smoothColors.name) { diff --git a/src/mol-repr/structure/visual/gaussian-surface-wireframe.ts b/src/mol-repr/structure/visual/gaussian-surface-wireframe.ts index 59eb1bc9cd1f924d947c3a88a868597a3ee361fe..8512cc36279ab7327299ee57f6f986cdd4ba16af 100644 --- a/src/mol-repr/structure/visual/gaussian-surface-wireframe.ts +++ b/src/mol-repr/structure/visual/gaussian-surface-wireframe.ts @@ -41,7 +41,7 @@ export const GaussianWireframeParams = { sizeFactor: PD.Numeric(3, { min: 0, max: 10, step: 0.1 }), lineSizeAttenuation: PD.Boolean(false), ignoreHydrogens: PD.Boolean(false), - onlyPolarHydrogens: PD.Boolean(false), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), includeParent: PD.Boolean(false, { isHidden: true }), }; export type GaussianWireframeParams = typeof GaussianWireframeParams @@ -58,7 +58,7 @@ export function GaussianWireframeVisual(materialId: number): UnitsVisual<Gaussia if (newProps.radiusOffset !== currentProps.radiusOffset) state.createGeometry = true; if (newProps.smoothness !== currentProps.smoothness) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.traceOnly !== currentProps.traceOnly) state.createGeometry = true; if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true; } diff --git a/src/mol-repr/structure/visual/molecular-surface-mesh.ts b/src/mol-repr/structure/visual/molecular-surface-mesh.ts index 5e0608039b102033f7f1754abd0a4c4dd1c77590..bd53471ce766d53103ce93fa8335ecedbae3fdd8 100644 --- a/src/mol-repr/structure/visual/molecular-surface-mesh.ts +++ b/src/mol-repr/structure/visual/molecular-surface-mesh.ts @@ -83,7 +83,7 @@ export function MolecularSurfaceMeshVisual(materialId: number): UnitsVisual<Mole if (newProps.probeRadius !== currentProps.probeRadius) state.createGeometry = true; if (newProps.probePositions !== currentProps.probePositions) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.traceOnly !== currentProps.traceOnly) state.createGeometry = true; if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true; @@ -152,7 +152,7 @@ export function StructureMolecularSurfaceMeshVisual(materialId: number): Complex if (newProps.probeRadius !== currentProps.probeRadius) state.createGeometry = true; if (newProps.probePositions !== currentProps.probePositions) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.traceOnly !== currentProps.traceOnly) state.createGeometry = true; if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true; diff --git a/src/mol-repr/structure/visual/molecular-surface-wireframe.ts b/src/mol-repr/structure/visual/molecular-surface-wireframe.ts index 45b93917a3c66a3aeca9a00e968e0d50c06aa97d..fcb097227d0f9dcc6db2e347f63d83ce232680fe 100644 --- a/src/mol-repr/structure/visual/molecular-surface-wireframe.ts +++ b/src/mol-repr/structure/visual/molecular-surface-wireframe.ts @@ -57,7 +57,7 @@ export function MolecularSurfaceWireframeVisual(materialId: number): UnitsVisual if (newProps.probeRadius !== currentProps.probeRadius) state.createGeometry = true; if (newProps.probePositions !== currentProps.probePositions) state.createGeometry = true; if (newProps.ignoreHydrogens !== currentProps.ignoreHydrogens) state.createGeometry = true; - if (newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens) state.createGeometry = true; + if (newProps.ignoreHydrogensVariant !== currentProps.ignoreHydrogensVariant) state.createGeometry = true; if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true; } }, materialId); diff --git a/src/mol-repr/structure/visual/util/bond.ts b/src/mol-repr/structure/visual/util/bond.ts index 4fc89d01935a742bceaebb76e6c962ff18681ce2..723d17e8bcf2a13efd9a2cb400207e7a2505d28a 100644 --- a/src/mol-repr/structure/visual/util/bond.ts +++ b/src/mol-repr/structure/visual/util/bond.ts @@ -14,14 +14,13 @@ import { ObjectKeys } from '../../../../mol-util/type-helpers'; import { PickingId } from '../../../../mol-geo/geometry/picking'; import { EmptyLoci, Loci } from '../../../../mol-model/loci'; import { Interval, OrderedSet, SortedArray } from '../../../../mol-data/int'; -import { isH, isHydrogen, StructureGroup } from './common'; -import { hasPolarNeighbour } from '../../../../mol-model-props/computed/chemistry/functional-group'; +import { isHydrogen, StructureGroup } from './common'; export const BondParams = { includeTypes: PD.MultiSelect(ObjectKeys(BondType.Names), PD.objectToOptions(BondType.Names)), excludeTypes: PD.MultiSelect([] as BondType.Names[], PD.objectToOptions(BondType.Names)), ignoreHydrogens: PD.Boolean(false), - onlyPolarHydrogens: PD.Boolean(false), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), aromaticBonds: PD.Boolean(true, { description: 'Display aromatic bonds with dashes' }), multipleBonds: PD.Select('symmetric', PD.arrayToOptions(['off', 'symmetric', 'offset'] as const)), }; @@ -49,12 +48,11 @@ export function ignoreBondType(include: BondType.Flag, exclude: BondType.Flag, f export function makeIntraBondIgnoreTest(structure: Structure, unit: Unit.Atomic, props: BondProps): undefined | ((edgeIndex: number) => boolean) { const elements = unit.elements; - const { atomicNumber } = unit.model.atomicHierarchy.derived.atom; const bonds = unit.bonds; const { a, b, edgeProps } = bonds; const { flags: _flags } = edgeProps; - const { ignoreHydrogens, onlyPolarHydrogens, includeTypes, excludeTypes } = props; + const { ignoreHydrogens, ignoreHydrogensVariant, includeTypes, excludeTypes } = props; const include = BondType.fromNames(includeTypes); const exclude = BondType.fromNames(excludeTypes); @@ -64,7 +62,7 @@ export function makeIntraBondIgnoreTest(structure: Structure, unit: Unit.Atomic, const childUnit = child?.unitMap.get(unit.id); if (child && !childUnit) throw new Error('expected childUnit to exist if child exists'); - if (allBondTypes && !onlyPolarHydrogens && !ignoreHydrogens && !child) return; + if (allBondTypes && !ignoreHydrogens && !child) return; return (edgeIndex: number) => { const aI = a[edgeIndex]; @@ -78,15 +76,9 @@ export function makeIntraBondIgnoreTest(structure: Structure, unit: Unit.Atomic, return true; } - if (!ignoreHydrogens && !onlyPolarHydrogens) return false; - if (isH(atomicNumber, elements[aI])) { - if (ignoreHydrogens) return true; - if (onlyPolarHydrogens && !hasPolarNeighbour(structure, unit, aI)) return true; - } - if (isH(atomicNumber, elements[bI])) { - if (ignoreHydrogens) return true; - if (onlyPolarHydrogens && !hasPolarNeighbour(structure, unit, bI)) return true; - } + if (!ignoreHydrogens) return false; + + if (isHydrogen(structure, unit, elements[aI], ignoreHydrogensVariant) || isHydrogen(structure, unit, elements[bI], ignoreHydrogensVariant)) return true; return false; }; @@ -96,7 +88,7 @@ export function makeInterBondIgnoreTest(structure: Structure, props: BondProps): const bonds = structure.interUnitBonds; const { edges } = bonds; - const { ignoreHydrogens, onlyPolarHydrogens, includeTypes, excludeTypes } = props; + const { ignoreHydrogens, ignoreHydrogensVariant, includeTypes, excludeTypes } = props; const include = BondType.fromNames(includeTypes); const exclude = BondType.fromNames(excludeTypes); @@ -104,7 +96,7 @@ export function makeInterBondIgnoreTest(structure: Structure, props: BondProps): const { child } = structure; - if (allBondTypes && !onlyPolarHydrogens && !ignoreHydrogens && !child) return; + if (allBondTypes && !ignoreHydrogens && !child) return; return (edgeIndex: number) => { if (child) { @@ -121,19 +113,7 @@ export function makeInterBondIgnoreTest(structure: Structure, props: BondProps): const b = edges[edgeIndex]; const uA = structure.unitMap.get(b.unitA); const uB = structure.unitMap.get(b.unitB); - if (isHydrogen(uA, uA.elements[b.indexA]) || isHydrogen(uB, uB.elements[b.indexB])) return true; - } - - if (onlyPolarHydrogens) { - const b = edges[edgeIndex]; - const uA = structure.unitMap.get(b.unitA); - if (isHydrogen(uA, uA.elements[b.indexA]) && !hasPolarNeighbour(structure, uA as Unit.Atomic, b.indexA)) { - return true; - } - const uB = structure.unitMap.get(b.unitB); - if (isHydrogen(uB, uB.elements[b.indexB]) && !hasPolarNeighbour(structure, uB as Unit.Atomic, b.indexB)) { - return true; - } + if (isHydrogen(structure, uA, uA.elements[b.indexA], ignoreHydrogensVariant) || isHydrogen(structure, uB, uB.elements[b.indexB], ignoreHydrogensVariant)) return true; } if (!allBondTypes) { diff --git a/src/mol-repr/structure/visual/util/common.ts b/src/mol-repr/structure/visual/util/common.ts index e2e9aa0156e51c1a612d79494d4afbfa46565d00..20dd1da691b7a677d4730c8b04fee82e9737293e 100644 --- a/src/mol-repr/structure/visual/util/common.ts +++ b/src/mol-repr/structure/visual/util/common.ts @@ -141,7 +141,7 @@ export function getConformation(unit: Unit) { export const CommonSurfaceParams = { ignoreHydrogens: PD.Boolean(false, { description: 'Whether or not to include hydrogen atoms in the surface calculation.' }), - onlyPolarHydrogens: PD.Boolean(false, { description: 'Whether or not to include polar hydrogen atoms in the surface calculation.' }), + ignoreHydrogensVariant: PD.Select('all', PD.arrayToOptions(['all', 'non-polar'] as const)), traceOnly: PD.Boolean(false, { description: 'Whether or not to only use trace atoms in the surface calculation.' }), includeParent: PD.Boolean(false, { description: 'Include elements of the parent structure in surface calculation to get a surface patch of the current structure.' }), }; @@ -169,7 +169,7 @@ function filterUnitId(id: AssignableArrayLike<number>, elements: SortedArray, in } export function getUnitConformationAndRadius(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: CommonSurfaceProps) { - const { ignoreHydrogens, onlyPolarHydrogens, traceOnly, includeParent } = props; + const { ignoreHydrogens, ignoreHydrogensVariant, traceOnly, includeParent } = props; const rootUnit = includeParent ? structure.root.unitMap.get(unit.id) : unit; const differentRoot = includeParent && rootUnit !== unit; @@ -182,13 +182,12 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, s let indices: SortedArray<ElementIndex>; let id: AssignableArrayLike<number>; - if (ignoreHydrogens || onlyPolarHydrogens || traceOnly || differentRoot) { + if (ignoreHydrogens || traceOnly || differentRoot) { const _indices: number[] = []; const _id: number[] = []; for (let i = 0, il = elements.length; i < il; ++i) { const eI = elements[i]; - if (ignoreHydrogens && isHydrogen(rootUnit, eI)) continue; - if (onlyPolarHydrogens && isHydrogen(rootUnit, eI) && Unit.isAtomic(rootUnit) && !hasPolarNeighbour(structure, rootUnit, SortedArray.indexOf(rootUnit.elements, eI) as StructureElement.UnitIndex)) continue; + if (ignoreHydrogens && isHydrogen(structure, rootUnit, eI, ignoreHydrogensVariant)) continue; if (traceOnly && !isTrace(rootUnit, eI)) continue; if (differentRoot && squaredDistance(x[eI], y[eI], z[eI], center) > radiusSq) continue; @@ -219,7 +218,7 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, s } export function getStructureConformationAndRadius(structure: Structure, sizeTheme: SizeTheme<any>, props: CommonSurfaceProps) { - const { ignoreHydrogens, onlyPolarHydrogens, traceOnly, includeParent } = props; + const { ignoreHydrogens, ignoreHydrogensVariant, traceOnly, includeParent } = props; const differentRoot = includeParent && !!structure.parent; const l = StructureElement.Location.create(structure.root); @@ -234,7 +233,7 @@ export function getStructureConformationAndRadius(structure: Structure, sizeThem let id: AssignableArrayLike<number>; let indices: OrderedSet<number>; - if (ignoreHydrogens || onlyPolarHydrogens || traceOnly || differentRoot) { + if (ignoreHydrogens || traceOnly || differentRoot) { const { getSerialIndex } = structure.serialMapping; const units = differentRoot ? structure.root.units : structure.units; @@ -252,8 +251,7 @@ export function getStructureConformationAndRadius(structure: Structure, sizeThem l.unit = unit; for (let j = 0, jl = elements.length; j < jl; ++j) { const eI = elements[j]; - if (ignoreHydrogens && isHydrogen(unit, eI)) continue; - if (onlyPolarHydrogens && isHydrogen(unit, eI) && Unit.isAtomic(unit) && !hasPolarNeighbour(structure, unit, SortedArray.indexOf(unit.elements, eI) as StructureElement.UnitIndex)) continue; + if (ignoreHydrogens && isHydrogen(structure, unit, eI, ignoreHydrogensVariant)) continue; if (traceOnly && !isTrace(unit, eI)) continue; const _x = x(eI), _y = y(eI), _z = z(eI); @@ -316,9 +314,12 @@ export function getStructureConformationAndRadius(structure: Structure, sizeThem } const _H = AtomicNumbers['H']; -export function isHydrogen(unit: Unit, element: ElementIndex) { +export function isHydrogen(structure: Structure, unit: Unit, element: ElementIndex, variant: 'all' | 'non-polar') { if (Unit.isCoarse(unit)) return false; - return unit.model.atomicHierarchy.derived.atom.atomicNumber[element] === _H; + return ( + unit.model.atomicHierarchy.derived.atom.atomicNumber[element] === _H && + (variant === 'all' || !hasPolarNeighbour(structure, unit, SortedArray.indexOf(unit.elements, element) as StructureElement.UnitIndex)) + ); } export function isH(atomicNumber: ArrayLike<number>, element: ElementIndex) { return atomicNumber[element] === _H; diff --git a/src/mol-repr/structure/visual/util/element.ts b/src/mol-repr/structure/visual/util/element.ts index a55a776bec0fa596c5cadff9fdd2e30510fe93c8..d19d99f2cb774aa9821946739d354109c81826a6 100644 --- a/src/mol-repr/structure/visual/util/element.ts +++ b/src/mol-repr/structure/visual/util/element.ts @@ -19,16 +19,15 @@ import { VisualContext } from '../../../../mol-repr/visual'; import { Theme } from '../../../../mol-theme/theme'; import { Spheres } from '../../../../mol-geo/geometry/spheres/spheres'; import { SpheresBuilder } from '../../../../mol-geo/geometry/spheres/spheres-builder'; -import { isTrace, isH, StructureGroup } from './common'; +import { isTrace, StructureGroup, isHydrogen } from './common'; import { Sphere3D } from '../../../../mol-math/geometry'; -import { hasPolarNeighbour } from '../../../../mol-model-props/computed/chemistry/functional-group'; // avoiding namespace lookup improved performance in Chrome (Aug 2020) const v3add = Vec3.add; type ElementProps = { ignoreHydrogens: boolean, - onlyPolarHydrogens: boolean, + ignoreHydrogensVariant: 'all' | 'non-polar', traceOnly: boolean, } @@ -38,35 +37,22 @@ export type ElementSphereMeshProps = { } & ElementProps export function makeElementIgnoreTest(structure: Structure, unit: Unit, props: ElementProps): undefined | ((i: ElementIndex) => boolean) { - const { ignoreHydrogens, onlyPolarHydrogens, traceOnly } = props; + const { ignoreHydrogens, ignoreHydrogensVariant, traceOnly } = props; - const { atomicNumber } = unit.model.atomicHierarchy.derived.atom; const isCoarse = Unit.isCoarse(unit); const { child } = structure; const childUnit = child?.unitMap.get(unit.id); if (child && !childUnit) throw new Error('expected childUnit to exist if child exists'); - if (!child && !ignoreHydrogens && !traceOnly && !onlyPolarHydrogens) return; + if (!child && !ignoreHydrogens && !traceOnly) return; return (element: ElementIndex) => { - if (!!childUnit && !SortedArray.has(childUnit.elements, element)) { - return true; - } - - if (traceOnly && !isTrace(unit, element)) { - return true; - } - - if (isCoarse) return false; - - if (!isH(atomicNumber, element)) return false; - if (ignoreHydrogens) return true; - if (onlyPolarHydrogens) { - return !hasPolarNeighbour(structure, unit, SortedArray.indexOf(unit.elements, element) as StructureElement.UnitIndex); - } - - return false; + return ( + (!!childUnit && !SortedArray.has(childUnit.elements, element)) || + (!isCoarse && ignoreHydrogens && isHydrogen(structure, unit, element, ignoreHydrogensVariant)) || + (traceOnly && !isTrace(unit, element)) + ); }; }