Compare commits

..

2 Commits

Author SHA1 Message Date
Alexander Rose
3667092327 tweak cube clamp param 2022-11-08 22:28:47 -08:00
Alexander Rose
842824057b add param to clamp cube values 2022-11-08 22:17:23 -08:00
104 changed files with 1645 additions and 31327 deletions

View File

@@ -6,57 +6,18 @@ Note that since we don't clearly distinguish between a public and private interf
## [Unreleased]
## [v3.27.0] - 2022-12-15
- Add an `includeTransparent` parameter to hide/show outlines of components that are transparent
- Fix 'once' for animations of systems with many frames
- Better guard against issue (black fringes) with bumpiness in impostors
- Improve impostor shaders
- Fix sphere near-clipping with orthographic projection
- Fix cylinder near-clipping
- Add interior cylinder caps
- Add per-pixel object clipping
- Fix `QualityAssessment` assignment bug for structures with different auth vs label sequence numbering
- Refresh `ApplyActionControl`'s param definition when toggling expanded state
- Fix `struct_conn` bond assignment for ions
- Ability to show only polar hydrogens
## [v3.26.0] - 2022-12-04
- Support for ``powerPreference`` webgl attribute. Add ``PluginConfig.General.PowerPreference`` and ``power-preference`` Viewer GET param.
- Excluded common protein caps `NME` and `ACE` from the ligand selection query
- Add screen-space shadow post-processing effect
- Add "Structure Molecular Surface" visual
- Add `external-volume` theme (coloring of arbitrary geometries by user-selected volume)
## [v3.25.1] - 2022-11-20
- Fix edge-case in `Structure.eachUnitPair` with single-element units
- Fix 'auto' structure-quality for coarse models
## [v3.25.0] - 2022-11-16
- Fix handling of gzipped assets (reverts #615)
## [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 (#615)
- 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 `Whole Structure` to `Auto`
- Change EM Volume Streaming default from `Whote 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

File diff suppressed because it is too large Load Diff

2808
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "molstar",
"version": "3.27.0",
"version": "3.23.0",
"description": "A comprehensive macromolecular library.",
"homepage": "https://github.com/molstar/molstar#readme",
"repository": {
@@ -92,59 +92,57 @@
"Panagiotis Tourlas <panagiot_tourlov@hotmail.com>",
"Adam Midlik <midlik@gmail.com>",
"Koya Sakuma <koya.sakuma.work@gmail.com>",
"Gianluca Tomasello <giagitom@gmail.com>",
"Jason Pattle <jpattle@exscientia.co.uk>",
"David Williams <dwilliams@nobiastx.com>"
"Gianluca Tomasello <giagitom@gmail.com>"
],
"license": "MIT",
"devDependencies": {
"@graphql-codegen/add": "^3.2.1",
"@graphql-codegen/cli": "^2.15.0",
"@graphql-codegen/cli": "^2.13.7",
"@graphql-codegen/time": "^3.2.1",
"@graphql-codegen/typescript": "^2.8.3",
"@graphql-codegen/typescript": "^2.7.4",
"@graphql-codegen/typescript-graphql-files-modules": "^2.2.1",
"@graphql-codegen/typescript-graphql-request": "^4.5.8",
"@graphql-codegen/typescript-operations": "^2.5.8",
"@graphql-codegen/typescript-graphql-request": "^4.5.6",
"@graphql-codegen/typescript-operations": "^2.5.4",
"@types/cors": "^2.8.12",
"@types/gl": "^6.0.2",
"@types/jest": "^29.2.3",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"@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",
"benchmark": "^2.1.4",
"concurrently": "^7.6.0",
"concurrently": "^7.4.0",
"cpx2": "^4.2.0",
"crypto-browserify": "^3.12.0",
"css-loader": "^6.7.2",
"eslint": "^8.29.0",
"css-loader": "^6.7.1",
"eslint": "^8.25.0",
"extra-watch-webpack-plugin": "^1.0.3",
"file-loader": "^6.2.0",
"fs-extra": "^11.1.0",
"fs-extra": "^10.1.0",
"graphql": "^16.6.0",
"http-server": "^14.1.1",
"jest": "^29.3.1",
"mini-css-extract-plugin": "^2.7.1",
"jest": "^29.2.0",
"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.56.1",
"sass-loader": "^13.2.0",
"simple-git": "^3.15.1",
"sass": "^1.55.0",
"sass-loader": "^13.1.0",
"simple-git": "^3.14.1",
"stream-browserify": "^3.0.0",
"style-loader": "^3.3.1",
"ts-jest": "^29.0.3",
"typescript": "^4.9.3",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.0"
"typescript": "^4.8.4",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
},
"dependencies": {
"@types/argparse": "^2.0.10",
"@types/benchmark": "^2.1.2",
"@types/compression": "1.7.2",
"@types/express": "^4.17.14",
"@types/node": "^16.18.4",
"@types/node": "^16.11.66",
"@types/node-fetch": "^2.6.2",
"@types/swagger-ui-dist": "3.30.1",
"argparse": "^2.0.1",
@@ -153,12 +151,12 @@
"cors": "^2.8.5",
"express": "^4.18.2",
"h264-mp4-encoder": "^1.0.12",
"immer": "^9.0.16",
"immer": "^9.0.15",
"immutable": "^4.1.0",
"node-fetch": "^2.6.7",
"rxjs": "^7.6.0",
"swagger-ui-dist": "^4.15.5",
"tslib": "^2.4.1",
"rxjs": "^7.5.7",
"swagger-ui-dist": "^4.14.3",
"tslib": "^2.4.0",
"util.promisify": "^1.1.1",
"xhr2": "^0.2.1"
},

View File

@@ -31,8 +31,7 @@ function shinyStyle(plugin: PluginContext) {
postprocessing: {
...plugin.canvas3d!.props.postprocessing,
occlusion: { name: 'off', params: {} },
shadow: { name: 'off', params: {} },
outline: { name: 'off', params: {} },
outline: { name: 'off', params: {} }
}
} });
}
@@ -49,15 +48,13 @@ function occlusionStyle(plugin: PluginContext) {
blurKernelSize: 15,
radius: 5,
samples: 32,
resolutionScale: 1,
resolutionScale: 1
} },
outline: { name: 'on', params: {
scale: 1.0,
threshold: 0.33,
color: Color(0x0000),
includeTransparent: true,
} },
shadow: { name: 'off', params: {} },
} }
}
} });
}

View File

@@ -91,7 +91,6 @@ const DefaultViewerOptions = {
enableDpoit: PluginConfig.General.EnableDpoit.defaultValue,
preferWebgl1: PluginConfig.General.PreferWebGl1.defaultValue,
allowMajorPerformanceCaveat: PluginConfig.General.AllowMajorPerformanceCaveat.defaultValue,
powerPreference: PluginConfig.General.PowerPreference.defaultValue,
viewportShowExpand: PluginConfig.Viewport.ShowExpand.defaultValue,
viewportShowControls: PluginConfig.Viewport.ShowControls.defaultValue,
@@ -164,7 +163,6 @@ export class Viewer {
[PluginConfig.General.EnableDpoit, o.enableDpoit],
[PluginConfig.General.PreferWebGl1, o.preferWebgl1],
[PluginConfig.General.AllowMajorPerformanceCaveat, o.allowMajorPerformanceCaveat],
[PluginConfig.General.PowerPreference, o.powerPreference],
[PluginConfig.Viewport.ShowExpand, o.viewportShowExpand],
[PluginConfig.Viewport.ShowControls, o.viewportShowControls],
[PluginConfig.Viewport.ShowSettings, o.viewportShowSettings],

View File

@@ -63,7 +63,6 @@
var enableDpoit = getParam('enable-dpoit', '[^&]+').trim() === '1';
var preferWebgl1 = getParam('prefer-webgl1', '[^&]+').trim() === '1' || void 0;
var allowMajorPerformanceCaveat = getParam('allow-major-performance-caveat', '[^&]+').trim() === '1';
var powerPreference = getParam('power-preference', '[^&]+').trim().toLowerCase();
molstar.Viewer.create('app', {
layoutShowControls: !hideControls,
@@ -81,7 +80,6 @@
enableDpoit: enableDpoit ? true : void 0,
preferWebgl1: preferWebgl1,
allowMajorPerformanceCaveat: allowMajorPerformanceCaveat,
powerPreference: powerPreference || 'high-performance',
}).then(viewer => {
var snapshotId = getParam('snapshot-id', '[^&]+').trim();
if (snapshotId) viewer.setRemoteSnapshot(snapshotId);

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -25,8 +25,7 @@ const Canvas3DPresets = {
canvas3d: <Preset>{
postprocessing: {
occlusion: { name: 'on', params: { samples: 32, radius: 6, bias: 1.4, blurKernelSize: 15, resolutionScale: 1 } },
outline: { name: 'on', params: { scale: 1, threshold: 0.33, color: Color(0x000000), includeTransparent: true, } },
shadow: { name: 'off', params: {} },
outline: { name: 'on', params: { scale: 1, threshold: 0.33, color: Color(0x000000) } }
},
renderer: {
ambientIntensity: 1.0,
@@ -38,8 +37,7 @@ const Canvas3DPresets = {
canvas3d: <Preset>{
postprocessing: {
occlusion: { name: 'on', params: { samples: 32, radius: 6, bias: 1.4, blurKernelSize: 15, resolutionScale: 1 } },
outline: { name: 'off', params: {} },
shadow: { name: 'off', params: {} },
outline: { name: 'off', params: {} }
},
renderer: {
ambientIntensity: 0.4,
@@ -52,8 +50,7 @@ const Canvas3DPresets = {
canvas3d: <Preset>{
postprocessing: {
occlusion: { name: 'off', params: {} },
outline: { name: 'off', params: {} },
shadow: { name: 'off', params: {} },
outline: { name: 'off', params: {} }
},
renderer: {
ambientIntensity: 0.4,

View File

@@ -585,7 +585,7 @@ export const LoadCellPackModel = StateAction.build({
... ctx.managers.structure.component.state.options,
visualQuality: 'custom',
ignoreLight: true,
hydrogens: 'hide-all',
showHydrogens: false,
});
ctx.canvas3d?.setProps({
multiSample: { mode: 'off' },
@@ -606,22 +606,12 @@ export const LoadCellPackModel = StateAction.build({
resolutionScale: 1,
}
},
shadow: {
name: 'on',
params: {
bias: 0.6,
maxDistance: 80,
steps: 3,
tolerance: 1.0,
}
},
outline: {
name: 'on',
params: {
scale: 1,
threshold: 0.33,
color: ColorNames.black,
includeTransparent: true,
}
}
}

View File

@@ -2,7 +2,6 @@
* Copyright (c) 2021 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>
*/
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
@@ -15,7 +14,6 @@ import { CustomPropSymbol } from '../../../mol-script/language/symbol';
import { Type } from '../../../mol-script/language/type';
import { CustomPropertyDescriptor } from '../../../mol-model/custom-property';
import { MmcifFormat } from '../../../mol-model-formats/structure/mmcif';
import { AtomicIndex } from '../../../mol-model/structure/model/properties/atomic';
export { QualityAssessment };
@@ -73,28 +71,14 @@ namespace QualityAssessment {
localNames.set(ma_qa_metric.id.value(i), name);
}
const residueKey: AtomicIndex.ResidueLabelKey = {
label_entity_id: '',
label_asym_id: '',
label_seq_id: 0,
pdbx_PDB_ins_code: undefined,
};
for (let i = 0, il = ma_qa_metric_local._rowCount; i < il; i++) {
if (model_id.value(i) !== model.modelNum) continue;
const labelAsymId = label_asym_id.value(i);
const entityIndex = index.findEntity(labelAsymId);
residueKey.label_entity_id = model.entities.data.id.value(entityIndex);
residueKey.label_asym_id = labelAsymId;
residueKey.label_seq_id = label_seq_id.value(i);
const rI = index.findResidueLabel(residueKey);
if (rI >= 0) {
const name = localNames.get(metric_id.value(i))!;
localMetrics.get(name)!.set(rI, metric_value.value(i));
}
const rI = index.findResidue(model.entities.data.id.value(entityIndex), labelAsymId, label_seq_id.value(i));
const name = localNames.get(metric_id.value(i))!;
localMetrics.get(name)!.set(rI, metric_value.value(i));
}
return {

View File

@@ -4,7 +4,7 @@ export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
// Generated on 2022-12-03T21:55:37-08:00
// Generated on 2022-08-20T16:36:05-07:00
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
@@ -343,14 +343,6 @@ export type Citation = {
*
*/
readonly journal_abbrev?: Maybe<Scalars['String']>;
/**
* Full name of the cited journal; relevant for journal articles.
*
* Examples:
* Journal of Molecular Biology
*
*/
readonly journal_full?: Maybe<Scalars['String']>;
/**
* The American Society for Testing and Materials (ASTM) code
* assigned to the journal cited (also referred to as the CODEN
@@ -558,7 +550,6 @@ export type CoreBranchedEntityInstance = {
readonly rcsb_id: Scalars['String'];
readonly rcsb_latest_revision?: Maybe<RcsbLatestRevision>;
readonly rcsb_ligand_neighbors?: Maybe<ReadonlyArray<Maybe<RcsbLigandNeighbors>>>;
readonly struct_asym?: Maybe<StructAsym>;
};
export type CoreChemComp = {
@@ -670,7 +661,6 @@ export type CoreEntry = {
readonly exptl?: Maybe<ReadonlyArray<Maybe<Exptl>>>;
readonly exptl_crystal?: Maybe<ReadonlyArray<Maybe<ExptlCrystal>>>;
readonly exptl_crystal_grow?: Maybe<ReadonlyArray<Maybe<ExptlCrystalGrow>>>;
readonly ma_data?: Maybe<ReadonlyArray<Maybe<MaData>>>;
/** Get all non-polymer (non-solvent) entities for this PDB entry. */
readonly nonpolymer_entities?: Maybe<ReadonlyArray<Maybe<CoreNonpolymerEntity>>>;
readonly pdbx_SG_project?: Maybe<ReadonlyArray<Maybe<PdbxSgProject>>>;
@@ -711,7 +701,6 @@ export type CoreEntry = {
/** The list of content types associated with this entry. */
readonly rcsb_associated_holdings?: Maybe<CurrentEntry>;
readonly rcsb_binding_affinity?: Maybe<ReadonlyArray<Maybe<RcsbBindingAffinity>>>;
readonly rcsb_comp_model_provenance?: Maybe<RcsbCompModelProvenance>;
readonly rcsb_entry_container_identifiers: RcsbEntryContainerIdentifiers;
readonly rcsb_entry_group_membership?: Maybe<ReadonlyArray<Maybe<RcsbEntryGroupMembership>>>;
readonly rcsb_entry_info: RcsbEntryInfo;
@@ -724,7 +713,6 @@ export type CoreEntry = {
*
*/
readonly rcsb_id: Scalars['String'];
readonly rcsb_ma_qa_metric_global?: Maybe<ReadonlyArray<Maybe<RcsbMaQaMetricGlobal>>>;
readonly rcsb_primary_citation?: Maybe<RcsbPrimaryCitation>;
readonly refine?: Maybe<ReadonlyArray<Maybe<Refine>>>;
readonly refine_analyze?: Maybe<ReadonlyArray<Maybe<RefineAnalyze>>>;
@@ -798,7 +786,6 @@ export type CoreNonpolymerEntityInstance = {
readonly rcsb_nonpolymer_instance_validation_score?: Maybe<ReadonlyArray<Maybe<RcsbNonpolymerInstanceValidationScore>>>;
readonly rcsb_nonpolymer_struct_conn?: Maybe<ReadonlyArray<Maybe<RcsbNonpolymerStructConn>>>;
readonly rcsb_target_neighbors?: Maybe<ReadonlyArray<Maybe<RcsbTargetNeighbors>>>;
readonly struct_asym?: Maybe<StructAsym>;
};
export type CorePfam = {
@@ -932,7 +919,6 @@ export type CorePolymerEntityInstance = {
readonly rcsb_polymer_instance_feature?: Maybe<ReadonlyArray<Maybe<RcsbPolymerInstanceFeature>>>;
readonly rcsb_polymer_instance_feature_summary?: Maybe<ReadonlyArray<Maybe<RcsbPolymerInstanceFeatureSummary>>>;
readonly rcsb_polymer_struct_conn?: Maybe<ReadonlyArray<Maybe<RcsbPolymerStructConn>>>;
readonly struct_asym?: Maybe<StructAsym>;
};
export type CorePubmed = {
@@ -1298,9 +1284,9 @@ export type Em2dCrystalEntity = {
readonly id: Scalars['String'];
/** pointer to _em_image_processing.id in the EM_IMAGE_PROCESSING category. */
readonly image_processing_id: Scalars['String'];
/** Unit-cell length a in angstroms. */
/** Unit-cell length a in Angstroms. */
readonly length_a?: Maybe<Scalars['Float']>;
/** Unit-cell length b in angstroms. */
/** Unit-cell length b in Angstroms. */
readonly length_b?: Maybe<Scalars['Float']>;
/** Thickness of 2D crystal */
readonly length_c?: Maybe<Scalars['Float']>;
@@ -1331,11 +1317,11 @@ export type Em3dCrystalEntity = {
readonly id: Scalars['String'];
/** pointer to _em_image_processing.id in the EM_IMAGE_PROCESSING category. */
readonly image_processing_id: Scalars['String'];
/** Unit-cell length a in angstroms. */
/** Unit-cell length a in Angstroms. */
readonly length_a?: Maybe<Scalars['Float']>;
/** Unit-cell length b in angstroms. */
/** Unit-cell length b in Angstroms. */
readonly length_b?: Maybe<Scalars['Float']>;
/** Unit-cell length c in angstroms. */
/** Unit-cell length c in Angstroms. */
readonly length_c?: Maybe<Scalars['Float']>;
/**
* Space group name.
@@ -1496,7 +1482,7 @@ export type Em3dReconstruction = {
*/
readonly refinement_type?: Maybe<Scalars['String']>;
/**
* The final resolution (in angstroms)of the 3D reconstruction.
* The final resolution (in Angstroms)of the 3D reconstruction.
*
* Examples:
* null, null
@@ -1572,7 +1558,7 @@ export type EmDiffractionShell = {
*/
readonly fourier_space_coverage?: Maybe<Scalars['Float']>;
/**
* High resolution limit for this shell (angstroms)
* High resolution limit for this shell (Angstroms)
*
* Examples:
* null
@@ -1582,7 +1568,7 @@ export type EmDiffractionShell = {
/** Unique identifier for the category em_diffraction_shell */
readonly id: Scalars['String'];
/**
* Low resolution limit for this shell (angstroms)
* Low resolution limit for this shell (Angstroms)
*
* Examples:
* null
@@ -1628,7 +1614,7 @@ export type EmDiffractionStats = {
*/
readonly fourier_space_coverage?: Maybe<Scalars['Float']>;
/**
* High resolution limit of the structure factor data, in angstroms
* High resolution limit of the structure factor data, in Angstroms
*
* Examples:
* null
@@ -2012,12 +1998,12 @@ export type EmImaging = {
/** The magnification indicated by the microscope readout. */
readonly nominal_magnification?: Maybe<Scalars['Int']>;
/**
* The specimen temperature maximum (kelvin) for the duration
* The specimen temperature maximum (degrees Kelvin) for the duration
* of imaging.
*/
readonly recording_temperature_maximum?: Maybe<Scalars['Float']>;
/**
* The specimen temperature minimum (kelvin) for the duration
* The specimen temperature minimum (degrees Kelvin) for the duration
* of imaging.
*/
readonly recording_temperature_minimum?: Maybe<Scalars['Float']>;
@@ -2042,7 +2028,7 @@ export type EmImaging = {
/** Foreign key to the EM_SPECIMEN category */
readonly specimen_id?: Maybe<Scalars['String']>;
/**
* The mean specimen stage temperature (in kelvin) during imaging
* The mean specimen stage temperature (degrees Kelvin) during imaging
* in the microscope.
*/
readonly temperature?: Maybe<Scalars['Float']>;
@@ -2229,7 +2215,7 @@ export type EmStaining = {
};
export type EmVitrification = {
/** The temperature (in kelvin) of the sample just prior to vitrification. */
/** The temperature (in degrees Kelvin) of the sample just prior to vitrification. */
readonly chamber_temperature?: Maybe<Scalars['Float']>;
/**
* This is the name of the cryogen.
@@ -2273,7 +2259,7 @@ export type EmVitrification = {
/** This data item is a pointer to _em_specimen.id */
readonly specimen_id: Scalars['String'];
/**
* The vitrification temperature (in kelvin), e.g.,
* The vitrification temperature (in degrees Kelvin), e.g.,
* temperature of the plunge instrument cryogen bath.
*/
readonly temp?: Maybe<Scalars['Float']>;
@@ -2378,14 +2364,6 @@ export type EntityPoly = {
*
*/
readonly pdbx_seq_one_letter_code_can?: Maybe<Scalars['String']>;
/**
* Evidence for the assignment of the polymer sequence.
*
* Allowable values:
* depositor provided, derived from coordinates
*
*/
readonly pdbx_sequence_evidence_code?: Maybe<Scalars['String']>;
/**
* The PDB strand/chain id(s) corresponding to this polymer entity.
*
@@ -3027,8 +3005,6 @@ export type Entry = {
* identifier.
*/
readonly id: Scalars['String'];
/** An identifier for the model collection associated with the entry. */
readonly ma_collection_id?: Maybe<Scalars['String']>;
};
export type Exptl = {
@@ -3287,29 +3263,6 @@ export type InterfacePartnerFeatureFeaturePositions = {
readonly values?: Maybe<ReadonlyArray<Maybe<Scalars['Float']>>>;
};
export type MaData = {
/**
* The type of data held in the dataset.
*
* Allowable values:
* coevolution MSA, input structure, model coordinates, other, polymeric template library, spatial restraints, target, target-template alignment, template structure
*
*/
readonly content_type?: Maybe<Scalars['String']>;
/** Details for other content types. */
readonly content_type_other_details?: Maybe<Scalars['String']>;
/** A unique identifier for the data. */
readonly id: Scalars['Int'];
/**
* An author-given name for the content held in the dataset.
*
* Examples:
* NMR NOE Distances, Target Template Alignment, Coevolution Data
*
*/
readonly name?: Maybe<Scalars['String']>;
};
export type MethodDetails = {
/** A description of special aspects of the clustering process */
readonly description?: Maybe<Scalars['String']>;
@@ -4246,7 +4199,7 @@ export type PdbxNmrExptlSampleConditions = {
*/
readonly pressure_units?: Maybe<Scalars['String']>;
/**
* The temperature (in kelvin) at which NMR data were
* The temperature (in Kelvin) at which NMR data were
* collected.
*/
readonly temperature?: Maybe<Scalars['String']>;
@@ -4500,7 +4453,7 @@ export type PdbxPrdAudit = {
* An identifier for the wwPDB site creating or modifying the molecule.
*
* Allowable values:
* BMRB, PDBC, PDBE, PDBJ, RCSB
* BMRB, PDBC, PDBJ, PDBe, RCSB
*
*/
readonly processing_site?: Maybe<Scalars['String']>;
@@ -6864,7 +6817,7 @@ export type Query = {
readonly assemblies?: Maybe<ReadonlyArray<Maybe<CoreAssembly>>>;
/** Get an assembly given the PDB ID and ASSEMBLY ID. Here ASSEMBLY ID is '1', '2', '3', etc. or 'deposited' for deposited coordinates. */
readonly assembly?: Maybe<CoreAssembly>;
/** Get a list of PDB branched entities given a list of ENTITY IDs. Here ENTITY ID is a compound identifier that includes entry_id and entity_id separated by '_', e.g. 1XXX_1. Note that the ENTRY ID part must be upper case. */
/** Get a list of PDB branched entities given a list of ENTITY IDs. Here ENTITY ID is a compound identifier that includes entry_id and entity_id separated by '_', e.g. 1XXX_1. */
readonly branched_entities?: Maybe<ReadonlyArray<Maybe<CoreBranchedEntity>>>;
/** Get a PDB branched entity, given the PDB ID and ENTITY ID. Here ENTITY ID is a '1', '2', '3', etc. */
readonly branched_entity?: Maybe<CoreBranchedEntity>;
@@ -6888,9 +6841,9 @@ export type Query = {
readonly group_provenance?: Maybe<GroupProvenance>;
/** Get a pairwise polymeric interface given the PDB ID, ASSEMBLY ID and INTERFACE ID. */
readonly interface?: Maybe<CoreInterface>;
/** Get a list of pairwise polymeric interfaces given a list of INTERFACE IDs. Here INTERFACE ID is a compound identifier that includes entry_id, assembly_id and interface_id e.g. 1XXX-1.1. Note that the ENTRY ID part must be upper case. */
/** Get a list of pairwise polymeric interfaces given a list of INTERFACE IDs. Here INTERFACE ID is a compound identifier that includes entry_id, assembly_id and interface_id e.g. 1XXX-1.1. */
readonly interfaces?: Maybe<ReadonlyArray<Maybe<CoreInterface>>>;
/** Get a list of PDB non-polymer entities given a list of ENTITY IDs. Here ENTITY ID is a compound identifier that includes entry_id and entity_id separated by '_', e.g. 1XXX_1. Note that the ENTRY ID part must be upper case. */
/** Get a list of PDB non-polymer entities given a list of ENTITY IDs. Here ENTITY ID is a compound identifier that includes entry_id and entity_id separated by '_', e.g. 1XXX_1. */
readonly nonpolymer_entities?: Maybe<ReadonlyArray<Maybe<CoreNonpolymerEntity>>>;
/** Get a PDB non-polymer entity, given the PDB ID and ENTITY ID. Here ENTITY ID is a '1', '2', '3', etc. */
readonly nonpolymer_entity?: Maybe<CoreNonpolymerEntity>;
@@ -6898,7 +6851,7 @@ export type Query = {
readonly nonpolymer_entity_instance?: Maybe<CoreNonpolymerEntityInstance>;
/** Get a list of PDB non-polymer entity instances (chains), given the list of ENTITY INSTANCE IDs. Here ENTITY INSTANCE ID identifies structural element in the asymmetric unit, e.g. 'A', 'B', etc. */
readonly nonpolymer_entity_instances?: Maybe<ReadonlyArray<Maybe<CoreNonpolymerEntityInstance>>>;
/** Get a list of PDB polymer entities given a list of ENTITY IDs. Here ENTITY ID is a compound identifier that includes entry_id and entity_id separated by '_', e.g. 1XXX_1. Note that the ENTRY ID part must be upper case. */
/** Get a list of PDB polymer entities given a list of ENTITY IDs. Here ENTITY ID is a compound identifier that includes entry_id and entity_id separated by '_', e.g. 1XXX_1. */
readonly polymer_entities?: Maybe<ReadonlyArray<Maybe<CorePolymerEntity>>>;
/** Get a PDB polymer entity, given the PDB ID and ENTITY ID. Here ENTITY ID is a '1', '2', '3', etc. */
readonly polymer_entity?: Maybe<CorePolymerEntity>;
@@ -8468,29 +8421,6 @@ export type RcsbClusterMembership = {
readonly identity?: Maybe<Scalars['Int']>;
};
export type RcsbCompModelProvenance = {
/**
* Entry identifier corresponding to the computed structure model.
*
* Examples:
* AF-P60325-F1, ma-bak-cepc-0019
*
*/
readonly entry_id: Scalars['String'];
/**
* Source database for the computed structure model.
*
* Allowable values:
* AlphaFoldDB, ModelArchive
*
*/
readonly source_db?: Maybe<Scalars['String']>;
/** Source filename for the computed structure model. */
readonly source_filename?: Maybe<Scalars['String']>;
/** Source URL for computed structure model file. */
readonly source_url?: Maybe<Scalars['String']>;
};
export type RcsbEntityHostOrganism = {
/**
* The beginning polymer sequence position for the polymer section corresponding
@@ -8727,7 +8657,7 @@ export type RcsbEntitySourceOrganism = {
* A code indicating the provenance of the source organism details for the entity
*
* Allowable values:
* PDB Primary Data, UniProt
* PDB Primary Data
*
*/
readonly provenance_source?: Maybe<Scalars['String']>;
@@ -8801,7 +8731,7 @@ export type RcsbEntryContainerIdentifiers = {
* Entry identifier for the container.
*
* Examples:
* 4HHB, AF_AFP60325F1, MA_MABAKCEPC0019
* 1KIP, 4HHB
*
*/
readonly entry_id: Scalars['String'];
@@ -8949,15 +8879,6 @@ export type RcsbEntryInfo = {
*
*/
readonly na_polymer_entity_types?: Maybe<Scalars['String']>;
/**
* This data item identifies secondary structure
* features of nucleic acids in the entry.
*
* Allowable values:
* a-form double helix, b-form double helix, bulge loop, double helix, four-way junction, hairpin loop, internal loop, mismatched base pair, other right-handed double helix, parallel strands, quadruple helix, tetraloop, three-way junction, triple helix, two-way junction, z-form double helix
*
*/
readonly ndb_struct_conf_na_feature_combined?: Maybe<ReadonlyArray<Maybe<Scalars['String']>>>;
/** Bound nonpolymer components in this entry. */
readonly nonpolymer_bound_components?: Maybe<ReadonlyArray<Maybe<Scalars['String']>>>;
/** The number of distinct non-polymer entities in the structure entry exclusive of solvent. */
@@ -9034,21 +8955,6 @@ export type RcsbEntryInfo = {
readonly software_programs_combined?: Maybe<ReadonlyArray<Maybe<Scalars['String']>>>;
/** The number of distinct solvent entities per deposited structure model. */
readonly solvent_entity_count?: Maybe<Scalars['Int']>;
/**
* Indicates if the structure was determined using experimental or computational methods.
*
* Allowable values:
* computational, experimental
*
*/
readonly structure_determination_methodology: Scalars['String'];
/**
* Indicates the priority of the value in _rcsb_entry_info.structure_determination_methodology.
* The lower the number the higher the priority.
* Priority values for "experimental" structures is currently set to 10 and
* the values for "computational" structures is set to 100.
*/
readonly structure_determination_methodology_priority?: Maybe<Scalars['Int']>;
};
export type RcsbEntryInfoDiffrnResolutionHigh = {
@@ -9388,49 +9294,6 @@ export type RcsbLigandNeighbors = {
readonly seq_id?: Maybe<Scalars['Int']>;
};
export type RcsbMaQaMetricGlobal = {
readonly ma_qa_metric_global?: Maybe<ReadonlyArray<Maybe<RcsbMaQaMetricGlobalMaQaMetricGlobal>>>;
/** The model identifier. */
readonly model_id: Scalars['Int'];
};
export type RcsbMaQaMetricGlobalMaQaMetricGlobal = {
/**
* Description of the global QA metric.
*
* Examples:
* confidence score predicting accuracy according to the CA-only Local Distance Difference Test (lDDT-CA) in [0,100]
*
*/
readonly description?: Maybe<Scalars['String']>;
/**
* Name of the global QA metric.
*
* Examples:
* pLDDT
*
*/
readonly name: Scalars['String'];
/**
* The type of global QA metric.
*
* Allowable values:
* PAE, contact probability, distance, energy, ipTM, normalized score, other, pLDDT, pLDDT all-atom, pLDDT all-atom in [0,1], pLDDT in [0,1], pTM, zscore
*
*/
readonly type: Scalars['String'];
/** Details for other type of global QA metric. */
readonly type_other_details?: Maybe<Scalars['String']>;
/**
* Value of the global QA metric.
*
* Examples:
* null
*
*/
readonly value: Scalars['Float'];
};
export type RcsbMembraneLineage = {
/** Hierarchy depth. */
readonly depth?: Maybe<Scalars['Int']>;
@@ -10469,7 +10332,7 @@ export type RcsbPolymerEntityContainerIdentifiersReferenceSequenceIdentifiers =
* Source of the reference database assignment
*
* Allowable values:
* PDB, RCSB, SIFTS, UniProt
* PDB, RCSB, SIFTS
*
*/
readonly provenance_source?: Maybe<Scalars['String']>;
@@ -10874,7 +10737,7 @@ export type RcsbPolymerInstanceFeature = {
* A type or category of the feature.
*
* Allowable values:
* ANGLE_OUTLIER, BEND, BINDING_SITE, BOND_OUTLIER, C-MANNOSYLATION_SITE, CATH, CIS-PEPTIDE, ECOD, HELIX_P, HELX_LH_PP_P, HELX_RH_3T_P, HELX_RH_AL_P, HELX_RH_PI_P, MA_QA_METRIC_LOCAL_TYPE_CONTACT_PROBABILITY, MA_QA_METRIC_LOCAL_TYPE_DISTANCE, MA_QA_METRIC_LOCAL_TYPE_ENERGY, MA_QA_METRIC_LOCAL_TYPE_IPTM, MA_QA_METRIC_LOCAL_TYPE_NORMALIZED_SCORE, MA_QA_METRIC_LOCAL_TYPE_OTHER, MA_QA_METRIC_LOCAL_TYPE_PAE, MA_QA_METRIC_LOCAL_TYPE_PLDDT, MA_QA_METRIC_LOCAL_TYPE_PLDDT_ALL-ATOM, MA_QA_METRIC_LOCAL_TYPE_PLDDT_ALL-ATOM_[0,1], MA_QA_METRIC_LOCAL_TYPE_PLDDT_[0,1], MA_QA_METRIC_LOCAL_TYPE_PTM, MA_QA_METRIC_LOCAL_TYPE_ZSCORE, MEMBRANE_SEGMENT, MOGUL_ANGLE_OUTLIER, MOGUL_BOND_OUTLIER, N-GLYCOSYLATION_SITE, O-GLYCOSYLATION_SITE, RAMACHANDRAN_OUTLIER, ROTAMER_OUTLIER, RSCC_OUTLIER, RSRZ_OUTLIER, S-GLYCOSYLATION_SITE, SABDAB_ANTIBODY_HEAVY_CHAIN_SUBCLASS, SABDAB_ANTIBODY_LIGHT_CHAIN_SUBCLASS, SABDAB_ANTIBODY_LIGHT_CHAIN_TYPE, SCOP, SCOP2B_SUPERFAMILY, SCOP2_FAMILY, SCOP2_SUPERFAMILY, SHEET, STEREO_OUTLIER, STRN, TURN_TY1_P, UNASSIGNED_SEC_STRUCT, UNOBSERVED_ATOM_XYZ, UNOBSERVED_RESIDUE_XYZ, ZERO_OCCUPANCY_ATOM_XYZ, ZERO_OCCUPANCY_RESIDUE_XYZ, ASA
* ANGLE_OUTLIER, BINDING_SITE, BOND_OUTLIER, C-MANNOSYLATION_SITE, CATH, CIS-PEPTIDE, ECOD, HELIX_P, MEMBRANE_SEGMENT, MOGUL_ANGLE_OUTLIER, MOGUL_BOND_OUTLIER, N-GLYCOSYLATION_SITE, O-GLYCOSYLATION_SITE, RAMACHANDRAN_OUTLIER, ROTAMER_OUTLIER, RSCC_OUTLIER, RSRZ_OUTLIER, S-GLYCOSYLATION_SITE, SABDAB_ANTIBODY_HEAVY_CHAIN_SUBCLASS, SABDAB_ANTIBODY_LIGHT_CHAIN_SUBCLASS, SABDAB_ANTIBODY_LIGHT_CHAIN_TYPE, SCOP, SCOP2B_SUPERFAMILY, SCOP2_FAMILY, SCOP2_SUPERFAMILY, SHEET, STEREO_OUTLIER, UNASSIGNED_SEC_STRUCT, UNOBSERVED_ATOM_XYZ, UNOBSERVED_RESIDUE_XYZ, ZERO_OCCUPANCY_ATOM_XYZ, ZERO_OCCUPANCY_RESIDUE_XYZ, ASA
*
*/
readonly type?: Maybe<Scalars['String']>;
@@ -10885,7 +10748,7 @@ export type RcsbPolymerInstanceFeatureAdditionalProperties = {
* The additional property name.
*
* Allowable values:
* CATH_DOMAIN_ID, CATH_NAME, ECOD_DOMAIN_ID, ECOD_FAMILY_NAME, MODELCIF_MODEL_ID, OMEGA_ANGLE, PARTNER_ASYM_ID, PARTNER_BOND_DISTANCE, PARTNER_COMP_ID, SCOP2_DOMAIN_ID, SCOP2_FAMILY_ID, SCOP2_FAMILY_NAME, SCOP2_SUPERFAMILY_ID, SCOP2_SUPERFAMILY_NAME, SCOP_DOMAIN_ID, SCOP_NAME, SCOP_SUN_ID, SHEET_SENSE
* CATH_DOMAIN_ID, CATH_NAME, ECOD_DOMAIN_ID, ECOD_FAMILY_NAME, OMEGA_ANGLE, PARTNER_ASYM_ID, PARTNER_BOND_DISTANCE, PARTNER_COMP_ID, SCOP2_DOMAIN_ID, SCOP2_FAMILY_ID, SCOP2_FAMILY_NAME, SCOP2_SUPERFAMILY_ID, SCOP2_SUPERFAMILY_NAME, SCOP_DOMAIN_ID, SCOP_NAME, SCOP_SUN_ID, SHEET_SENSE
*
*/
readonly name?: Maybe<Scalars['String']>;
@@ -10955,7 +10818,7 @@ export type RcsbPolymerInstanceFeatureSummary = {
* Type or category of the feature.
*
* Allowable values:
* ANGLE_OUTLIER, BEND, BINDING_SITE, BOND_OUTLIER, C-MANNOSYLATION_SITE, CATH, CIS-PEPTIDE, ECOD, HELIX_P, HELX_LH_PP_P, HELX_RH_3T_P, HELX_RH_AL_P, HELX_RH_PI_P, MA_QA_METRIC_LOCAL_TYPE_CONTACT_PROBABILITY, MA_QA_METRIC_LOCAL_TYPE_DISTANCE, MA_QA_METRIC_LOCAL_TYPE_ENERGY, MA_QA_METRIC_LOCAL_TYPE_IPTM, MA_QA_METRIC_LOCAL_TYPE_NORMALIZED_SCORE, MA_QA_METRIC_LOCAL_TYPE_OTHER, MA_QA_METRIC_LOCAL_TYPE_PAE, MA_QA_METRIC_LOCAL_TYPE_PLDDT, MA_QA_METRIC_LOCAL_TYPE_PLDDT_ALL-ATOM, MA_QA_METRIC_LOCAL_TYPE_PLDDT_ALL-ATOM_[0,1], MA_QA_METRIC_LOCAL_TYPE_PLDDT_[0,1], MA_QA_METRIC_LOCAL_TYPE_PTM, MA_QA_METRIC_LOCAL_TYPE_ZSCORE, MEMBRANE_SEGMENT, MOGUL_ANGLE_OUTLIER, MOGUL_BOND_OUTLIER, N-GLYCOSYLATION_SITE, O-GLYCOSYLATION_SITE, RAMACHANDRAN_OUTLIER, ROTAMER_OUTLIER, RSCC_OUTLIER, RSRZ_OUTLIER, S-GLYCOSYLATION_SITE, SABDAB_ANTIBODY_HEAVY_CHAIN_SUBCLASS, SABDAB_ANTIBODY_LIGHT_CHAIN_SUBCLASS, SABDAB_ANTIBODY_LIGHT_CHAIN_TYPE, SCOP, SCOP2B_SUPERFAMILY, SCOP2_FAMILY, SCOP2_SUPERFAMILY, SHEET, STEREO_OUTLIER, STRN, TURN_TY1_P, UNASSIGNED_SEC_STRUCT, UNOBSERVED_ATOM_XYZ, UNOBSERVED_RESIDUE_XYZ, ZERO_OCCUPANCY_ATOM_XYZ, ZERO_OCCUPANCY_RESIDUE_XYZ
* ANGLE_OUTLIER, BINDING_SITE, BOND_OUTLIER, C-MANNOSYLATION_SITE, CATH, CIS-PEPTIDE, ECOD, HELIX_P, MEMBRANE_SEGMENT, MOGUL_ANGLE_OUTLIER, MOGUL_BOND_OUTLIER, N-GLYCOSYLATION_SITE, O-GLYCOSYLATION_SITE, RAMACHANDRAN_OUTLIER, ROTAMER_OUTLIER, RSCC_OUTLIER, RSRZ_OUTLIER, S-GLYCOSYLATION_SITE, SABDAB_ANTIBODY_HEAVY_CHAIN_SUBCLASS, SABDAB_ANTIBODY_LIGHT_CHAIN_SUBCLASS, SABDAB_ANTIBODY_LIGHT_CHAIN_TYPE, SAbDab Antibody Heavy Chain Subclass, SAbDab Antibody Light Chain Subclass, SAbDab Antibody Light Chain Type, SCOP, SCOP2 Family, SCOP2 Superfamily, SCOP2B Superfamily, SCOP2B_SUPERFAMILY, SCOP2_FAMILY, SCOP2_SUPERFAMILY, SHEET, STEREO_OUTLIER, UNASSIGNED_SEC_STRUCT, UNOBSERVED_ATOM_XYZ, UNOBSERVED_RESIDUE_XYZ, ZERO_OCCUPANCY_ATOM_XYZ, ZERO_OCCUPANCY_RESIDUE_XYZ
*
*/
readonly type?: Maybe<Scalars['String']>;
@@ -13514,11 +13377,6 @@ export type ReflnsShell = {
};
export type Software = {
/**
* This data item is a pointer to _citation.id in the CITATION
* category.
*/
readonly citation_id?: Maybe<Scalars['String']>;
/**
* The classification of the program according to its
* major function.
@@ -13669,37 +13527,6 @@ export type Struct = {
readonly title?: Maybe<Scalars['String']>;
};
export type StructAsym = {
/**
* This data item is a pointer to _atom_site.pdbx_PDB_strand_id the
* ATOM_SITE category.
*
* Examples:
* 1ABC
*
*/
readonly pdbx_PDB_id?: Maybe<Scalars['String']>;
/**
* This data item is a pointer to _atom_site.ndb_alias_strand_id the
* ATOM_SITE category.
*/
readonly pdbx_alt_id?: Maybe<Scalars['String']>;
/**
* This data item gives the order of the structural elements in the
* ATOM_SITE category.
*/
readonly pdbx_order?: Maybe<Scalars['Int']>;
/**
* This data item describes the general type of the structural elements
* in the ATOM_SITE category.
*
* Allowable values:
* ATOMN, ATOMP, ATOMS, HETAC, HETAD, HETAI, HETAIN, HETAS, HETIC
*
*/
readonly pdbx_type?: Maybe<Scalars['String']>;
};
export type StructKeywords = {
/**
* Terms characterizing the macromolecular structure.

View File

@@ -120,7 +120,6 @@ interface Canvas3DContext {
namespace Canvas3DContext {
export const DefaultAttribs = {
powerPreference: 'high-performance' as WebGLContextAttributes['powerPreference'],
failIfMajorPerformanceCaveat: false,
/** true by default to avoid issues with Safari (Jan 2021) */
antialias: true,
@@ -141,9 +140,8 @@ namespace Canvas3DContext {
if (a.enableWboit && a.enableDpoit) throw new Error('Multiple transparency methods not allowed.');
const { powerPreference, failIfMajorPerformanceCaveat, antialias, preserveDrawingBuffer, pixelScale, preferWebGl1 } = a;
const { failIfMajorPerformanceCaveat, antialias, preserveDrawingBuffer, pixelScale, preferWebGl1 } = a;
const gl = getGLContext(canvas, {
powerPreference,
failIfMajorPerformanceCaveat,
antialias,
preserveDrawingBuffer,

View File

@@ -142,7 +142,7 @@ export class DrawPass {
}
if (PostprocessingPass.isEnabled(postprocessingProps)) {
if (PostprocessingPass.isTransparentOutlineEnabled(postprocessingProps)) {
if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
this.depthTargetTransparent.bind();
renderer.clearDepth(true);
if (scene.opacityAverage < 1) {
@@ -150,7 +150,7 @@ export class DrawPass {
}
}
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps, renderer.light);
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps);
}
this.depthTextureOpaque.detachFramebuffer(this.colorTarget.framebuffer, 'depth');
@@ -196,7 +196,7 @@ export class DrawPass {
}
if (PostprocessingPass.isEnabled(postprocessingProps)) {
if (PostprocessingPass.isTransparentOutlineEnabled(postprocessingProps)) {
if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
this.depthTargetTransparent.bind();
renderer.clearDepth(true);
if (scene.opacityAverage < 1) {
@@ -204,7 +204,7 @@ export class DrawPass {
}
}
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps, renderer.light);
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps);
}
// render transparent primitives and volumes
@@ -260,7 +260,7 @@ export class DrawPass {
this.colorTarget.depthRenderbuffer?.detachFramebuffer(this.postprocessing.target.framebuffer);
}
if (PostprocessingPass.isTransparentOutlineEnabled(postprocessingProps)) {
if (PostprocessingPass.isOutlineEnabled(postprocessingProps)) {
this.depthTargetTransparent.bind();
renderer.clearDepth(true);
if (scene.opacityAverage < 1) {
@@ -268,7 +268,7 @@ export class DrawPass {
}
}
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps, renderer.light);
this.postprocessing.render(camera, false, transparentBackground, renderer.props.backgroundColor, postprocessingProps);
if (!this.packedDepth) {
this.depthTextureOpaque.attachFramebuffer(this.postprocessing.target.framebuffer, 'depth');

View File

@@ -3,7 +3,6 @@
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Áron Samuel Kovács <aron.kovacs@mail.muni.cz>
* @author Ludovic Autin <ludovic.autin@gmail.com>
*/
import { CopyRenderable, createCopyRenderable, QuadSchema, QuadValues } from '../../mol-gl/compute/util';
@@ -31,8 +30,6 @@ import { SmaaParams, SmaaPass } from './smaa';
import { isTimingMode } from '../../mol-util/debug';
import { BackgroundParams, BackgroundPass } from './background';
import { AssetManager } from '../../mol-util/assets';
import { Light } from '../../mol-gl/renderer';
import { shadows_frag } from '../../mol-gl/shader/shadows.frag';
const OutlinesSchema = {
...QuadSchema,
@@ -45,12 +42,10 @@ const OutlinesSchema = {
uFar: UniformSpec('f'),
uMaxPossibleViewZDiff: UniformSpec('f'),
dTransparentOutline: DefineSpec('boolean'),
};
type OutlinesRenderable = ComputeRenderable<Values<typeof OutlinesSchema>>
function getOutlinesRenderable(ctx: WebGLContext, depthTextureOpaque: Texture, depthTextureTransparent: Texture, transparentOutline: boolean): OutlinesRenderable {
function getOutlinesRenderable(ctx: WebGLContext, depthTextureOpaque: Texture, depthTextureTransparent: Texture): OutlinesRenderable {
const width = depthTextureOpaque.getWidth();
const height = depthTextureOpaque.getHeight();
@@ -65,8 +60,6 @@ function getOutlinesRenderable(ctx: WebGLContext, depthTextureOpaque: Texture, d
uFar: ValueCell.create(10000),
uMaxPossibleViewZDiff: ValueCell.create(0.5),
dTransparentOutline: ValueCell.create(transparentOutline),
};
const schema = { ...OutlinesSchema };
@@ -76,64 +69,6 @@ function getOutlinesRenderable(ctx: WebGLContext, depthTextureOpaque: Texture, d
return createComputeRenderable(renderItem, values);
}
const ShadowsSchema = {
...QuadSchema,
tDepth: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'),
uTexSize: UniformSpec('v2'),
uProjection: UniformSpec('m4'),
uInvProjection: UniformSpec('m4'),
uBounds: UniformSpec('v4'),
dOrthographic: DefineSpec('number'),
uNear: UniformSpec('f'),
uFar: UniformSpec('f'),
dSteps: DefineSpec('number'),
uMaxDistance: UniformSpec('f'),
uTolerance: UniformSpec('f'),
uBias: UniformSpec('f'),
uLightDirection: UniformSpec('v3[]'),
uLightColor: UniformSpec('v3[]'),
dLightCount: DefineSpec('number'),
};
type ShadowsRenderable = ComputeRenderable<Values<typeof ShadowsSchema>>
function getShadowsRenderable(ctx: WebGLContext, depthTexture: Texture): ShadowsRenderable {
const width = depthTexture.getWidth();
const height = depthTexture.getHeight();
const values: Values<typeof ShadowsSchema> = {
...QuadValues,
tDepth: ValueCell.create(depthTexture),
uTexSize: ValueCell.create(Vec2.create(width, height)),
uProjection: ValueCell.create(Mat4.identity()),
uInvProjection: ValueCell.create(Mat4.identity()),
uBounds: ValueCell.create(Vec4()),
dOrthographic: ValueCell.create(0),
uNear: ValueCell.create(1),
uFar: ValueCell.create(10000),
dSteps: ValueCell.create(1),
uMaxDistance: ValueCell.create(3.0),
uTolerance: ValueCell.create(1.0),
uBias: ValueCell.create(0.6),
uLightDirection: ValueCell.create([]),
uLightColor: ValueCell.create([]),
dLightCount: ValueCell.create(0),
};
const schema = { ...ShadowsSchema };
const shaderCode = ShaderCode('shadows', quad_vert, shadows_frag);
const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values);
return createComputeRenderable(renderItem, values);
}
const SsaoSchema = {
...QuadSchema,
tDepth: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'),
@@ -269,7 +204,6 @@ const PostprocessingSchema = {
tColor: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'),
tDepthOpaque: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'),
tDepthTransparent: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'),
tShadows: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'),
tOutlines: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'),
uTexSize: UniformSpec('v2'),
@@ -287,25 +221,19 @@ const PostprocessingSchema = {
dOcclusionEnable: DefineSpec('boolean'),
uOcclusionOffset: UniformSpec('v2'),
dShadowEnable: DefineSpec('boolean'),
dOutlineEnable: DefineSpec('boolean'),
dOutlineScale: DefineSpec('number'),
uOutlineThreshold: UniformSpec('f'),
dTransparentOutline: DefineSpec('boolean'),
};
type PostprocessingRenderable = ComputeRenderable<Values<typeof PostprocessingSchema>>
function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, depthTextureOpaque: Texture, depthTextureTransparent: Texture, shadowsTexture: Texture, outlinesTexture: Texture, ssaoDepthTexture: Texture, transparentOutline: boolean): PostprocessingRenderable {
function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, depthTextureOpaque: Texture, depthTextureTransparent: Texture, outlinesTexture: Texture, ssaoDepthTexture: Texture): PostprocessingRenderable {
const values: Values<typeof PostprocessingSchema> = {
...QuadValues,
tSsaoDepth: ValueCell.create(ssaoDepthTexture),
tColor: ValueCell.create(colorTexture),
tDepthOpaque: ValueCell.create(depthTextureOpaque),
tDepthTransparent: ValueCell.create(depthTextureTransparent),
tShadows: ValueCell.create(shadowsTexture),
tOutlines: ValueCell.create(outlinesTexture),
uTexSize: ValueCell.create(Vec2.create(colorTexture.getWidth(), colorTexture.getHeight())),
@@ -323,13 +251,9 @@ function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, d
dOcclusionEnable: ValueCell.create(true),
uOcclusionOffset: ValueCell.create(Vec2.create(0, 0)),
dShadowEnable: ValueCell.create(false),
dOutlineEnable: ValueCell.create(false),
dOutlineScale: ValueCell.create(1),
uOutlineThreshold: ValueCell.create(0.33),
dTransparentOutline: ValueCell.create(transparentOutline),
};
const schema = { ...PostprocessingSchema };
@@ -350,21 +274,11 @@ export const PostprocessingParams = {
}),
off: PD.Group({})
}, { cycle: true, description: 'Darken occluded crevices with the ambient occlusion effect' }),
shadow: PD.MappedStatic('off', {
on: PD.Group({
steps: PD.Numeric(1, { min: 1, max: 64, step: 1 }),
bias: PD.Numeric(0.6, { min: 0.0, max: 1.0, step: 0.01 }),
maxDistance: PD.Numeric(3, { min: 0, max: 256, step: 1 }),
tolerance: PD.Numeric(1.0, { min: 0.0, max: 10.0, step: 0.1 }),
}),
off: PD.Group({})
}, { cycle: true, description: 'Simplistic shadows' }),
outline: PD.MappedStatic('off', {
on: PD.Group({
scale: PD.Numeric(1, { min: 1, max: 5, step: 1 }),
threshold: PD.Numeric(0.33, { min: 0.01, max: 1, step: 0.01 }),
color: PD.Color(Color(0x000000)),
includeTransparent: PD.Boolean(true, { description: 'Whether to show outline for transparent objects' }),
}),
off: PD.Group({})
}, { cycle: true, description: 'Draw outline around 3D objects' }),
@@ -375,16 +289,15 @@ export const PostprocessingParams = {
}, { options: [['fxaa', 'FXAA'], ['smaa', 'SMAA'], ['off', 'Off']], description: 'Smooth pixel edges' }),
background: PD.Group(BackgroundParams, { isFlat: true }),
};
export type PostprocessingProps = PD.Values<typeof PostprocessingParams>
export class PostprocessingPass {
static isEnabled(props: PostprocessingProps) {
return props.occlusion.name === 'on' || props.shadow.name === 'on' || props.outline.name === 'on' || props.background.variant.name !== 'off';
return props.occlusion.name === 'on' || props.outline.name === 'on' || props.background.variant.name !== 'off';
}
static isTransparentOutlineEnabled(props: PostprocessingProps) {
return props.outline.name === 'on' && props.outline.params.includeTransparent;
static isOutlineEnabled(props: PostprocessingProps) {
return props.outline.name === 'on';
}
readonly target: RenderTarget;
@@ -392,9 +305,6 @@ export class PostprocessingPass {
private readonly outlinesTarget: RenderTarget;
private readonly outlinesRenderable: OutlinesRenderable;
private readonly shadowsTarget: RenderTarget;
private readonly shadowsRenderable: ShadowsRenderable;
private readonly ssaoFramebuffer: Framebuffer;
private readonly ssaoBlurFirstPassFramebuffer: Framebuffer;
private readonly ssaoBlurSecondPassFramebuffer: Framebuffer;
@@ -438,10 +348,7 @@ export class PostprocessingPass {
this.target = webgl.createRenderTarget(width, height, false, 'uint8', 'linear');
this.outlinesTarget = webgl.createRenderTarget(width, height, false);
this.outlinesRenderable = getOutlinesRenderable(webgl, depthTextureOpaque, depthTextureTransparent, true);
this.shadowsTarget = webgl.createRenderTarget(width, height, false);
this.shadowsRenderable = getShadowsRenderable(webgl, depthTextureOpaque);
this.outlinesRenderable = getOutlinesRenderable(webgl, depthTextureOpaque, depthTextureTransparent);
this.ssaoFramebuffer = webgl.resources.framebuffer();
this.ssaoBlurFirstPassFramebuffer = webgl.resources.framebuffer();
@@ -466,7 +373,7 @@ export class PostprocessingPass {
this.ssaoRenderable = getSsaoRenderable(webgl, this.downsampleFactor === 1 ? depthTextureOpaque : this.downsampledDepthTarget.texture);
this.ssaoBlurFirstPassRenderable = getSsaoBlurRenderable(webgl, this.ssaoDepthTexture, 'horizontal');
this.ssaoBlurSecondPassRenderable = getSsaoBlurRenderable(webgl, this.ssaoDepthBlurProxyTexture, 'vertical');
this.renderable = getPostprocessingRenderable(webgl, colorTarget.texture, depthTextureOpaque, depthTextureTransparent, this.shadowsTarget.texture, this.outlinesTarget.texture, this.ssaoDepthTexture, true);
this.renderable = getPostprocessingRenderable(webgl, colorTarget.texture, depthTextureOpaque, depthTextureTransparent, this.outlinesTarget.texture, this.ssaoDepthTexture);
this.background = new BackgroundPass(webgl, assetManager, width, height);
}
@@ -482,14 +389,12 @@ export class PostprocessingPass {
const sh = Math.floor(height * this.ssaoScale);
this.target.setSize(width, height);
this.outlinesTarget.setSize(width, height);
this.shadowsTarget.setSize(width, height);
this.downsampledDepthTarget.setSize(sw, sh);
this.ssaoDepthTexture.define(sw, sh);
this.ssaoDepthBlurProxyTexture.define(sw, sh);
ValueCell.update(this.renderable.values.uTexSize, Vec2.set(this.renderable.values.uTexSize.ref.value, width, height));
ValueCell.update(this.outlinesRenderable.values.uTexSize, Vec2.set(this.outlinesRenderable.values.uTexSize.ref.value, width, height));
ValueCell.update(this.shadowsRenderable.values.uTexSize, Vec2.set(this.shadowsRenderable.values.uTexSize.ref.value, width, height));
ValueCell.update(this.downsampleDepthRenderable.values.uTexSize, Vec2.set(this.downsampleDepthRenderable.values.uTexSize.ref.value, sw, sh));
ValueCell.update(this.ssaoRenderable.values.uTexSize, Vec2.set(this.ssaoRenderable.values.uTexSize.ref.value, sw, sh));
ValueCell.update(this.ssaoBlurFirstPassRenderable.values.uTexSize, Vec2.set(this.ssaoBlurFirstPassRenderable.values.uTexSize.ref.value, sw, sh));
@@ -499,29 +404,25 @@ export class PostprocessingPass {
}
}
private updateState(camera: ICamera, transparentBackground: boolean, backgroundColor: Color, props: PostprocessingProps, light: Light) {
let needsUpdateShadows = false;
private updateState(camera: ICamera, transparentBackground: boolean, backgroundColor: Color, props: PostprocessingProps) {
let needsUpdateMain = false;
let needsUpdateSsao = false;
let needsUpdateSsaoBlur = false;
let needsUpdateOutlines = false;
const orthographic = camera.state.mode === 'orthographic' ? 1 : 0;
const outlinesEnabled = props.outline.name === 'on';
const shadowsEnabled = props.shadow.name === 'on';
const occlusionEnabled = props.occlusion.name === 'on';
const invProjection = Mat4.identity();
Mat4.invert(invProjection, camera.projection);
const [w, h] = this.renderable.values.uTexSize.ref.value;
const v = camera.viewport;
if (props.occlusion.name === 'on') {
ValueCell.update(this.ssaoRenderable.values.uProjection, camera.projection);
ValueCell.update(this.ssaoRenderable.values.uInvProjection, invProjection);
const [w, h] = this.renderable.values.uTexSize.ref.value;
const b = this.ssaoRenderable.values.uBounds;
const v = camera.viewport;
const s = this.ssaoScale;
Vec4.set(b.ref.value,
Math.floor(v.x * s) / (w * s),
@@ -593,41 +494,8 @@ export class PostprocessingPass {
}
}
if (props.shadow.name === 'on') {
ValueCell.update(this.shadowsRenderable.values.uProjection, camera.projection);
ValueCell.update(this.shadowsRenderable.values.uInvProjection, invProjection);
Vec4.set(this.shadowsRenderable.values.uBounds.ref.value,
v.x / w,
v.y / h,
(v.x + v.width) / w,
(v.y + v.height) / h
);
ValueCell.update(this.shadowsRenderable.values.uBounds, this.shadowsRenderable.values.uBounds.ref.value);
ValueCell.updateIfChanged(this.shadowsRenderable.values.uNear, camera.near);
ValueCell.updateIfChanged(this.shadowsRenderable.values.uFar, camera.far);
ValueCell.updateIfChanged(this.shadowsRenderable.values.dOrthographic, orthographic);
ValueCell.updateIfChanged(this.shadowsRenderable.values.uMaxDistance, props.shadow.params.maxDistance);
ValueCell.updateIfChanged(this.shadowsRenderable.values.uTolerance, props.shadow.params.tolerance);
ValueCell.updateIfChanged(this.shadowsRenderable.values.uBias, props.shadow.params.bias);
if (this.shadowsRenderable.values.dSteps.ref.value !== props.shadow.params.steps) {
ValueCell.update(this.shadowsRenderable.values.dSteps, props.shadow.params.steps);
needsUpdateShadows = true;
}
ValueCell.update(this.shadowsRenderable.values.uLightDirection, light.direction);
ValueCell.update(this.shadowsRenderable.values.uLightColor, light.color);
if (this.shadowsRenderable.values.dLightCount.ref.value !== light.count) {
ValueCell.update(this.shadowsRenderable.values.dLightCount, light.count);
needsUpdateShadows = true;
}
}
if (props.outline.name === 'on') {
let { threshold, includeTransparent } = props.outline.params;
const transparentOutline = includeTransparent ?? true;
let { threshold } = props.outline.params;
// orthographic needs lower threshold
if (camera.state.mode === 'orthographic') threshold /= 5;
const factor = Math.pow(1000, threshold) / 1000;
@@ -638,16 +506,12 @@ export class PostprocessingPass {
ValueCell.updateIfChanged(this.outlinesRenderable.values.uNear, camera.near);
ValueCell.updateIfChanged(this.outlinesRenderable.values.uFar, camera.far);
ValueCell.updateIfChanged(this.outlinesRenderable.values.uMaxPossibleViewZDiff, maxPossibleViewZDiff);
if (this.renderable.values.dTransparentOutline.ref.value !== transparentOutline) { needsUpdateOutlines = true; }
ValueCell.updateIfChanged(this.outlinesRenderable.values.dTransparentOutline, transparentOutline);
ValueCell.update(this.renderable.values.uOutlineColor, Color.toVec3Normalized(this.renderable.values.uOutlineColor.ref.value, props.outline.params.color));
ValueCell.updateIfChanged(this.renderable.values.uMaxPossibleViewZDiff, maxPossibleViewZDiff);
if (this.renderable.values.dOutlineScale.ref.value !== outlineScale) { needsUpdateMain = true; }
ValueCell.updateIfChanged(this.renderable.values.dOutlineScale, outlineScale);
if (this.renderable.values.dTransparentOutline.ref.value !== transparentOutline) { needsUpdateMain = true; }
ValueCell.updateIfChanged(this.renderable.values.dTransparentOutline, transparentOutline);
}
ValueCell.updateIfChanged(this.renderable.values.uFar, camera.far);
@@ -658,22 +522,11 @@ export class PostprocessingPass {
ValueCell.updateIfChanged(this.renderable.values.uTransparentBackground, transparentBackground);
if (this.renderable.values.dOrthographic.ref.value !== orthographic) { needsUpdateMain = true; }
ValueCell.updateIfChanged(this.renderable.values.dOrthographic, orthographic);
if (this.renderable.values.dOutlineEnable.ref.value !== outlinesEnabled) { needsUpdateMain = true; }
ValueCell.updateIfChanged(this.renderable.values.dOutlineEnable, outlinesEnabled);
if (this.renderable.values.dShadowEnable.ref.value !== shadowsEnabled) { needsUpdateMain = true; }
ValueCell.updateIfChanged(this.renderable.values.dShadowEnable, shadowsEnabled);
if (this.renderable.values.dOcclusionEnable.ref.value !== occlusionEnabled) { needsUpdateMain = true; }
ValueCell.updateIfChanged(this.renderable.values.dOcclusionEnable, occlusionEnabled);
if (needsUpdateOutlines) {
this.outlinesRenderable.update();
}
if (needsUpdateShadows) {
this.shadowsRenderable.update();
}
if (needsUpdateSsao) {
this.ssaoRenderable.update();
}
@@ -711,20 +564,15 @@ export class PostprocessingPass {
this.transparentBackground = value;
}
render(camera: ICamera, toDrawingBuffer: boolean, transparentBackground: boolean, backgroundColor: Color, props: PostprocessingProps, light: Light) {
render(camera: ICamera, toDrawingBuffer: boolean, transparentBackground: boolean, backgroundColor: Color, props: PostprocessingProps) {
if (isTimingMode) this.webgl.timer.mark('PostprocessingPass.render');
this.updateState(camera, transparentBackground, backgroundColor, props, light);
this.updateState(camera, transparentBackground, backgroundColor, props);
if (props.outline.name === 'on') {
this.outlinesTarget.bind();
this.outlinesRenderable.render();
}
if (props.shadow.name === 'on') {
this.shadowsTarget.bind();
this.shadowsRenderable.render();
}
// don't render occlusion if offset is given,
// which will reuse the existing occlusion
if (props.occlusion.name === 'on' && this.occlusionOffset[0] === 0 && this.occlusionOffset[1] === 0) {

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -21,7 +21,6 @@ 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) {
@@ -55,7 +54,6 @@ 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),
};
}
}
@@ -76,7 +74,6 @@ 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),
};
}
}

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2021-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -21,7 +21,6 @@ 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) {
@@ -55,7 +54,6 @@ 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),
};
}
}
@@ -76,7 +74,6 @@ 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),
};
}
}

View File

@@ -7,7 +7,7 @@
import { ValueCell } from '../../../mol-util';
import { Sphere3D } from '../../../mol-math/geometry';
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
import { LocationIterator, PositionLocation } from '../../../mol-geo/util/location-iterator';
import { LocationIterator } from '../../../mol-geo/util/location-iterator';
import { TransformData } from '../transform-data';
import { createColors } from '../color-data';
import { createMarkers } from '../marker-data';
@@ -20,12 +20,11 @@ import { createEmptyTransparency } from '../transparency-data';
import { TextureMeshValues } from '../../../mol-gl/renderable/texture-mesh';
import { calculateTransformBoundingSphere } from '../../../mol-gl/renderable/util';
import { createNullTexture, Texture } from '../../../mol-gl/webgl/texture';
import { Vec2, Vec3, Vec4 } from '../../../mol-math/linear-algebra';
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';
import { WebGLContext } from '../../../mol-gl/webgl/context';
export interface TextureMesh {
readonly kind: 'texture-mesh',
@@ -44,10 +43,7 @@ export interface TextureMesh {
readonly boundingSphere: Sphere3D
readonly meta: {
webgl?: WebGLContext
[k: string]: unknown
}
readonly meta: { [k: string]: unknown }
}
export namespace TextureMesh {
@@ -135,42 +131,9 @@ export namespace TextureMesh {
updateBoundingSphere,
createRenderableState,
updateRenderableState,
createPositionIterator,
createPositionIterator: () => LocationIterator(1, 1, 1, () => NullLocation)
};
const TextureMeshName = 'texture-mesh';
function createPositionIterator(textureMesh: TextureMesh, transform: TransformData): LocationIterator {
const webgl = textureMesh.meta.webgl;
if (!webgl) return LocationIterator(1, 1, 1, () => NullLocation);
if (!webgl.namedFramebuffers[TextureMeshName]) {
webgl.namedFramebuffers[TextureMeshName] = webgl.resources.framebuffer();
}
const framebuffer = webgl.namedFramebuffers[TextureMeshName];
const [width, height] = textureMesh.geoTextureDim.ref.value;
const vertices = new Float32Array(width * height * 4);
framebuffer.bind();
textureMesh.vertexTexture.ref.value.attachFramebuffer(framebuffer, 0);
webgl.readPixels(0, 0, width, height, vertices);
const groupCount = textureMesh.vertexCount;
const instanceCount = transform.instanceCount.ref.value;
const location = PositionLocation();
const p = location.position;
const v = vertices;
const m = transform.aTransform.ref.value;
const getLocation = (groupIndex: number, instanceIndex: number) => {
if (instanceIndex < 0) {
Vec3.fromArray(p, v, groupIndex * 4);
} else {
Vec3.transformMat4Offset(p, v, m, 0, groupIndex * 4, instanceIndex * 16);
}
return location;
};
return LocationIterator(groupCount, instanceCount, 1, getLocation);
}
function createValues(textureMesh: TextureMesh, transform: TransformData, locationIt: LocationIterator, theme: Theme, props: PD.Values<Params>): TextureMeshValues {
const { instanceCount, groupCount } = locationIt;
const positionIt = Utils.createPositionIterator(textureMesh, transform);

View File

@@ -21,7 +21,6 @@ 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) {
@@ -64,7 +63,6 @@ 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),
};
}
}
@@ -86,7 +84,6 @@ 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),
};
}
}

View File

@@ -229,7 +229,6 @@ 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>
@@ -243,8 +242,7 @@ export const TransparencySchema = {
uTransparencyGridDim: UniformSpec('v3'),
uTransparencyGridTransform: UniformSpec('v4'),
tTransparencyGrid: TextureSpec('texture', 'alpha', 'ubyte', 'linear'),
dTransparencyType: DefineSpec('string', ['instance', 'groupInstance', 'volumeInstance']),
uTransparencyStrength: UniformSpec('f', 'material'),
dTransparencyType: DefineSpec('string', ['instance', 'groupInstance', 'volumeInstance'])
} as const;
export type TransparencySchema = typeof TransparencySchema
export type TransparencyValues = Values<TransparencySchema>
@@ -258,7 +256,6 @@ 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>

View File

@@ -54,7 +54,6 @@ export const enum MarkingType {
interface Renderer {
readonly stats: RendererStats
readonly props: Readonly<RendererProps>
readonly light: Readonly<Light>
clear: (toBackgroundColor: boolean, ignoreTransparentBackground?: boolean) => void
clearDepth: (packed?: boolean) => void
@@ -104,13 +103,13 @@ export const RendererParams = {
xrayEdgeFalloff: PD.Numeric(1, { min: 0.0, max: 3.0, step: 0.1 }),
light: PD.ObjectList({
inclination: PD.Numeric(150, { min: 0, max: 180, step: 1 }),
azimuth: PD.Numeric(320, { min: 0, max: 360, step: 1 }),
inclination: PD.Numeric(180, { min: 0, max: 180, step: 1 }),
azimuth: PD.Numeric(0, { min: 0, max: 360, step: 1 }),
color: PD.Color(Color.fromNormalizedRgb(1.0, 1.0, 1.0)),
intensity: PD.Numeric(0.6, { min: 0.0, max: 1.0, step: 0.01 }),
}, o => Color.toHexString(o.color), { defaultValue: [{
inclination: 150,
azimuth: 320,
inclination: 180,
azimuth: 0,
color: Color.fromNormalizedRgb(1.0, 1.0, 1.0),
intensity: 0.6
}] }),
@@ -119,7 +118,7 @@ export const RendererParams = {
};
export type RendererProps = PD.Values<typeof RendererParams>
export type Light = {
type Light = {
count: number
direction: number[]
color: number[]
@@ -828,9 +827,6 @@ namespace Renderer {
instancedDrawCount: stats.instancedDrawCount,
};
},
get light(): Light {
return light;
},
dispose: () => {
// TODO
}

View File

@@ -12,7 +12,7 @@ export const apply_light_color = `
gl_FragColor = material;
#else
#ifdef bumpEnabled
if (uBumpFrequency > 0.0 && uBumpAmplitude > 0.0 && bumpiness > 0.0) {
if (uBumpFrequency > 0.0 && uBumpAmplitude > 0.0) {
normal = perturbNormal(-vViewPosition, normal, fbm(vModelPosition * uBumpFrequency), (uBumpAmplitude * bumpiness) / uBumpFrequency);
}
#endif

View File

@@ -42,7 +42,6 @@ export const assign_color_varying = `
#else
vOverpaint.rgb = mix(vColor.rgb, vOverpaint.rgb, vOverpaint.a);
#endif
vOverpaint *= uOverpaintStrength;
#endif
#ifdef dSubstance
@@ -59,7 +58,6 @@ 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
@@ -88,6 +86,5 @@ export const assign_color_varying = `
vec3 tgridPos = (uTransparencyGridTransform.w * (vModelPosition - uTransparencyGridTransform.xyz)) / uTransparencyGridDim;
vTransparency = texture3dFrom2dLinear(tTransparencyGrid, tgridPos, uTransparencyGridDim, uTransparencyTexDim).a;
#endif
vTransparency *= uTransparencyStrength;
#endif
`;

View File

@@ -1,7 +1,12 @@
export const clip_instance = `
#if defined(dClipVariant_instance) && dClipObjectCount != 0
int flag = 0;
#if defined(dClipping)
flag = int(floor(vClipping * 255.0 + 0.5));
#endif
vec4 mCenter = uModel * aTransform * vec4(uInvariantBoundingSphere.xyz, 1.0);
if (clipTest(vec4(mCenter.xyz, uInvariantBoundingSphere.w)))
if (clipTest(vec4(mCenter.xyz, uInvariantBoundingSphere.w), flag))
// move out of [ -w, +w ] to 'discard' in vert shader
gl_Position.z = 2.0 * gl_Position.w;
#endif

View File

@@ -1,6 +1,12 @@
export const clip_pixel = `
#if defined(dClipVariant_pixel) && dClipObjectCount != 0
if (clipTest(vec4(vModelPosition, 0.0)))
#if defined(dClipping)
int clippingFlag = int(floor(vClipping * 255.0 + 0.5));
#else
int clippingFlag = 0;
#endif
if (clipTest(vec4(vModelPosition, 0.0), clippingFlag))
discard;
#endif
`;

View File

@@ -39,7 +39,6 @@ uniform float uBumpiness;
uniform vec4 uOverpaintGridTransform;
uniform sampler2D tOverpaintGrid;
#endif
uniform float uOverpaintStrength;
#endif
#ifdef dSubstance
@@ -54,7 +53,6 @@ uniform float uBumpiness;
uniform vec4 uSubstanceGridTransform;
uniform sampler2D tSubstanceGrid;
#endif
uniform float uSubstanceStrength;
#endif
#elif defined(dRenderVariant_pick)
#if __VERSION__ == 100 || !defined(dVaryingGroup)
@@ -88,6 +86,5 @@ uniform float uBumpiness;
uniform vec4 uTransparencyGridTransform;
uniform sampler2D tTransparencyGrid;
#endif
uniform float uTransparencyStrength;
#endif
`;

View File

@@ -1,5 +1,5 @@
/**
* 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 Ludovic Autin <autin@scripps.edu>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -7,45 +7,45 @@
export const common_clip = `
#if dClipObjectCount != 0
vec3 quaternionTransform(const in vec4 q, const in vec3 v) {
vec3 quaternionTransform(vec4 q, vec3 v) {
vec3 t = 2.0 * cross(q.xyz, v);
return v + q.w * t + cross(q.xyz, t);
}
vec4 computePlane(const in vec3 normal, const in vec3 inPoint) {
vec4 computePlane(vec3 normal, vec3 inPoint) {
return vec4(normalize(normal), -dot(normal, inPoint));
}
float planeSD(const in vec4 plane, const in vec3 center) {
float planeSD(vec4 plane, vec3 center) {
return -dot(plane.xyz, center - plane.xyz * -plane.w);
}
float sphereSD(const in vec3 position, const in vec4 rotation, const in vec3 size, const in vec3 center) {
float sphereSD(vec3 position, vec4 rotation, vec3 size, vec3 center) {
return (
length(quaternionTransform(vec4(-rotation.x, -rotation.y, -rotation.z, rotation.w), center - position) / size) - 1.0
) * min(min(size.x, size.y), size.z);
}
float cubeSD(const in vec3 position, const in vec4 rotation, const in vec3 size, const in vec3 center) {
float cubeSD(vec3 position, vec4 rotation, vec3 size, vec3 center) {
vec3 d = abs(quaternionTransform(vec4(-rotation.x, -rotation.y, -rotation.z, rotation.w), center - position)) - size;
return min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0));
}
float cylinderSD(const in vec3 position, const in vec4 rotation, const in vec3 size, const in vec3 center) {
float cylinderSD(vec3 position, vec4 rotation, vec3 size, vec3 center) {
vec3 t = quaternionTransform(vec4(-rotation.x, -rotation.y, -rotation.z, rotation.w), center - position);
vec2 d = abs(vec2(length(t.xz), t.y)) - size.xy;
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
}
float infiniteConeSD(const in vec3 position, const in vec4 rotation, const in vec3 size, const in vec3 center) {
float infiniteConeSD(vec3 position, vec4 rotation, vec3 size, vec3 center) {
vec3 t = quaternionTransform(vec4(-rotation.x, -rotation.y, -rotation.z, rotation.w), center - position);
float q = length(t.xy);
return dot(size.xy, vec2(q, t.z));
}
float getSignedDistance(const in vec3 center, const in int type, const in vec3 position, const in vec4 rotation, const in vec3 scale) {
float getSignedDistance(vec3 center, int type, vec3 position, vec4 rotation, vec3 scale) {
if (type == 1) {
vec3 normal = quaternionTransform(rotation, vec3(0.0, 1.0, 0.0));
vec4 plane = computePlane(normal, position);
@@ -65,7 +65,7 @@ export const common_clip = `
#if __VERSION__ == 100
// 8-bit
int bitwiseAnd(const in int a, const in int b) {
int bitwiseAnd(int a, int b) {
int d = 128;
int result = 0;
for (int i = 0; i < 8; ++i) {
@@ -78,23 +78,17 @@ export const common_clip = `
return result;
}
bool hasBit(const in int mask, const in int bit) {
bool hasBit(int mask, int bit) {
return bitwiseAnd(mask, bit) == 0;
}
#else
bool hasBit(const in int mask, const in int bit) {
bool hasBit(int mask, int bit) {
return (mask & bit) == 0;
}
#endif
bool clipTest(const in vec4 sphere) {
// flag is a bit-flag for clip-objects to ignore (note, object ids start at 1 not 0)
#if defined(dClipping)
int flag = int(floor(vClipping * 255.0 + 0.5));
#else
int flag = 0;
#endif
// flag is a bit-flag for clip-objects to ignore (note, object ids start at 1 not 0)
bool clipTest(vec4 sphere, int flag) {
#pragma unroll_loop_start
for (int i = 0; i < dClipObjectCount; ++i) {
if (flag == 0 || hasBit(flag, UNROLLED_LOOP_INDEX + 1)) {

View File

@@ -33,8 +33,7 @@ uniform mat4 uInvView;
bool CylinderImpostor(
in vec3 rayOrigin, in vec3 rayDir,
in vec3 start, in vec3 end, in float radius,
out vec3 cameraNormal, out bool interior,
out vec3 modelPosition, out vec3 viewPosition, out float fragmentDepth
out vec4 intersection, out bool interior
){
vec3 ba = end - start;
vec3 oc = rayOrigin - start;
@@ -43,7 +42,7 @@ bool CylinderImpostor(
float bard = dot(ba, rayDir);
float baoc = dot(ba, oc);
float k2 = baba - bard * bard;
float k2 = baba - bard*bard;
float k1 = baba * dot(oc, rayDir) - baoc * bard;
float k0 = baba * dot(oc, oc) - baoc * baoc - radius * radius * baba;
@@ -59,14 +58,8 @@ bool CylinderImpostor(
float y = baoc + t * bard;
if (y > 0.0 && y < baba) {
interior = false;
cameraNormal = (oc + t * rayDir - ba * y / baba) / radius;
modelPosition = rayOrigin + t * rayDir;
viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
fragmentDepth = calcDepth(viewPosition);
#if defined(dClipVariant_pixel) && dClipObjectCount != 0
if (clipTest(vec4(modelPosition, 0.0))) fragmentDepth = -1.0;
#endif
if (fragmentDepth > 0.0) return true;
intersection = vec4(t, (oc + t * rayDir - ba * y / baba) / radius);
return true;
}
if (topCap && y < 0.0) {
@@ -74,22 +67,16 @@ bool CylinderImpostor(
t = -baoc / bard;
if (abs(k1 + k2 * t) < h) {
interior = false;
cameraNormal = -ba / baba;
modelPosition = rayOrigin + t * rayDir;
viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
fragmentDepth = calcDepth(viewPosition);
if (fragmentDepth > 0.0) return true;
intersection = vec4(t, ba * sign(y) / baba);
return true;
}
} else if(bottomCap && y >= 0.0) {
// bottom cap
t = (baba - baoc) / bard;
if (abs(k1 + k2 * t) < h) {
interior = false;
cameraNormal = ba / baba;
modelPosition = rayOrigin + t * rayDir;
viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
fragmentDepth = calcDepth(viewPosition);
if (fragmentDepth > 0.0) return true;
intersection = vec4(t, ba * sign(y) / baba);
return true;
}
}
@@ -100,61 +87,36 @@ bool CylinderImpostor(
y = baoc + t * bard;
if (y > 0.0 && y < baba) {
interior = true;
cameraNormal = -(oc + t * rayDir - ba * y / baba) / radius;
modelPosition = rayOrigin + t * rayDir;
viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
fragmentDepth = calcDepth(viewPosition);
intersection = vec4(t, (oc + t * rayDir - ba * y / baba) / radius);
return true;
}
if (topCap && y < 0.0) {
// top cap
t = -baoc / bard;
if (abs(k1 + k2 * t) < -h) {
interior = true;
cameraNormal = ba / baba;
modelPosition = rayOrigin + t * rayDir;
viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
fragmentDepth = calcDepth(viewPosition);
if (fragmentDepth > 0.0) return true;
}
} else if(bottomCap && y >= 0.0) {
// bottom cap
t = (baba - baoc) / bard;
if (abs(k1 + k2 * t) < -h) {
interior = true;
cameraNormal = -ba / baba;
modelPosition = rayOrigin + t * rayDir;
viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
fragmentDepth = calcDepth(viewPosition);
if (fragmentDepth > 0.0) return true;
}
}
// TODO: handle inside caps???
}
return false;
}
void main() {
vec3 rayOrigin = vModelPosition;
#include clip_pixel
vec3 rayDir = mix(normalize(vModelPosition - uCameraPosition), uCameraDir, uIsOrtho);
vec3 cameraNormal;
vec3 modelPosition;
vec3 viewPosition;
float fragmentDepth;
bool hit = CylinderImpostor(rayOrigin, rayDir, vStart, vEnd, vSize, cameraNormal, interior, modelPosition, viewPosition, fragmentDepth);
vec4 intersection;
bool interior;
bool hit = CylinderImpostor(vModelPosition, rayDir, vStart, vEnd, vSize, intersection, interior);
if (!hit) discard;
vec3 vViewPosition = vModelPosition + intersection.x * rayDir;
vViewPosition = (uView * vec4(vViewPosition, 1.0)).xyz;
float fragmentDepth = calcDepth(vViewPosition);
if (fragmentDepth < 0.0) discard;
if (fragmentDepth > 1.0) discard;
gl_FragDepthEXT = fragmentDepth;
vec3 vViewPosition = viewPosition;
vec3 vModelPosition = modelPosition;
#include clip_pixel
vec3 vModelPosition = (uInvView * vec4(vViewPosition, 1.0)).xyz;
#include assign_material_color
#if defined(dRenderVariant_pick)
@@ -173,7 +135,7 @@ void main() {
gl_FragColor = material;
#elif defined(dRenderVariant_color)
mat3 normalMatrix = transpose3(inverse3(mat3(uView)));
vec3 normal = normalize(normalMatrix * -normalize(cameraNormal));
vec3 normal = normalize(normalMatrix * -normalize(intersection.yzw));
#include apply_light_color
#include apply_interior_color

View File

@@ -1,5 +1,5 @@
/**
* 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 Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -55,12 +55,7 @@ void main() {
vec3 camDir = -mix(normalize(vModelPosition - uCameraPosition), uCameraDir, uIsOrtho);
vec3 dir = vEnd - vStart;
// ensure cylinder 'dir' is pointing towards the camera
if(dot(camDir, dir) < 0.0) {
dir = -dir;
vec3 tmp = vStart;
vStart = vEnd;
vEnd = tmp;
}
if(dot(camDir, dir) < 0.0) dir = -dir;
vec3 left = cross(camDir, dir);
vec3 up = cross(left, dir);
@@ -74,9 +69,6 @@ void main() {
vViewPosition = mvPosition.xyz;
gl_Position = uProjection * mvPosition;
mvPosition.z -= 2.0 * (length(vEnd - vStart) + vSize); // avoid clipping
gl_Position.z = (uProjection * mvPosition).z;
#include clip_instance
}
`;

View File

@@ -229,7 +229,7 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 rayDir) {
#if defined(dClipVariant_pixel) && dClipObjectCount != 0
vec3 vModelPosition = v3m4(unitPos * uGridDim, modelTransform);
if (clipTest(vec4(vModelPosition, 0.0))) {
if (clipTest(vec4(vModelPosition, 0.0), 0)) {
prevValue = value;
pos += step;
continue;
@@ -270,16 +270,16 @@ vec4 raymarch(vec3 startLoc, vec3 step, vec3 rayDir) {
#elif defined(dColorType_groupInstance)
material.rgb = readFromTexture(tColor, vInstance * float(uGroupCount) + group, uColorTexDim).rgb;
#elif defined(dColorType_vertex)
material.rgb = texture3dFrom1dTrilinear(tColor, unitPos, uGridDim, uColorTexDim, 0.0).rgb;
material.rgb = texture3dFrom1dTrilinear(tColor, isoPos, uGridDim, uColorTexDim, 0.0).rgb;
#elif defined(dColorType_vertexInstance)
material.rgb = texture3dFrom1dTrilinear(tColor, unitPos, uGridDim, uColorTexDim, vInstance * float(uVertexCount)).rgb;
material.rgb = texture3dFrom1dTrilinear(tColor, isoPos, uGridDim, uColorTexDim, vInstance * float(uVertexCount)).rgb;
#endif
#ifdef dOverpaint
#if defined(dOverpaintType_groupInstance)
overpaint = readFromTexture(tOverpaint, vInstance * float(uGroupCount) + group, uOverpaintTexDim);
#elif defined(dOverpaintType_vertexInstance)
overpaint = texture3dFrom1dTrilinear(tOverpaint, unitPos, uGridDim, uOverpaintTexDim, vInstance * float(uVertexCount));
overpaint = texture3dFrom1dTrilinear(tOverpaint, isoPos, uGridDim, uOverpaintTexDim, vInstance * float(uVertexCount));
#endif
material.rgb = mix(material.rgb, overpaint.rgb, overpaint.a);

View File

@@ -38,11 +38,7 @@ float getDepthOpaque(const in vec2 coords) {
}
float getDepthTransparent(const in vec2 coords) {
#ifdef dTransparentOutline
return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
#else
return 1.0;
#endif
return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
}
bool isBackground(const in float depth) {

View File

@@ -14,7 +14,6 @@ uniform sampler2D tSsaoDepth;
uniform sampler2D tColor;
uniform sampler2D tDepthOpaque;
uniform sampler2D tDepthTransparent;
uniform sampler2D tShadows;
uniform sampler2D tOutlines;
uniform vec2 uTexSize;
@@ -51,11 +50,7 @@ float getDepthOpaque(const in vec2 coords) {
}
float getDepthTransparent(const in vec2 coords) {
#ifdef dTransparentOutline
return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
#else
return 1.0;
#endif
return unpackRGBAToDepth(texture2D(tDepthTransparent, coords));
}
bool isBackground(const in float depth) {
@@ -125,20 +120,7 @@ void main(void) {
}
#endif
#ifdef dShadowEnable
if (!isBackground(opaqueDepth)) {
viewDist = abs(getViewZ(opaqueDepth));
fogFactor = smoothstep(uFogNear, uFogFar, viewDist);
vec4 shadow = texture2D(tShadows, coords);
if (!uTransparentBackground) {
color.rgb = mix(mix(vec3(0), uFogColor, fogFactor), color.rgb, shadow.a);
} else {
color.rgb = mix(vec3(0) * (1.0 - fogFactor), color.rgb, shadow.a);
}
}
#endif
// outline needs to be handled after occlusion and shadow to keep them clean
// outline needs to be handled after occlusion to keep them clean
#ifdef dOutlineEnable
float closestTexel;
float outline = getOutline(coords, opaqueDepth, closestTexel);

View File

@@ -1,131 +0,0 @@
/**
* Copyright (c) 2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Ludovic Autin <ludovic.autin@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
export const shadows_frag = `
precision highp float;
precision highp int;
precision highp sampler2D;
#include common
uniform sampler2D tDepth;
uniform vec2 uTexSize;
uniform vec4 uBounds;
uniform float uNear;
uniform float uFar;
#if dLightCount != 0
uniform vec3 uLightDirection[dLightCount];
uniform vec3 uLightColor[dLightCount];
#endif
uniform mat4 uProjection;
uniform mat4 uInvProjection;
uniform float uMaxDistance;
uniform float uTolerance;
uniform float uBias;
bool isBackground(const in float depth) {
return depth == 1.0;
}
bool outsideBounds(const in vec2 p) {
return p.x < uBounds.x || p.y < uBounds.y || p.x > uBounds.z || p.y > uBounds.w;
}
float getViewZ(const in float depth) {
#if dOrthographic == 1
return orthographicDepthToViewZ(depth, uNear, uFar);
#else
return perspectiveDepthToViewZ(depth, uNear, uFar);
#endif
}
float getDepth(const in vec2 coords) {
#ifdef depthTextureSupport
return texture2D(tDepth, coords).r;
#else
return unpackRGBAToDepth(texture2D(tDepth, coords));
#endif
}
float screenFade(const in vec2 coords) {
vec2 c = (coords - uBounds.xy) / (uBounds.zw - uBounds.xy);
vec2 fade = max(12.0 * abs(c - 0.5) - 5.0, vec2(0.0));
return saturate(1.0 - dot(fade, fade));
}
// based on https://panoskarabelas.com/posts/screen_space_shadows/
float screenSpaceShadow(const in vec3 position, const in vec3 lightDirection, const in float stepLength) {
// Ray position and direction (in view-space)
vec3 rayPos = position;
vec3 rayDir = -lightDirection;
// Compute ray step
vec3 rayStep = rayDir * stepLength;
// Ray march towards the light
float occlusion = 0.0;
vec4 rayCoords = vec4(0.0);
for (int i = 0; i < dSteps; ++i) {
// Step the ray
rayPos += rayStep;
rayCoords = uProjection * vec4(rayPos, 1.0);
rayCoords.xyz = (rayCoords.xyz / rayCoords.w) * 0.5 + 0.5;
if (outsideBounds(rayCoords.xy))
return 1.0;
// Compute the difference between the ray's and the camera's depth
float depth = getDepth(rayCoords.xy);
float viewZ = getViewZ(depth);
float zDelta = rayPos.z - viewZ;
if (zDelta < uTolerance) {
occlusion = 1.0;
// Fade out as we approach the edges of the screen
occlusion *= screenFade(rayCoords.xy);
break;
}
}
return 1.0 - (uBias * occlusion);
}
void main(void) {
vec2 invTexSize = 1.0 / uTexSize;
vec2 selfCoords = gl_FragCoord.xy * invTexSize;
float selfDepth = getDepth(selfCoords);
if (isBackground(selfDepth)) {
gl_FragColor = vec4(0.0);
return;
}
vec3 selfViewPos = screenSpaceToViewSpace(vec3(selfCoords, selfDepth), uInvProjection);
float stepLength = uMaxDistance / float(dSteps);
float o = 1.0;
#if dLightCount != 0
float sh[dLightCount];
#pragma unroll_loop_start
for (int i = 0; i < dLightCount; ++i) {
sh[i] = screenSpaceShadow(selfViewPos, uLightDirection[i], stepLength);
o = min(o, sh[i]);
}
#pragma unroll_loop_end
#endif
gl_FragColor = vec4(o);
}
`;

View File

@@ -23,8 +23,12 @@ varying float vRadiusSq;
varying vec3 vPoint;
varying vec3 vPointViewPosition;
bool SphereImpostor(out vec3 modelPos, out vec3 cameraPos, out vec3 cameraNormal, out bool interior, out float fragmentDepth, out bool clipped){
vec3 cameraPos;
vec3 cameraNormal;
bool Impostor(out vec3 cameraPos, out vec3 cameraNormal){
vec3 cameraSpherePos = -vPointViewPosition;
cameraSpherePos.z += vRadius;
vec3 rayOrigin = mix(vec3(0.0, 0.0, 0.0), vPoint, uIsOrtho);
vec3 rayDirection = mix(normalize(vPoint), vec3(0.0, 0.0, 1.0), uIsOrtho);
@@ -33,61 +37,50 @@ bool SphereImpostor(out vec3 modelPos, out vec3 cameraPos, out vec3 cameraNormal
float B = dot(rayDirection, cameraSphereDir);
float det = B * B + vRadiusSq - dot(cameraSphereDir, cameraSphereDir);
if (det < 0.0) return false;
float sqrtDet = sqrt(det);
float posT = mix(B + sqrtDet, B - sqrtDet, uIsOrtho);
float negT = mix(B - sqrtDet, B + sqrtDet, uIsOrtho);
cameraPos = rayDirection * negT + rayOrigin;
modelPos = (uInvView * vec4(cameraPos, 1.0)).xyz;
fragmentDepth = calcDepth(cameraPos);
#if defined(dClipVariant_pixel) && dClipObjectCount != 0
if (clipTest(vec4(modelPos, 0.0))) {
clipped = true;
fragmentDepth = -1.0;
}
#endif
if (fragmentDepth > 0.0) {
cameraNormal = normalize(cameraPos - cameraSpherePos);
interior = false;
return true;
} else if (uDoubleSided) {
cameraPos = rayDirection * posT + rayOrigin;
modelPos = (uInvView * vec4(cameraPos, 1.0)).xyz;
fragmentDepth = calcDepth(cameraPos);
cameraNormal = -normalize(cameraPos - cameraSpherePos);
interior = true;
return true;
if (det < 0.0){
discard;
return false;
}
return false;
float sqrtDet = sqrt(det);
float posT = mix(B + sqrtDet, B + sqrtDet, uIsOrtho);
float negT = mix(B - sqrtDet, sqrtDet - B, uIsOrtho);
cameraPos = rayDirection * negT + rayOrigin;
if (calcDepth(cameraPos) <= 0.0) {
cameraPos = rayDirection * posT + rayOrigin;
interior = true;
} else {
interior = false;
}
cameraNormal = normalize(cameraPos - cameraSpherePos);
cameraNormal *= float(!interior) * 2.0 - 1.0;
return !interior;
}
void main(void){
vec3 modelPos;
vec3 cameraPos;
vec3 cameraNormal;
float fragmentDepth;
bool clipped = false;
bool hit = SphereImpostor(modelPos, cameraPos, cameraNormal, interior, fragmentDepth, clipped);
if (!hit) discard;
#include clip_pixel
bool flag = Impostor(cameraPos, cameraNormal);
if (!uDoubleSided) {
if (interior) discard;
}
vec3 vViewPosition = cameraPos;
float fragmentDepth = calcDepth(vViewPosition);
if (!flag && fragmentDepth >= 0.0) {
fragmentDepth = 0.0 + (0.0000001 / vRadius);
}
if (fragmentDepth < 0.0) discard;
if (fragmentDepth > 1.0) discard;
vec3 vViewPosition = cameraPos;
vec3 vModelPosition = modelPos;
if (interior && !clipped) {
fragmentDepth = 0.0 + (0.0000001 / vRadius);
}
gl_FragDepthEXT = fragmentDepth;
#include clip_pixel
vec3 vModelPosition = (uInvView * vec4(vViewPosition, 1.0)).xyz;
#include assign_material_color
#if defined(dRenderVariant_pick)

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -85,6 +85,7 @@ void main(void){
vec4 position4 = vec4(aPosition, 1.0);
vec4 mvPosition = uModelView * aTransform * position4;
mvPosition.z -= vRadius; // avoid clipping, added again in fragment shader
gl_Position = uProjection * vec4(mvPosition.xyz, 1.0);
quadraticProjection(size, aPosition);
@@ -96,9 +97,6 @@ void main(void){
vModelPosition = (uModel * aTransform * position4).xyz; // for clipping in frag shader
mvPosition.z -= 2.0 * vRadius; // avoid clipping
gl_Position.z = (uProjection * vec4(mvPosition.xyz, 1.0)).z;
#include clip_instance
}
`;

View File

@@ -19,9 +19,6 @@ 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;
@@ -49,9 +46,6 @@ 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;
}
@@ -66,9 +60,6 @@ export function getStandardDerivatives(gl: GLRenderingContext): COMPAT_standard_
}
}
/**
* See https://registry.khronos.org/webgl/extensions/OES_element_index_uint/
*/
export interface COMPAT_element_index_uint {
}
@@ -76,9 +67,6 @@ 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;
@@ -144,9 +132,6 @@ 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
@@ -162,9 +147,6 @@ export function getBlendMinMax(gl: GLRenderingContext): COMPAT_blend_minmax | nu
}
}
/**
* See https://registry.khronos.org/webgl/extensions/EXT_frag_depth/
*/
export interface COMPAT_frag_depth {
}
@@ -214,9 +196,6 @@ 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;
@@ -289,73 +268,6 @@ 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 {
}
@@ -363,9 +275,6 @@ 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;
}
@@ -384,9 +293,6 @@ 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;
@@ -414,9 +320,6 @@ 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
@@ -498,31 +401,6 @@ 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;

View File

@@ -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, getDrawBuffersIndexed, COMPAT_draw_buffers_indexed, getParallelShaderCompile, COMPAT_parallel_shader_compile, getFboRenderMipmap, COMPAT_fboRenderMipmap } 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 } 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,12 +23,9 @@ 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
}
@@ -97,10 +94,6 @@ 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"');
@@ -113,39 +106,28 @@ 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,
};

View File

@@ -1,7 +1,7 @@
/**
* Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Code-generated 'BIRD' schema file. Dictionary versions: mmCIF 5.363, IHM 1.17, MA 1.4.3.
* Code-generated 'BIRD' schema file. Dictionary versions: mmCIF 5.362, IHM 1.17, MA 1.4.3.
*
* @author molstar/ciftools package
*/

View File

@@ -1,7 +1,7 @@
/**
* Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Code-generated 'CCD' schema file. Dictionary versions: mmCIF 5.363, IHM 1.17, MA 1.4.3.
* Code-generated 'CCD' schema file. Dictionary versions: mmCIF 5.362, IHM 1.17, MA 1.4.3.
*
* @author molstar/ciftools package
*/

View File

@@ -1,7 +1,7 @@
/**
* Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Code-generated 'mmCIF' schema file. Dictionary versions: mmCIF 5.363, IHM 1.17, MA 1.4.3.
* Code-generated 'mmCIF' schema file. Dictionary versions: mmCIF 5.362, IHM 1.17, MA 1.4.3.
*
* @author molstar/ciftools package
*/

View File

@@ -1,11 +1,11 @@
/**
* Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2017 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,13 +29,11 @@ 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,
/**
@@ -53,20 +51,19 @@ namespace SymmetryOperator {
export const RotationTranslationEpsilon = 0.005;
export type CreateInfo = { assembly?: SymmetryOperator['assembly'], ncsId?: number, hkl?: Vec3, spgrOp?: number, key?: number }
export type CreateInfo = { assembly?: SymmetryOperator['assembly'], ncsId?: number, hkl?: Vec3, spgrOp?: number }
export function create(name: string, matrix: Mat4, info?: CreateInfo | SymmetryOperator): SymmetryOperator {
let { assembly, ncsId, hkl, spgrOp, key } = info || { };
let { assembly, ncsId, hkl, spgrOp } = info || { };
const _hkl = hkl ? Vec3.clone(hkl) : Vec3();
spgrOp = spgrOp ?? -1;
key = key ?? -1;
spgrOp = defaults(spgrOp, -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, key };
if (isIdentity) return { name, assembly, matrix, inverse: Mat4.identity(), isIdentity: true, hkl: _hkl, spgrOp, ncsId, suffix };
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, key, ncsId, suffix };
return { name, assembly, matrix, inverse: Mat4.invert(Mat4(), matrix), isIdentity: false, hkl: _hkl, spgrOp, ncsId, suffix };
}
function isSymmetryOperator(x: any): x is SymmetryOperator {

View File

@@ -14,8 +14,6 @@ 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>
@@ -26,22 +24,18 @@ 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, operatorA, operatorB, order, distance, flag });
return builder.createGraph({ key, order, distance, flag });
}
export namespace IndexPairBonds {
@@ -56,10 +50,6 @@ 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
@@ -93,30 +83,12 @@ 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, operatorA, operatorB, order, distance, flag }, count),
bonds: getGraph(indexA, indexB, { key, order, distance, flag }, count),
maxDistance: p.maxDistance
};
}
/** Like `getEdgeIndex` but taking `edgeProps.operatorA` and `edgeProps.operatorB` into account */
export function getEdgeIndexForOperators(bonds: IndexPairs, i: ElementIndex, j: ElementIndex, opI: number, opJ: number): number {
let a, b, opA, opB;
if (i < j) {
a = i; b = j;
opA = opI; opB = opJ;
} else {
a = j; b = i;
opA = opJ; opB = opI;
}
for (let t = bonds.offset[a], _t = bonds.offset[a + 1]; t < _t; t++) {
if (bonds.b[t] === b && bonds.edgeProps.operatorA[t] === opA && bonds.edgeProps.operatorB[t] === opB) return t;
}
return -1;
}
}

View File

@@ -1,7 +1,8 @@
/**
* Copyright (c) 2020 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 David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { CubeFile } from '../../mol-io/reader/cube/parser';
@@ -11,8 +12,9 @@ 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 }): Task<Volume> {
export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number, label?: string, entryId?: string, clamp?: { min: number, max: number } }): Task<Volume> {
return Task.create<Volume>('Create Volume', async () => {
const { header, values: sourceValues } = source;
const space = Tensor.Space(header.dim, [0, 1, 2], Float64Array);
@@ -24,6 +26,7 @@ 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;
@@ -31,7 +34,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++] = sourceValues[s];
values[o++] = clamp(sourceValues[s], min, max);
s += nth;
}
}

View File

@@ -22,7 +22,7 @@ namespace AlignSequences {
score: number
}
export function createSeqIdIndicesMap(element: StructureElement.Loci.Element) {
function createSeqIdIndicesMap(element: StructureElement.Loci.Element) {
const seqIds = new Map<number, StructureElement.UnitIndex[]>();
if (Unit.isAtomic(element.unit)) {
const { label_seq_id } = element.unit.model.atomicHierarchy.residues;
@@ -94,7 +94,7 @@ namespace AlignSequences {
}
}
export function entityKey(unit: Unit) {
function entityKey(unit: Unit) {
switch (unit.kind) {
case Unit.Kind.Atomic:
return unit.model.atomicHierarchy.index.getEntityFromChain(unit.chainIndex[unit.elements[0]]);
@@ -105,6 +105,6 @@ export function entityKey(unit: Unit) {
}
}
export function getSequence(unit: Unit) {
function getSequence(unit: Unit) {
return unit.model.sequence.byEntityKey[entityKey(unit)].sequence;
}

View File

@@ -166,14 +166,6 @@ export interface AtomicIndex {
findResidue(key: AtomicIndex.ResidueKey): ResidueIndex,
findResidue(label_entity_id: string, label_asym_id: string, auth_seq_id: number, pdbx_PDB_ins_code?: string): ResidueIndex,
/**
* Index of the 1st occurence of this residue using "all-label" address.
* Doesn't work for "ligands" as they don't have a label seq id assigned.
* @returns index or -1 if not present.
*/
findResidueLabel(key: AtomicIndex.ResidueLabelKey): ResidueIndex,
/**
* Index of the 1st occurence of this residue.
* @param key.pdbx_PDB_ins_code Empty string for undefined

View File

@@ -124,14 +124,6 @@ class Index implements AtomicIndex {
return rm.has(id) ? rm.get(id)! : -1 as ResidueIndex;
}
findResidueLabel(key: AtomicIndex.ResidueLabelKey): ResidueIndex {
const cI = this.findChainLabel(key);
if (cI < 0) return -1 as ResidueIndex;
const rm = this.map.chain_index_label_seq_id.get(cI)!;
const id = getResidueId(key.label_seq_id, key.pdbx_PDB_ins_code || '');
return rm.has(id) ? rm.get(id)! : -1 as ResidueIndex;
}
findResidueAuth(key: AtomicIndex.ResidueAuthKey): ResidueIndex {
const cI = this.findChainAuth(key);
if (cI < 0) return -1 as ResidueIndex;

View File

@@ -285,10 +285,6 @@ export const AminoAcidNamesD = new Set([
]);
export const AminoAcidNames = SetUtils.unionMany(AminoAcidNamesL, AminoAcidNamesD);
export const CommonProteinCaps = new Set([
'NME', 'ACE'
]);
export const RnaBaseNames = new Set([
'A', 'C', 'T', 'G', 'I', 'U',
'N' // unknown RNA base from CCD

File diff suppressed because one or more lines are too long

View File

@@ -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);
}
}

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2017-2021 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,7 +173,6 @@ 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),

View File

@@ -1224,7 +1224,7 @@ namespace Structure {
const closeUnits = lookup.findUnitIndices(imageCenter[0], imageCenter[1], imageCenter[2], bs.radius + maxRadius);
for (let i = 0; i < closeUnits.count; i++) {
const other = structure.units[closeUnits.indices[i]];
if (other.elements.length > 3 && !Box3D.overlaps(bbox, other.boundary.box)) continue;
if (!Box3D.overlaps(bbox, other.boundary.box)) continue;
if (!validUnit(other) || unit.id >= other.id || !validUnitPair(unit, other)) continue;
if (other.elements.length >= unit.elements.length) callback(unit, other);

View File

@@ -71,8 +71,6 @@ 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];
@@ -82,7 +80,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, operatorA, operatorB } } = indexPairs.bonds;
const { offset, b, edgeProps: { order, distance, flag, key } } = indexPairs.bonds;
const srcA = sourceIndex.value(aI);
const aeI = getElementIdx(type_symbolA.value(aI));
@@ -92,11 +90,6 @@ 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 && opA !== opKeyB) ||
(opB >= 0 && opB !== opKeyB && opB !== opKeyA)) continue;
const beI = getElementIdx(type_symbolA.value(bI));
const d = distance[i];
@@ -249,29 +242,13 @@ function computeInterUnitBonds(structure: Structure, props?: Partial<InterBondCo
(!Unit.isAtomic(a) || mtA[a.residueIndex[a.elements[0]]] !== MoleculeType.Water) &&
(!Unit.isAtomic(b) || mtB[b.residueIndex[b.elements[0]]] !== MoleculeType.Water)
);
const sameModel = a.model === b.model;
const notIonA = (!Unit.isAtomic(a) || mtA[a.residueIndex[a.elements[0]]] !== MoleculeType.Ion) || (sameModel && hasStructConnRecord(a));
const notIonB = (!Unit.isAtomic(b) || mtB[b.residueIndex[b.elements[0]]] !== MoleculeType.Ion) || (sameModel && hasStructConnRecord(b));
const notIon = notIonA && notIonB;
const notIon = (
(!Unit.isAtomic(a) || mtA[a.residueIndex[a.elements[0]]] !== MoleculeType.Ion) &&
(!Unit.isAtomic(b) || mtB[b.residueIndex[b.elements[0]]] !== MoleculeType.Ion)
);
return Structure.validUnitPair(s, a, b) && (notWater || !p.ignoreWater) && (notIon || !p.ignoreIon);
}),
});
}
function hasStructConnRecord(unit: Unit) {
if (!Unit.isAtomic(unit)) return false;
const elements = unit.elements;
const structConn = StructConn.Provider.get(unit.model);
if (structConn) {
for (let i = 0, _i = elements.length; i < _i; i++) {
if (structConn.byAtomIndex.get(elements[i])) {
return true;
}
}
}
return false;
}
export { computeInterUnitBonds };

View File

@@ -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, operatorA, operatorB } } = indexPairs.bonds;
const { offset, b, edgeProps: { order, distance, flag, key } } = indexPairs.bonds;
const { atomSourceIndex: sourceIndex } = unit.model.atomicHierarchy;
const { invertedIndex } = Model.getInvertedAtomSourceIndex(unit.model);
@@ -66,8 +66,6 @@ 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));
@@ -82,10 +80,6 @@ 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];

View File

@@ -64,7 +64,7 @@ export function alignAndSuperpose(xs: StructureElement.Loci[]): AlignAndSuperpos
return ret;
}
export function getPositionTable(xs: StructureElement.Loci, n: number): MinimizeRmsd.Positions {
function getPositionTable(xs: StructureElement.Loci, n: number): MinimizeRmsd.Positions {
const ret = MinimizeRmsd.Positions.empty(n);
let o = 0;
for (const u of xs.elements) {

View File

@@ -124,11 +124,6 @@ export const AnimateModelIndex = PluginStateAnimation.create({
? params.duration.params.durationInS * 1000
: Math.ceil(1000 * traj.data.frameCount / params.duration.params.targetFps);
if (params.mode.name === 'once' && t.current >= durationInMs) {
isEnd = true;
return { modelIndex: traj.data.frameCount - 1 };
}
let phase: number = (t.current % durationInMs) / durationInMs;
if (params.mode.name === 'loop') {
if (params.mode.params.direction === 'backward') {
@@ -140,6 +135,7 @@ export const AnimateModelIndex = PluginStateAnimation.create({
}
const modelIndex = Math.min(Math.floor(traj.data.frameCount * phase), traj.data.frameCount - 1);
isEnd = isEnd || modelIndex === traj.data.frameCount - 1;
return { modelIndex };
}
});

View File

@@ -37,7 +37,6 @@ export namespace StructureRepresentationPresetProvider {
export const CommonParams = {
ignoreHydrogens: PD.Optional(PD.Boolean(false)),
onlyPolarHydrogens: PD.Optional(PD.Boolean(false)),
ignoreLight: PD.Optional(PD.Boolean(false)),
quality: PD.Optional(PD.Select<VisualQuality>('auto', VisualQualityOptions)),
theme: PD.Optional(PD.Group({
@@ -71,13 +70,11 @@ export namespace StructureRepresentationPresetProvider {
const builder = plugin.builders.structure.representation;
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: !plugin.managers.structure.component.state.options.showHydrogens,
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.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

View File

@@ -7,7 +7,7 @@
import { CustomProperty } from '../../mol-model-props/common/custom-property';
import { QueryContext, Structure, StructureQuery, StructureSelection, StructureProperties, StructureElement } from '../../mol-model/structure';
import { BondType, NucleicBackboneAtoms, ProteinBackboneAtoms, SecondaryStructureType, AminoAcidNamesL, RnaBaseNames, DnaBaseNames, WaterNames, ElementSymbol, PolymerNames, CommonProteinCaps } from '../../mol-model/structure/model/types';
import { BondType, NucleicBackboneAtoms, ProteinBackboneAtoms, SecondaryStructureType, AminoAcidNamesL, RnaBaseNames, DnaBaseNames, WaterNames, ElementSymbol, PolymerNames } from '../../mol-model/structure/model/types';
import { PluginContext } from '../../mol-plugin/context';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { Expression } from '../../mol-script/language/expression';
@@ -350,23 +350,14 @@ const ligand = StructureSelectionQuery('Ligand', MS.struct.modifier.union([
])
]),
]),
by: MS.struct.combinator.merge([
MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer']),
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
'residue-test': MS.core.set.has([
MS.set(...SetUtils.toArray(PolymerNames)), MS.ammp('label_comp_id')
])
}),
]),
by: MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer']),
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
'residue-test': MS.core.set.has([
MS.set(...SetUtils.toArray(CommonProteinCaps)),
MS.ammp('label_comp_id'),
]),
}),
MS.set(...SetUtils.toArray(PolymerNames)), MS.ammp('label_comp_id')
])
})
])
})
]), { category: StructureSelectionCategory.Type });

View File

@@ -70,8 +70,7 @@ 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.showHydrogens;
p.ignoreLight = options.ignoreLight;
p.material = options.materialStyle;
p.clip = options.clipObjects;
@@ -81,17 +80,15 @@ 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 { showHydrogens, visualQuality: quality, ignoreLight, materialStyle: material, clipObjects: clip } = this.state.options;
const ignoreHydrogens = !showHydrogens;
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.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.quality = quality;
old.type.params.ignoreLight = ignoreLight;
old.type.params.material = material;
@@ -314,10 +311,9 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone
addRepresentation(components: ReadonlyArray<StructureComponentRef>, type: string) {
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 { showHydrogens, visualQuality: quality, ignoreLight, materialStyle: material, clipObjects: clip } = this.state.options;
const ignoreHydrogens = !showHydrogens;
const typeParams = { ignoreHydrogens, quality, ignoreLight, material, clip };
return this.plugin.dataTransaction(async () => {
for (const component of components) {
@@ -352,10 +348,9 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone
const xs = structures || this.currentStructures;
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 { showHydrogens, visualQuality: quality, ignoreLight, materialStyle: material, clipObjects: clip } = this.state.options;
const ignoreHydrogens = !showHydrogens;
const typeParams = { ignoreHydrogens, quality, ignoreLight, material, clip };
const componentKey = UUID.create22();
for (const s of xs) {
@@ -463,13 +458,9 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone
namespace StructureComponentManager {
export const OptionsParams = {
hydrogens: PD.Select(
'all',
[['all', 'Show All'], ['hide-all', 'Hide All'], ['only-polar', 'Only Polar']] as const,
{ description: 'Determine display of hydrogen atoms in representations' }
),
showHydrogens: PD.Boolean(true, { description: 'Toggle display of hydrogen atoms in representations' }),
visualQuality: PD.Select('auto', VisualQualityOptions, { description: 'Control the visual/rendering quality of representations' }),
ignoreLight: PD.Boolean(false, { description: 'Ignore light for stylized rendering of representations' }),
ignoreLight: PD.Boolean(false, { description: 'Ignore light for stylized rendering of representtions' }),
materialStyle: Material.getParam(),
clipObjects: PD.Group(Clip.Params),
interactions: PD.Group(InteractionsProvider.defaultParams, { label: 'Non-covalent Interactions' }),

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2018-2021 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,7 +43,6 @@ 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 };
@@ -57,7 +56,6 @@ export { SubstanceStructureRepresentation3DFromScript };
export { SubstanceStructureRepresentation3DFromBundle };
export { ClippingStructureRepresentation3DFromScript };
export { ClippingStructureRepresentation3DFromBundle };
export { ThemeStrengthRepresentation3D };
export { VolumeRepresentation3D };
type StructureRepresentation3D = typeof StructureRepresentation3D
@@ -747,62 +745,6 @@ 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 {

View File

@@ -88,12 +88,24 @@ 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, { ...params, label: a.data.name || a.label }).runInContext(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 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);
});

View File

@@ -18,7 +18,7 @@ import { getPrecision } from '../../mol-util/number';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { ParamMapping } from '../../mol-util/param-mapping';
import { camelCaseToWords } from '../../mol-util/string';
import { PluginReactContext, PluginUIComponent } from '../base';
import { PluginUIComponent } from '../base';
import { PluginUIContext } from '../context';
import { ActionMenu } from './action-menu';
import { ColorOptions, ColorValueOption, CombinedColorControl } from './color';
@@ -505,12 +505,10 @@ export class ValueRefControl extends React.PureComponent<ParamProps<PD.ValueRef<
toggle = () => this.setState({ showOptions: !this.state.showOptions });
private get items() {
return ActionMenu.createItemsFromSelectOptions(this.props.param.getOptions(this.context));
}
items = memoizeLatest((param: PD.ValueRef) => ActionMenu.createItemsFromSelectOptions(param.getOptions()));
renderControl() {
const items = this.items;
const items = this.items(this.props.param);
const current = this.props.value.ref ? ActionMenu.findItem(items, this.props.value.ref) : void 0;
const label = current
? current.label
@@ -523,7 +521,7 @@ export class ValueRefControl extends React.PureComponent<ParamProps<PD.ValueRef<
renderAddOn() {
if (!this.state.showOptions) return null;
const items = this.items;
const items = this.items(this.props.param);
const current = ActionMenu.findItem(items, this.props.value.ref);
return <ActionMenu items={items} current={current} onSelect={this.onSelect} />;
@@ -541,7 +539,6 @@ export class ValueRefControl extends React.PureComponent<ParamProps<PD.ValueRef<
});
}
}
ValueRefControl.contextType = PluginReactContext;
export class IntervalControl extends React.PureComponent<ParamProps<PD.Interval>, { isExpanded: boolean }> {
state = { isExpanded: false };

View File

@@ -29,7 +29,7 @@ const MaxDisplaySequenceLength = 5000;
const MaxSelectOptionsCount = 1000;
const MaxSequenceWrappersCount = 30;
export function opKey(l: StructureElement.Location) {
function opKey(l: StructureElement.Location) {
const ids = SP.unit.pdbx_struct_oper_list_ids(l);
const ncs = SP.unit.struct_ncs_oper_id(l);
const hkl = SP.unit.hkl(l);
@@ -37,12 +37,12 @@ export function opKey(l: StructureElement.Location) {
return `${ids.sort().join(',')}|${ncs}|${hkl}|${spgrOp}`;
}
export function splitModelEntityId(modelEntityId: string) {
function splitModelEntityId(modelEntityId: string) {
const [modelIdx, entityId] = modelEntityId.split('|');
return [parseInt(modelIdx), entityId];
}
export function getSequenceWrapper(state: { structure: Structure, modelEntityId: string, chainGroupId: number, operatorKey: string }, structureSelection: StructureSelectionManager): SequenceWrapper.Any | string {
function getSequenceWrapper(state: { structure: Structure, modelEntityId: string, chainGroupId: number, operatorKey: string }, structureSelection: StructureSelectionManager): SequenceWrapper.Any | string {
const { structure, modelEntityId, chainGroupId, operatorKey } = state;
const l = StructureElement.Location.create(structure);
const [modelIdx, entityId] = splitModelEntityId(modelEntityId);
@@ -97,7 +97,7 @@ export function getSequenceWrapper(state: { structure: Structure, modelEntityId:
}
}
export function getModelEntityOptions(structure: Structure, polymersOnly = false): [string, string][] {
function getModelEntityOptions(structure: Structure, polymersOnly = false): [string, string][] {
const options: [string, string][] = [];
const l = StructureElement.Location.create(structure);
const seen = new Set<string>();
@@ -131,7 +131,7 @@ export function getModelEntityOptions(structure: Structure, polymersOnly = false
return options;
}
export function getChainOptions(structure: Structure, modelEntityId: string): [number, string][] {
function getChainOptions(structure: Structure, modelEntityId: string): [number, string][] {
const options: [number, string][] = [];
const l = StructureElement.Location.create(structure);
const seen = new Set<number>();
@@ -161,7 +161,7 @@ export function getChainOptions(structure: Structure, modelEntityId: string): [n
return options;
}
export function getOperatorOptions(structure: Structure, modelEntityId: string, chainGroupId: number): [string, string][] {
function getOperatorOptions(structure: Structure, modelEntityId: string, chainGroupId: number): [string, string][] {
const options: [string, string][] = [];
const l = StructureElement.Location.create(structure);
const seen = new Set<string>();
@@ -189,7 +189,7 @@ export function getOperatorOptions(structure: Structure, modelEntityId: string,
return options;
}
export function getStructureOptions(state: State) {
function getStructureOptions(state: State) {
const options: [string, string][] = [];
const all: Structure[] = [];

View File

@@ -27,21 +27,21 @@ const MaxSequenceNumberSize = 5;
// TODO: this is somewhat inefficient and should be done using a canvas.
export class Sequence<P extends SequenceProps> extends PluginUIComponent<P> {
protected parentDiv = React.createRef<HTMLDivElement>();
protected lastMouseOverSeqIdx = -1;
protected highlightQueue = new Subject<{ seqIdx: number, buttons: number, button: number, modifiers: ModifiersKeys }>();
private parentDiv = React.createRef<HTMLDivElement>();
private lastMouseOverSeqIdx = -1;
private highlightQueue = new Subject<{ seqIdx: number, buttons: number, button: number, modifiers: ModifiersKeys }>();
protected lociHighlightProvider = (loci: Representation.Loci, action: MarkerAction) => {
private lociHighlightProvider = (loci: Representation.Loci, action: MarkerAction) => {
const changed = this.props.sequenceWrapper.markResidue(loci.loci, action);
if (changed) this.updateMarker();
};
protected lociSelectionProvider = (loci: Representation.Loci, action: MarkerAction) => {
private lociSelectionProvider = (loci: Representation.Loci, action: MarkerAction) => {
const changed = this.props.sequenceWrapper.markResidue(loci.loci, action);
if (changed) this.updateMarker();
};
protected get sequenceNumberPeriod() {
private get sequenceNumberPeriod() {
if (this.props.sequenceNumberPeriod !== undefined) {
return this.props.sequenceNumberPeriod as number;
}
@@ -104,7 +104,7 @@ export class Sequence<P extends SequenceProps> extends PluginUIComponent<P> {
e.preventDefault();
};
protected mouseDownLoci: StructureElement.Loci | undefined = undefined;
private mouseDownLoci: StructureElement.Loci | undefined = undefined;
mouseDown = (e: React.MouseEvent) => {
e.stopPropagation();
@@ -148,7 +148,7 @@ export class Sequence<P extends SequenceProps> extends PluginUIComponent<P> {
this.mouseDownLoci = undefined;
};
protected getBackgroundColor(marker: number) {
private getBackgroundColor(marker: number) {
// TODO: make marker color configurable
if (typeof marker === 'undefined') console.error('unexpected marker value');
return marker === 0
@@ -158,17 +158,17 @@ export class Sequence<P extends SequenceProps> extends PluginUIComponent<P> {
: 'rgb(255, 102, 153)'; // highlighted
}
protected getResidueClass(seqIdx: number, label: string) {
private getResidueClass(seqIdx: number, label: string) {
return label.length > 1
? this.props.sequenceWrapper.residueClass(seqIdx) + (seqIdx === 0 ? ' msp-sequence-residue-long-begin' : ' msp-sequence-residue-long')
: this.props.sequenceWrapper.residueClass(seqIdx);
}
protected residue(seqIdx: number, label: string, marker: number) {
private residue(seqIdx: number, label: string, marker: number) {
return <span key={seqIdx} data-seqid={seqIdx} style={{ backgroundColor: this.getBackgroundColor(marker) }} className={this.getResidueClass(seqIdx, label)}>{`\u200b${label}\u200b`}</span>;
}
protected getSequenceNumberClass(seqIdx: number, seqNum: string, label: string) {
private getSequenceNumberClass(seqIdx: number, seqNum: string, label: string) {
const classList = ['msp-sequence-number'];
if (seqNum.startsWith('-')) {
if (label.length > 1 && seqIdx > 0) classList.push('msp-sequence-number-long-negative');
@@ -179,8 +179,8 @@ export class Sequence<P extends SequenceProps> extends PluginUIComponent<P> {
return classList.join(' ');
}
protected location = StructureElement.Location.create(void 0);
protected getSequenceNumber(seqIdx: number) {
private location = StructureElement.Location.create(void 0);
private getSequenceNumber(seqIdx: number) {
let seqNum = '';
const loci = this.props.sequenceWrapper.getLoci(seqIdx);
const l = StructureElement.Loci.getFirstLocation(loci, this.location);
@@ -196,16 +196,16 @@ export class Sequence<P extends SequenceProps> extends PluginUIComponent<P> {
return seqNum;
}
protected padSeqNum(n: string) {
private padSeqNum(n: string) {
if (n.length < MaxSequenceNumberSize) return n + new Array(MaxSequenceNumberSize - n.length + 1).join('\u00A0');
return n;
}
protected getSequenceNumberSpan(seqIdx: number, label: string) {
private getSequenceNumberSpan(seqIdx: number, label: string) {
const seqNum = this.getSequenceNumber(seqIdx);
return <span key={`marker-${seqIdx}`} className={this.getSequenceNumberClass(seqIdx, seqNum, label)}>{this.padSeqNum(seqNum)}</span>;
}
protected updateMarker() {
private updateMarker() {
if (!this.parentDiv.current) return;
const xs = this.parentDiv.current.children;
const { markerArray } = this.props.sequenceWrapper;

View File

@@ -4,7 +4,7 @@
top: 0;
right: 0;
bottom: 0;
background: $default-background;
background: black;
.msp-btn-link {
background: rgba(0,0,0,0.2);

View File

@@ -28,8 +28,7 @@ namespace ApplyActionControl {
params: any,
error?: string,
busy: boolean,
isInitial: boolean,
isCollapsed?: boolean,
isInitial: boolean
}
}
@@ -41,7 +40,7 @@ class ApplyActionControl extends TransformControlBase<ApplyActionControl.Props,
ref: this.props.nodeRef
});
}
getInfo() { return this._getInfo(this.props.nodeRef, this.props.state.transforms.get(this.props.nodeRef).version, this.state?.isCollapsed); }
getInfo() { return this._getInfo(this.props.nodeRef, this.props.state.transforms.get(this.props.nodeRef).version); }
getTransformerId() { return this.props.state.transforms.get(this.props.nodeRef).transformer.id; }
getHeader() { return this.props.hideHeader ? 'none' : this.props.action.definition.display; }
canApply() { return !this.state.error && !this.state.busy; }
@@ -50,9 +49,9 @@ class ApplyActionControl extends TransformControlBase<ApplyActionControl.Props,
isUpdate() { return false; }
getSourceAndTarget() { return { a: this.props.state.cells.get(this.props.nodeRef)!.obj }; }
private _getInfo = memoizeLatest((t: StateTransform.Ref, v: string, collapsed?: boolean) => StateTransformParameters.infoFromAction(this.plugin, this.props.state, this.props.action, this.props.nodeRef));
private _getInfo = memoizeLatest((t: StateTransform.Ref, v: string) => StateTransformParameters.infoFromAction(this.plugin, this.props.state, this.props.action, this.props.nodeRef));
state: ApplyActionControl.ComponentState = { plugin: this.plugin, ref: this.props.nodeRef, version: this.props.state.transforms.get(this.props.nodeRef).version, error: void 0, isInitial: true, params: this.getInfo().initialValues, busy: false, isCollapsed: this.props.initiallyCollapsed };
state = { plugin: this.plugin, ref: this.props.nodeRef, version: this.props.state.transforms.get(this.props.nodeRef).version, error: void 0, isInitial: true, params: this.getInfo().initialValues, busy: false, isCollapsed: this.props.initiallyCollapsed };
static getDerivedStateFromProps(props: ApplyActionControl.Props, state: ApplyActionControl.ComponentState) {
const version = props.state.transforms.get(props.nodeRef).version;

View File

@@ -56,13 +56,12 @@ export class QuickStyles extends PurePluginUIComponent {
postprocessing: {
outline: {
name: 'on',
params: { scale: 1, color: Color(0x000000), threshold: 0.25, includeTransparent: true }
params: { scale: 1, color: Color(0x000000), threshold: 0.25 }
},
occlusion: {
name: 'on',
params: { bias: 0.8, blurKernelSize: 15, radius: 5, samples: 32, resolutionScale: 1 }
},
shadow: { name: 'off', params: {} },
}
});
}
@@ -79,7 +78,7 @@ export class QuickStyles extends PurePluginUIComponent {
name: 'on',
params: pp.outline.name === 'on'
? pp.outline.params
: { scale: 1, color: Color(0x000000), threshold: 0.33, includeTransparent: true }
: { scale: 1, color: Color(0x000000), threshold: 0.33 }
},
occlusion: {
name: 'on',
@@ -87,7 +86,6 @@ export class QuickStyles extends PurePluginUIComponent {
? pp.occlusion.params
: { bias: 0.8, blurKernelSize: 15, radius: 5, samples: 32, resolutionScale: 1 }
},
shadow: { name: 'off', params: {} },
}
});
}

View File

@@ -65,7 +65,7 @@ type SuperpositionControlsState = {
options: StructureSuperpositionOptions
}
export interface LociEntry {
interface LociEntry {
loci: StructureElement.Loci,
label: string,
cell: StateObjectCell<PluginStateObject.Molecule.Structure>

View File

@@ -59,7 +59,6 @@ const SimpleSettingsParams = {
}, { pivot: 'color' }),
lighting: PD.Group({
occlusion: Canvas3DParams.postprocessing.params.occlusion,
shadow: Canvas3DParams.postprocessing.params.shadow,
outline: Canvas3DParams.postprocessing.params.outline,
fog: Canvas3DParams.cameraFog,
}, { isFlat: true }),
@@ -115,7 +114,6 @@ const SimpleSettingsMapping = ParamMapping({
},
lighting: {
occlusion: canvas.postprocessing.occlusion,
shadow: canvas.postprocessing.shadow,
outline: canvas.postprocessing.outline,
fog: canvas.cameraFog,
},
@@ -131,7 +129,6 @@ const SimpleSettingsMapping = ParamMapping({
canvas.transparentBackground = s.background.transparent;
canvas.renderer.backgroundColor = s.background.color;
canvas.postprocessing.occlusion = s.lighting.occlusion;
canvas.postprocessing.shadow = s.lighting.shadow;
canvas.postprocessing.outline = s.lighting.outline;
canvas.postprocessing.background = s.background.style;
canvas.cameraFog = s.lighting.fog;

View File

@@ -52,7 +52,6 @@ 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),
ignoreLight: PD.Boolean(false),
material: Material.getParam(),
clip: PD.Group(Clip.Params),
@@ -81,7 +80,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, ignoreLight: this.params.ignoreLight, material: this.params.material, clip: this.params.clip }
}
};
}

View File

@@ -37,7 +37,6 @@ export const PluginConfig = {
// TODO: check back in a few weeks to see if it was fixed
PreferWebGl1: item('plugin-config.prefer-webgl1', PluginFeatureDetection.preferWebGl1),
AllowMajorPerformanceCaveat: item('plugin-config.allow-major-performance-caveat', false),
PowerPreference: item<WebGLContextAttributes['powerPreference']>('plugin-config.power-preference', 'high-performance'),
},
State: {
DefaultServer: item('plugin-state.server', 'https://webchem.ncbr.muni.cz/molstar-state'),

View File

@@ -267,8 +267,7 @@ export class PluginContext {
const enableDpoit = this.config.get(PluginConfig.General.EnableDpoit) || false;
const preferWebGl1 = this.config.get(PluginConfig.General.PreferWebGl1) || false;
const failIfMajorPerformanceCaveat = !(this.config.get(PluginConfig.General.AllowMajorPerformanceCaveat) ?? false);
const powerPreference = this.config.get(PluginConfig.General.PowerPreference) || 'high-performance';
(this.canvas3dContext as Canvas3DContext) = Canvas3DContext.fromCanvas(canvas, this.managers.asset, { antialias, preserveDrawingBuffer, pixelScale, pickScale, pickPadding, enableWboit, enableDpoit, preferWebGl1, failIfMajorPerformanceCaveat, powerPreference });
(this.canvas3dContext as Canvas3DContext) = Canvas3DContext.fromCanvas(canvas, this.managers.asset, { antialias, preserveDrawingBuffer, pixelScale, pickScale, pickPadding, enableWboit, enableDpoit, preferWebGl1, failIfMajorPerformanceCaveat });
}
(this.canvas3d as Canvas3D) = Canvas3D.create(this.canvas3dContext!);
this.canvas3dInit.next(true);

View File

@@ -104,7 +104,6 @@ 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),

View File

@@ -140,7 +140,7 @@ export class RepresentationRegistry<D, S extends Representation.State> {
//
export { Representation };
interface Representation<D, P extends PD.Params = PD.Params, S extends Representation.State = Representation.State> {
interface Representation<D, P extends PD.Params = {}, S extends Representation.State = Representation.State> {
readonly label: string
readonly updated: Subject<number>
/** Number of addressable groups in all visuals of the representation */
@@ -191,8 +191,6 @@ 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 */
@@ -201,20 +199,7 @@ 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,
themeStrength: { overpaint: 1, transparency: 1, substance: 1 },
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, markerActions: MarkerActions.All };
}
export function updateState(state: State, update: Partial<State>) {
if (update.visible !== undefined) state.visible = update.visible;
@@ -225,7 +210,6 @@ 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;
@@ -236,7 +220,7 @@ namespace Representation {
}
export const StateBuilder: StateBuilder<State> = { create: createState, update: updateState };
export type Any<P extends PD.Params = PD.Params, S extends State = State> = Representation<any, P, S>
export type Any = Representation<any, any, any>
export const Empty: Any = {
label: '', groupCount: 0, renderObjects: [], geometryVersion: -1, props: {}, params: {}, updated: new Subject(), state: createState(), theme: Theme.createEmpty(),
createOrUpdate: () => Task.constant('', undefined),
@@ -248,7 +232,7 @@ namespace Representation {
destroy: () => {}
};
export type Def<D, P extends PD.Params = PD.Params, S extends State = State> = { [k: string]: RepresentationFactory<D, P, S> }
export type Def<D, P extends PD.Params = {}, S extends State = State> = { [k: string]: RepresentationFactory<D, P, S> }
export class GeometryState {
private curr = new Set<number>();
@@ -272,7 +256,7 @@ namespace Representation {
}
}
export function createMulti<D, P extends PD.Params = PD.Params, S extends State = State>(label: string, ctx: RepresentationContext, getParams: RepresentationParamsGetter<D, P>, stateBuilder: StateBuilder<S>, reprDefs: Def<D, P>): Representation<D, P, S> {
export function createMulti<D, P extends PD.Params = {}, S extends State = State>(label: string, ctx: RepresentationContext, getParams: RepresentationParamsGetter<D, P>, stateBuilder: StateBuilder<S>, reprDefs: Def<D, P>): Representation<D, P, S> {
let version = 0;
const updated = new Subject<number>();
const geometryState = new GeometryState();
@@ -448,7 +432,6 @@ 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);

View File

@@ -127,7 +127,6 @@ 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

View File

@@ -299,9 +299,6 @@ 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) {

View File

@@ -1,13 +1,13 @@
/**
* Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { MolecularSurfaceMeshVisual, MolecularSurfaceMeshParams, StructureMolecularSurfaceMeshVisual } from '../visual/molecular-surface-mesh';
import { MolecularSurfaceMeshVisual, MolecularSurfaceMeshParams } from '../visual/molecular-surface-mesh';
import { UnitsRepresentation } from '../units-representation';
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
import { ComplexRepresentation, StructureRepresentation, StructureRepresentationProvider, StructureRepresentationStateBuilder } from '../representation';
import { StructureRepresentation, StructureRepresentationProvider, StructureRepresentationStateBuilder } from '../representation';
import { Representation, RepresentationParamsGetter, RepresentationContext } from '../../../mol-repr/representation';
import { ThemeRegistryContext } from '../../../mol-theme/theme';
import { Structure } from '../../../mol-model/structure';
@@ -16,7 +16,6 @@ import { BaseGeometry } from '../../../mol-geo/geometry/base';
const MolecularSurfaceVisuals = {
'molecular-surface-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, MolecularSurfaceMeshParams>) => UnitsRepresentation('Molecular surface mesh', ctx, getParams, MolecularSurfaceMeshVisual),
'structure-molecular-surface-mesh': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, MolecularSurfaceMeshParams>) => ComplexRepresentation('Structure Molecular surface mesh', ctx, getParams, StructureMolecularSurfaceMeshVisual),
'molecular-surface-wireframe': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, MolecularSurfaceWireframeParams>) => UnitsRepresentation('Molecular surface wireframe', ctx, getParams, MolecularSurfaceWireframeVisual),
};

View File

@@ -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, themeStrength, transform, unitTransforms } = state;
const { visible, alphaFactor, pickable, overpaint, transparency, substance, clipping, transform, unitTransforms } = state;
if (visible !== undefined) visual.setVisibility(visible);
if (alphaFactor !== undefined) visual.setAlphaFactor(alphaFactor);
@@ -231,7 +231,6 @@ 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) {
@@ -244,7 +243,7 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
}
function setState(state: Partial<StructureRepresentationState>) {
const { visible, alphaFactor, pickable, overpaint, transparency, substance, clipping, themeStrength, transform, unitTransforms, syncManually, markerActions } = state;
const { visible, alphaFactor, pickable, overpaint, transparency, substance, clipping, transform, unitTransforms, syncManually, markerActions } = state;
const newState: Partial<StructureRepresentationState> = {};
if (visible !== _state.visible) newState.visible = visible;
@@ -262,7 +261,6 @@ 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;
}

View File

@@ -381,9 +381,6 @@ 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) {

View File

@@ -222,7 +222,6 @@ export function InterUnitBondCylinderImpostorVisual(materialId: number): Complex
newProps.linkScale !== currentProps.linkScale ||
newProps.linkSpacing !== currentProps.linkSpacing ||
newProps.ignoreHydrogens !== currentProps.ignoreHydrogens ||
newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens ||
newProps.linkCap !== currentProps.linkCap ||
newProps.aromaticScale !== currentProps.aromaticScale ||
newProps.aromaticSpacing !== currentProps.aromaticSpacing ||
@@ -265,7 +264,6 @@ export function InterUnitBondCylinderMeshVisual(materialId: number): ComplexVisu
newProps.linkScale !== currentProps.linkScale ||
newProps.linkSpacing !== currentProps.linkSpacing ||
newProps.ignoreHydrogens !== currentProps.ignoreHydrogens ||
newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens ||
newProps.linkCap !== currentProps.linkCap ||
newProps.aromaticScale !== currentProps.aromaticScale ||
newProps.aromaticSpacing !== currentProps.aromaticSpacing ||

View File

@@ -138,7 +138,6 @@ export function InterUnitBondLineVisual(materialId: number): ComplexVisual<Inter
newProps.aromaticDashCount !== currentProps.aromaticDashCount ||
newProps.dashCount !== currentProps.dashCount ||
newProps.ignoreHydrogens !== currentProps.ignoreHydrogens ||
newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens ||
!arrayEqual(newProps.includeTypes, currentProps.includeTypes) ||
!arrayEqual(newProps.excludeTypes, currentProps.excludeTypes) ||
newProps.multipleBonds !== currentProps.multipleBonds

View File

@@ -239,7 +239,6 @@ export function IntraUnitBondCylinderImpostorVisual(materialId: number): UnitsVi
newProps.linkScale !== currentProps.linkScale ||
newProps.linkSpacing !== currentProps.linkSpacing ||
newProps.ignoreHydrogens !== currentProps.ignoreHydrogens ||
newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens ||
newProps.linkCap !== currentProps.linkCap ||
newProps.aromaticScale !== currentProps.aromaticScale ||
newProps.aromaticSpacing !== currentProps.aromaticSpacing ||
@@ -287,7 +286,6 @@ export function IntraUnitBondCylinderMeshVisual(materialId: number): UnitsVisual
newProps.linkScale !== currentProps.linkScale ||
newProps.linkSpacing !== currentProps.linkSpacing ||
newProps.ignoreHydrogens !== currentProps.ignoreHydrogens ||
newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens ||
newProps.linkCap !== currentProps.linkCap ||
newProps.aromaticScale !== currentProps.aromaticScale ||
newProps.aromaticSpacing !== currentProps.aromaticSpacing ||

View File

@@ -164,7 +164,6 @@ export function IntraUnitBondLineVisual(materialId: number): UnitsVisual<IntraUn
newProps.aromaticDashCount !== currentProps.aromaticDashCount ||
newProps.dashCount !== currentProps.dashCount ||
newProps.ignoreHydrogens !== currentProps.ignoreHydrogens ||
newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens ||
!arrayEqual(newProps.includeTypes, currentProps.includeTypes) ||
!arrayEqual(newProps.excludeTypes, currentProps.excludeTypes) ||
newProps.aromaticBonds !== currentProps.aromaticBonds ||

View File

@@ -27,7 +27,6 @@ export const ElementCrossParams = {
...UnitsLinesParams,
lineSizeAttenuation: PD.Boolean(false),
ignoreHydrogens: PD.Boolean(false),
onlyPolarHydrogens: PD.Boolean(false),
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 +85,6 @@ 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.traceOnly !== currentProps.traceOnly ||
newProps.crosses !== currentProps.crosses ||
newProps.crossSize !== currentProps.crossSize

View File

@@ -23,7 +23,6 @@ export const ElementPointParams = {
...UnitsPointsParams,
pointSizeAttenuation: PD.Boolean(false),
ignoreHydrogens: PD.Boolean(false),
onlyPolarHydrogens: PD.Boolean(false),
traceOnly: PD.Boolean(false),
};
export type ElementPointParams = typeof ElementPointParams
@@ -90,7 +89,6 @@ 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.traceOnly !== currentProps.traceOnly
);
}

View File

@@ -20,7 +20,6 @@ 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),
traceOnly: PD.Boolean(false),
tryUseImpostor: PD.Boolean(true),
};
@@ -42,7 +41,6 @@ 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.traceOnly !== currentProps.traceOnly
);
},
@@ -64,7 +62,6 @@ export function ElementSphereMeshVisual(materialId: number): UnitsVisual<Element
newProps.sizeFactor !== currentProps.sizeFactor ||
newProps.detail !== currentProps.detail ||
newProps.ignoreHydrogens !== currentProps.ignoreHydrogens ||
newProps.onlyPolarHydrogens !== currentProps.onlyPolarHydrogens ||
newProps.traceOnly !== currentProps.traceOnly
);
},

View File

@@ -43,7 +43,6 @@ export const GaussianDensityVolumeParams = {
...ComplexDirectVolumeParams,
...GaussianDensityParams,
ignoreHydrogens: PD.Boolean(false),
onlyPolarHydrogens: PD.Boolean(false),
includeParent: PD.Boolean(false, { isHidden: true }),
};
export type GaussianDensityVolumeParams = typeof GaussianDensityVolumeParams
@@ -60,7 +59,6 @@ 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.traceOnly !== currentProps.traceOnly) state.createGeometry = true;
if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true;
},
@@ -101,7 +99,6 @@ export const UnitsGaussianDensityVolumeParams = {
...UnitsDirectVolumeParams,
...GaussianDensityParams,
ignoreHydrogens: PD.Boolean(false),
onlyPolarHydrogens: PD.Boolean(false),
includeParent: PD.Boolean(false, { isHidden: true }),
};
export type UnitsGaussianDensityVolumeParams = typeof UnitsGaussianDensityVolumeParams
@@ -118,7 +115,6 @@ 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.traceOnly !== currentProps.traceOnly) state.createGeometry = true;
if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true;
},

View File

@@ -34,7 +34,6 @@ const SharedParams = {
...GaussianDensityParams,
...ColorSmoothingParams,
ignoreHydrogens: PD.Boolean(false),
onlyPolarHydrogens: PD.Boolean(false),
tryUseGpu: PD.Boolean(true),
includeParent: PD.Boolean(false, { isHidden: true }),
};
@@ -128,7 +127,6 @@ 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.traceOnly !== currentProps.traceOnly) state.createGeometry = true;
if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true;
if (newProps.smoothColors.name !== currentProps.smoothColors.name) {
@@ -195,7 +193,6 @@ 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.traceOnly !== currentProps.traceOnly) state.createGeometry = true;
if (newProps.smoothColors.name !== currentProps.smoothColors.name) {
state.updateColor = true;
@@ -250,7 +247,6 @@ async function createGaussianSurfaceTextureMesh(ctx: VisualContext, unit: Unit,
const boundingSphere = Sphere3D.expand(Sphere3D(), unit.boundary.sphere, densityTextureData.maxRadius);
const surface = TextureMesh.create(gv.vertexCount, groupCount, gv.vertexTexture, gv.groupTexture, gv.normalTexture, boundingSphere, textureMesh);
(surface.meta as GaussianSurfaceMeta).resolution = densityTextureData.resolution;
surface.meta.webgl = ctx.webgl;
return surface;
}
@@ -267,7 +263,6 @@ 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.traceOnly !== currentProps.traceOnly) state.createGeometry = true;
if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true;
if (newProps.smoothColors.name !== currentProps.smoothColors.name) {
@@ -326,7 +321,6 @@ async function createStructureGaussianSurfaceTextureMesh(ctx: VisualContext, str
const boundingSphere = Sphere3D.expand(Sphere3D(), structure.boundary.sphere, densityTextureData.maxRadius);
const surface = TextureMesh.create(gv.vertexCount, groupCount, gv.vertexTexture, gv.groupTexture, gv.normalTexture, boundingSphere, textureMesh);
(surface.meta as GaussianSurfaceMeta).resolution = densityTextureData.resolution;
surface.meta.webgl = ctx.webgl;
return surface;
}
@@ -343,7 +337,6 @@ 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.traceOnly !== currentProps.traceOnly) state.createGeometry = true;
if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true;
if (newProps.smoothColors.name !== currentProps.smoothColors.name) {

View File

@@ -41,7 +41,6 @@ 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),
includeParent: PD.Boolean(false, { isHidden: true }),
};
export type GaussianWireframeParams = typeof GaussianWireframeParams
@@ -58,7 +57,6 @@ 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.traceOnly !== currentProps.traceOnly) state.createGeometry = true;
if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true;
}

View File

@@ -11,9 +11,9 @@ import { VisualContext } from '../../visual';
import { Unit, Structure } from '../../../mol-model/structure';
import { Theme } from '../../../mol-theme/theme';
import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
import { computeStructureMolecularSurface, computeUnitMolecularSurface } from './util/molecular-surface';
import { computeUnitMolecularSurface } from './util/molecular-surface';
import { computeMarchingCubesMesh } from '../../../mol-geo/util/marching-cubes/algorithm';
import { ElementIterator, getElementLoci, eachElement, getSerialElementLoci, eachSerialElement } from './util/element';
import { ElementIterator, getElementLoci, eachElement } from './util/element';
import { VisualUpdateState } from '../../util';
import { CommonSurfaceParams } from './util/common';
import { Sphere3D } from '../../../mol-math/geometry';
@@ -23,7 +23,6 @@ import { WebGLContext } from '../../../mol-gl/webgl/context';
import { applyMeshColorSmoothing } from '../../../mol-geo/geometry/mesh/color-smoothing';
import { ColorSmoothingParams, getColorSmoothingProps } from '../../../mol-geo/geometry/base';
import { ValueCell } from '../../../mol-util';
import { ComplexMeshVisual, ComplexVisual } from '../complex-visual';
export const MolecularSurfaceMeshParams = {
...UnitsMeshParams,
@@ -83,76 +82,6 @@ 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.traceOnly !== currentProps.traceOnly) state.createGeometry = true;
if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true;
if (newProps.smoothColors.name !== currentProps.smoothColors.name) {
state.updateColor = true;
} else if (newProps.smoothColors.name === 'on' && currentProps.smoothColors.name === 'on') {
if (newProps.smoothColors.params.resolutionFactor !== currentProps.smoothColors.params.resolutionFactor) state.updateColor = true;
if (newProps.smoothColors.params.sampleStride !== currentProps.smoothColors.params.sampleStride) state.updateColor = true;
}
},
processValues: (values: MeshValues, geometry: Mesh, props: PD.Values<MolecularSurfaceMeshParams>, theme: Theme, webgl?: WebGLContext) => {
const { resolution, colorTexture } = geometry.meta as MolecularSurfaceMeta;
const csp = getColorSmoothingProps(props.smoothColors, theme.color.preferSmoothing, resolution);
if (csp) {
applyMeshColorSmoothing(values, csp.resolution, csp.stride, webgl, colorTexture);
(geometry.meta as MolecularSurfaceMeta).colorTexture = values.tColorGrid.ref.value;
}
},
dispose: (geometry: Mesh) => {
(geometry.meta as MolecularSurfaceMeta).colorTexture?.destroy();
}
}, materialId);
}
//
async function createStructureMolecularSurfaceMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: MolecularSurfaceMeshProps, mesh?: Mesh): Promise<Mesh> {
const { transform, field, idField, resolution, maxRadius } = await computeStructureMolecularSurface(structure, theme.size, props).runInContext(ctx.runtime);
const params = {
isoLevel: props.probeRadius,
scalarField: field,
idField
};
const surface = await computeMarchingCubesMesh(params, mesh).runAsChild(ctx.runtime);
if (props.includeParent) {
const iterations = Math.ceil(2 / props.resolution);
Mesh.smoothEdges(surface, { iterations, maxNewEdgeLength: Math.sqrt(2) });
}
Mesh.transform(surface, transform);
if (ctx.webgl && !ctx.webgl.isWebGL2) {
Mesh.uniformTriangleGroup(surface);
ValueCell.updateIfChanged(surface.varyingGroup, false);
} else {
ValueCell.updateIfChanged(surface.varyingGroup, true);
}
const sphere = Sphere3D.expand(Sphere3D(), structure.boundary.sphere, maxRadius);
surface.setBoundingSphere(sphere);
(surface.meta as MolecularSurfaceMeta).resolution = resolution;
return surface;
}
export function StructureMolecularSurfaceMeshVisual(materialId: number): ComplexVisual<MolecularSurfaceMeshParams> {
return ComplexMeshVisual<MolecularSurfaceMeshParams>({
defaultProps: PD.getDefaultValues(MolecularSurfaceMeshParams),
createGeometry: createStructureMolecularSurfaceMesh,
createLocationIterator: ElementIterator.fromStructure,
getLoci: getSerialElementLoci,
eachLocation: eachSerialElement,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<MolecularSurfaceMeshParams>, currentProps: PD.Values<MolecularSurfaceMeshParams>) => {
if (newProps.resolution !== currentProps.resolution) state.createGeometry = true;
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.traceOnly !== currentProps.traceOnly) state.createGeometry = true;
if (newProps.includeParent !== currentProps.includeParent) state.createGeometry = true;

View File

@@ -57,7 +57,6 @@ 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.includeParent !== currentProps.includeParent) state.createGeometry = true;
}
}, materialId);

View File

@@ -2,7 +2,6 @@
* 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>
*/
import { BondType } from '../../../../mol-model/structure/model/types';
@@ -15,13 +14,11 @@ 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';
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),
aromaticBonds: PD.Boolean(true, { description: 'Display aromatic bonds with dashes' }),
multipleBonds: PD.Select('symmetric', PD.arrayToOptions(['off', 'symmetric', 'offset'] as const)),
};
@@ -54,7 +51,7 @@ export function makeIntraBondIgnoreTest(structure: Structure, unit: Unit.Atomic,
const { a, b, edgeProps } = bonds;
const { flags: _flags } = edgeProps;
const { ignoreHydrogens, onlyPolarHydrogens, includeTypes, excludeTypes } = props;
const { ignoreHydrogens, includeTypes, excludeTypes } = props;
const include = BondType.fromNames(includeTypes);
const exclude = BondType.fromNames(excludeTypes);
@@ -64,31 +61,14 @@ 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];
const bI = b[edgeIndex];
if ((!!childUnit && !SortedArray.has(childUnit.elements, elements[aI]))) {
return true;
}
if (!allBondTypes && ignoreBondType(include, exclude, _flags[edgeIndex])) {
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;
}
return false;
return (
(!!childUnit && !SortedArray.has(childUnit.elements, elements[a[edgeIndex]])) ||
(ignoreHydrogens && (isH(atomicNumber, elements[a[edgeIndex]]) || isH(atomicNumber, elements[b[edgeIndex]]))) ||
(!allBondTypes && ignoreBondType(include, exclude, _flags[edgeIndex]))
);
};
}
@@ -96,7 +76,7 @@ export function makeInterBondIgnoreTest(structure: Structure, props: BondProps):
const bonds = structure.interUnitBonds;
const { edges } = bonds;
const { ignoreHydrogens, onlyPolarHydrogens, includeTypes, excludeTypes } = props;
const { ignoreHydrogens, includeTypes, excludeTypes } = props;
const include = BondType.fromNames(includeTypes);
const exclude = BondType.fromNames(excludeTypes);
@@ -104,7 +84,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) {
@@ -124,18 +104,6 @@ export function makeInterBondIgnoreTest(structure: Structure, props: BondProps):
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 (!allBondTypes) {
if (ignoreBondType(include, exclude, edges[edgeIndex].props.flag)) return true;
}

View File

@@ -2,7 +2,6 @@
* 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>
*/
import { Unit, Structure, ElementIndex, StructureElement, ResidueIndex } from '../../../../mol-model/structure';
@@ -17,7 +16,6 @@ import { AssignableArrayLike } from '../../../../mol-util/type-helpers';
import { getBoundary } from '../../../../mol-math/geometry/boundary';
import { Box3D } from '../../../../mol-math/geometry';
import { SizeTheme } from '../../../../mol-theme/size';
import { hasPolarNeighbour } from '../../../../mol-model-props/computed/chemistry/functional-group';
/** Return a Loci for the elements of a whole residue the elementIndex belongs to. */
export function getResidueLoci(structure: Structure, unit: Unit.Atomic, elementIndex: ElementIndex): Loci {
@@ -141,7 +139,6 @@ 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.' }),
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.' }),
};
@@ -154,7 +151,7 @@ function squaredDistance(x: number, y: number, z: number, center: Vec3) {
}
/** marks `indices` for filtering/ignoring in `id` when not in `elements` */
function filterUnitId(id: AssignableArrayLike<number>, elements: SortedArray, indices: SortedArray) {
function filterId(id: AssignableArrayLike<number>, elements: SortedArray, indices: SortedArray) {
let start = 0;
const end = elements.length;
for (let i = 0, il = indices.length; i < il; ++i) {
@@ -169,28 +166,26 @@ 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, traceOnly, includeParent } = props;
const rootUnit = includeParent ? structure.root.unitMap.get(unit.id) : unit;
const differentRoot = includeParent && rootUnit !== unit;
const { x, y, z } = getConformation(rootUnit);
const { elements } = rootUnit;
const { center, radius: sphereRadius } = unit.boundary.sphere;
const extraRadius = (4 + 1.5) * 2; // TODO should be twice (the max vdW/sphere radius plus the probe radius)
const extraRadius = (2 + 1.5) * 2; // TODO should be twice (the max vdW/sphere radius plus the probe radius)
const radiusSq = (sphereRadius + extraRadius) * (sphereRadius + extraRadius);
let indices: SortedArray<ElementIndex>;
let id: AssignableArrayLike<number>;
if (ignoreHydrogens || onlyPolarHydrogens || traceOnly || differentRoot) {
const _indices: number[] = [];
const _id: number[] = [];
if (ignoreHydrogens || traceOnly || (includeParent && rootUnit !== unit)) {
const _indices = [];
const _id = [];
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 (traceOnly && !isTrace(rootUnit, eI)) continue;
if (differentRoot && squaredDistance(x[eI], y[eI], z[eI], center) > radiusSq) continue;
if (includeParent && squaredDistance(x[eI], y[eI], z[eI], center) > radiusSq) continue;
_indices.push(eI);
_id.push(i);
@@ -203,11 +198,11 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, s
}
if (includeParent && rootUnit !== unit) {
filterUnitId(id, unit.elements, indices);
filterId(id, unit.elements, indices);
}
const position = { indices, x, y, z, id };
const boundary = differentRoot ? getBoundary(position) : unit.boundary;
const boundary = unit === rootUnit ? unit.boundary : getBoundary(position);
const l = StructureElement.Location.create(structure, rootUnit);
const radius = (index: number) => {
@@ -218,68 +213,43 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, s
return { position, boundary, radius };
}
export function getStructureConformationAndRadius(structure: Structure, sizeTheme: SizeTheme<any>, props: CommonSurfaceProps) {
const { ignoreHydrogens, onlyPolarHydrogens, traceOnly, includeParent } = props;
const differentRoot = includeParent && !!structure.parent;
const l = StructureElement.Location.create(structure.root);
const { center, radius: sphereRadius } = structure.boundary.sphere;
const extraRadius = (4 + 1.5) * 2; // TODO should be twice (the max vdW/sphere radius plus the probe radius)
const radiusSq = (sphereRadius + extraRadius) * (sphereRadius + extraRadius);
export function getStructureConformationAndRadius(structure: Structure, sizeTheme: SizeTheme<any>, ignoreHydrogens: boolean, traceOnly: boolean) {
const l = StructureElement.Location.create(structure);
let xs: ArrayLike<number>;
let ys: ArrayLike<number>;
let zs: ArrayLike<number>;
let rs: ArrayLike<number>;
let id: AssignableArrayLike<number>;
let indices: OrderedSet<number>;
if (ignoreHydrogens || onlyPolarHydrogens || traceOnly || differentRoot) {
const { getSerialIndex } = structure.serialMapping;
const units = differentRoot ? structure.root.units : structure.units;
let id: ArrayLike<number>;
if (ignoreHydrogens || traceOnly) {
const _xs: number[] = [];
const _ys: number[] = [];
const _zs: number[] = [];
const _rs: number[] = [];
const _id: number[] = [];
for (let i = 0, il = units.length; i < il; ++i) {
const unit = units[i];
for (let i = 0, m = 0, il = structure.units.length; i < il; ++i) {
const unit = structure.units[i];
const { elements } = unit;
const { x, y, z } = unit.conformation;
const childUnit = structure.unitMap.get(unit.id);
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 (traceOnly && !isTrace(unit, eI)) continue;
const _x = x(eI), _y = y(eI), _z = z(eI);
if (differentRoot && squaredDistance(_x, _y, _z, center) > radiusSq) continue;
_xs.push(_x);
_ys.push(_y);
_zs.push(_z);
_xs.push(x(eI));
_ys.push(y(eI));
_zs.push(z(eI));
l.element = eI;
_rs.push(sizeTheme.size(l));
if (differentRoot) {
const idx = childUnit ? SortedArray.indexOf(childUnit.elements, eI) : -1;
if (idx === -1) {
_id.push(-2); // mark for filtering/ignoring when not in `elements`
} else {
_id.push(getSerialIndex(childUnit, eI));
}
} else {
_id.push(getSerialIndex(unit, eI));
}
_id.push(m + j);
}
m += elements.length;
}
xs = _xs, ys = _ys, zs = _zs, rs = _rs;
id = _id;
indices = OrderedSet.ofRange(0, id.length);
} else {
const { elementCount } = structure;
const _xs = new Float32Array(elementCount);
@@ -305,14 +275,12 @@ export function getStructureConformationAndRadius(structure: Structure, sizeThem
}
xs = _xs, ys = _ys, zs = _zs, rs = _rs;
id = fillSerial(new Uint32Array(elementCount));
indices = OrderedSet.ofRange(0, id.length);
}
const position = { indices, x: xs, y: ys, z: zs, id };
const boundary = differentRoot ? getBoundary(position) : structure.boundary;
const position = { indices: OrderedSet.ofRange(0, id.length), x: xs, y: ys, z: zs, id };
const radius = (index: number) => rs[index];
return { position, boundary, radius };
return { position, radius };
}
const _H = AtomicNumbers['H'];

View File

@@ -21,14 +21,12 @@ import { Spheres } from '../../../../mol-geo/geometry/spheres/spheres';
import { SpheresBuilder } from '../../../../mol-geo/geometry/spheres/spheres-builder';
import { isTrace, isH, StructureGroup } 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,
traceOnly: boolean,
}
@@ -38,7 +36,7 @@ export type ElementSphereMeshProps = {
} & ElementProps
export function makeElementIgnoreTest(structure: Structure, unit: Unit, props: ElementProps): undefined | ((i: ElementIndex) => boolean) {
const { ignoreHydrogens, onlyPolarHydrogens, traceOnly } = props;
const { ignoreHydrogens, traceOnly } = props;
const { atomicNumber } = unit.model.atomicHierarchy.derived.atom;
const isCoarse = Unit.isCoarse(unit);
@@ -47,26 +45,14 @@ export function makeElementIgnoreTest(structure: Structure, unit: Unit, props: E
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 && isH(atomicNumber, element)) ||
(traceOnly && !isTrace(unit, element))
);
};
}

View File

@@ -1,5 +1,5 @@
/**
* Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
@@ -34,51 +34,56 @@ export function getTextureMaxCells(webgl: WebGLContext, structure?: Structure) {
//
export function computeUnitGaussianDensity(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: GaussianDensityProps) {
const { position, boundary, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, props);
const p = ensureReasonableResolution(boundary.box, props);
const { box } = unit.lookup3d.boundary;
const p = ensureReasonableResolution(box, props);
const { position, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, p);
return Task.create('Gaussian Density', async ctx => {
return await GaussianDensityCPU(ctx, position, boundary.box, radius, p);
return await GaussianDensityCPU(ctx, position, box, radius, p);
});
}
export function computeUnitGaussianDensityTexture(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
const { position, boundary, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, props);
const p = ensureReasonableResolution(boundary.box, props, getTextureMaxCells(webgl, structure));
const { box } = unit.lookup3d.boundary;
const p = ensureReasonableResolution(box, props, getTextureMaxCells(webgl, structure));
const { position, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, p);
return Task.create('Gaussian Density', async ctx => {
return GaussianDensityTexture(webgl, position, boundary.box, radius, p, texture);
return GaussianDensityTexture(webgl, position, box, radius, p, texture);
});
}
export function computeUnitGaussianDensityTexture2d(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, powerOfTwo: boolean, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
const { position, boundary, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, props);
const p = ensureReasonableResolution(boundary.box, props, getTextureMaxCells(webgl, structure));
const { box } = unit.lookup3d.boundary;
const p = ensureReasonableResolution(box, props, getTextureMaxCells(webgl, structure));
const { position, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, p);
return Task.create('Gaussian Density', async ctx => {
return GaussianDensityTexture2d(webgl, position, boundary.box, radius, powerOfTwo, p, texture);
return GaussianDensityTexture2d(webgl, position, box, radius, powerOfTwo, p, texture);
});
}
//
export function computeStructureGaussianDensity(structure: Structure, sizeTheme: SizeTheme<any>, props: GaussianDensityProps) {
const { position, boundary, radius } = getStructureConformationAndRadius(structure, sizeTheme, props);
const p = ensureReasonableResolution(boundary.box, props);
const { box } = structure.lookup3d.boundary;
const p = ensureReasonableResolution(box, props);
const { position, radius } = getStructureConformationAndRadius(structure, sizeTheme, props.ignoreHydrogens, props.traceOnly);
return Task.create('Gaussian Density', async ctx => {
return await GaussianDensityCPU(ctx, position, boundary.box, radius, p);
return await GaussianDensityCPU(ctx, position, box, radius, p);
});
}
export function computeStructureGaussianDensityTexture(structure: Structure, sizeTheme: SizeTheme<any>, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
const { position, boundary, radius } = getStructureConformationAndRadius(structure, sizeTheme, props);
const p = ensureReasonableResolution(boundary.box, props);
const { box } = structure.lookup3d.boundary;
const p = ensureReasonableResolution(box, props, getTextureMaxCells(webgl));
const { position, radius } = getStructureConformationAndRadius(structure, sizeTheme, props.ignoreHydrogens, props.traceOnly);
return Task.create('Gaussian Density', async ctx => {
return GaussianDensityTexture(webgl, position, boundary.box, radius, p, texture);
return GaussianDensityTexture(webgl, position, box, radius, p, texture);
});
}
export function computeStructureGaussianDensityTexture2d(structure: Structure, sizeTheme: SizeTheme<any>, powerOfTwo: boolean, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
const { box } = structure.lookup3d.boundary;
const { position, boundary, radius } = getStructureConformationAndRadius(structure, sizeTheme, props);
const p = ensureReasonableResolution(boundary.box, props);
const p = ensureReasonableResolution(box, props, getTextureMaxCells(webgl));
const { position, radius } = getStructureConformationAndRadius(structure, sizeTheme, props.ignoreHydrogens, props.traceOnly);
return Task.create('Gaussian Density', async ctx => {
return GaussianDensityTexture2d(webgl, position, box, radius, powerOfTwo, p, texture);
});

View File

@@ -1,12 +1,12 @@
/**
* Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Unit, Structure } from '../../../../mol-model/structure';
import { Task, RuntimeContext } from '../../../../mol-task';
import { getUnitConformationAndRadius, CommonSurfaceProps, ensureReasonableResolution, getStructureConformationAndRadius } from './common';
import { getUnitConformationAndRadius, CommonSurfaceProps, ensureReasonableResolution } from './common';
import { PositionData, DensityData, Box3D } from '../../../../mol-math/geometry';
import { MolecularSurfaceCalculationProps, calcMolecularSurface } from '../../../../mol-math/geometry/molecular-surface';
import { OrderedSet } from '../../../../mol-data/int';
@@ -15,7 +15,7 @@ import { SizeTheme } from '../../../../mol-theme/size';
export type MolecularSurfaceProps = MolecularSurfaceCalculationProps & CommonSurfaceProps
function getUnitPositionDataAndMaxRadius(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: MolecularSurfaceProps) {
function getPositionDataAndMaxRadius(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: MolecularSurfaceProps) {
const { probeRadius } = props;
const { position, boundary, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, props);
const { indices } = position;
@@ -34,38 +34,11 @@ function getUnitPositionDataAndMaxRadius(structure: Structure, unit: Unit, sizeT
}
export function computeUnitMolecularSurface(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: MolecularSurfaceProps) {
const { position, boundary, maxRadius } = getUnitPositionDataAndMaxRadius(structure, unit, sizeTheme, props);
const p = ensureReasonableResolution(boundary.box, props);
const { box } = unit.lookup3d.boundary;
const p = ensureReasonableResolution(box, props);
const { position, boundary, maxRadius } = getPositionDataAndMaxRadius(structure, unit, sizeTheme, p);
return Task.create('Molecular Surface', async ctx => {
return await MolecularSurface(ctx, position, boundary, maxRadius, boundary.box, p);
});
}
//
function getStructurePositionDataAndMaxRadius(structure: Structure, sizeTheme: SizeTheme<any>, props: MolecularSurfaceProps) {
const { probeRadius } = props;
const { position, boundary, radius } = getStructureConformationAndRadius(structure, sizeTheme, props);
const { indices } = position;
const n = OrderedSet.size(indices);
const radii = new Float32Array(OrderedSet.end(indices));
let maxRadius = 0;
for (let i = 0; i < n; ++i) {
const j = OrderedSet.getAt(indices, i);
const r = radius(j);
if (maxRadius < r) maxRadius = r;
radii[j] = r + probeRadius;
}
return { position: { ...position, radius: radii }, boundary, maxRadius };
}
export function computeStructureMolecularSurface(structure: Structure, sizeTheme: SizeTheme<any>, props: MolecularSurfaceProps) {
const { position, boundary, maxRadius } = getStructurePositionDataAndMaxRadius(structure, sizeTheme, props);
const p = ensureReasonableResolution(boundary.box, props);
return Task.create('Molecular Surface', async ctx => {
return await MolecularSurface(ctx, position, boundary, maxRadius, boundary.box, p);
return await MolecularSurface(ctx, position, boundary, maxRadius, box, p);
});
}

View File

@@ -75,7 +75,7 @@ export type QualityThresholds = typeof DefaultQualityThresholds
export function getStructureQuality(structure: Structure, tresholds: Partial<QualityThresholds> = {}): VisualQuality {
const t = { ...DefaultQualityThresholds, ...tresholds };
let score = structure.elementCount * t.elementCountFactor;
if (structure.isCoarseGrained || structure.isCoarse) score *= t.coarseGrainedFactor;
if (structure.isCoarseGrained) score *= t.coarseGrainedFactor;
if (score > t.lowestElementCount) {
return 'lowest';
} else if (score > t.lowerElementCount) {

View File

@@ -55,7 +55,6 @@ 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
}
@@ -350,14 +349,6 @@ 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;

View File

@@ -201,7 +201,6 @@ async function createVolumeIsosurfaceTextureMesh(ctx: VisualContext, volume: Vol
const groupCount = volume.grid.cells.data.length;
const surface = TextureMesh.create(gv.vertexCount, groupCount, gv.vertexTexture, gv.groupTexture, gv.normalTexture, Volume.getBoundingSphere(volume), textureMesh);
surface.meta.webgl = ctx.webgl;
return surface;
}

View File

@@ -252,9 +252,6 @@ 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) {

View File

@@ -273,7 +273,6 @@ 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.')
},

View File

@@ -299,7 +299,6 @@ 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) => {

Some files were not shown because too many files have changed in this diff Show More