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
69 changed files with 1469 additions and 2910 deletions

View File

@@ -6,41 +6,18 @@ Note that since we don't clearly distinguish between a public and private interf
## [Unreleased]
## [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

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.26.0",
"version": "3.23.0",
"description": "A comprehensive macromolecular library.",
"homepage": "https://github.com/molstar/molstar#readme",
"repository": {
@@ -92,58 +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>"
"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",
@@ -152,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,14 +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),
} },
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) } },
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

@@ -606,15 +606,6 @@ 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: {

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

@@ -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');
@@ -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
@@ -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,
@@ -72,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'),
@@ -265,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'),
@@ -283,22 +221,19 @@ const PostprocessingSchema = {
dOcclusionEnable: DefineSpec('boolean'),
uOcclusionOffset: UniformSpec('v2'),
dShadowEnable: DefineSpec('boolean'),
dOutlineEnable: DefineSpec('boolean'),
dOutlineScale: DefineSpec('number'),
uOutlineThreshold: UniformSpec('f'),
};
type PostprocessingRenderable = ComputeRenderable<Values<typeof PostprocessingSchema>>
function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, depthTextureOpaque: Texture, depthTextureTransparent: Texture, shadowsTexture: Texture, outlinesTexture: Texture, ssaoDepthTexture: Texture): 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())),
@@ -316,8 +251,6 @@ 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),
@@ -341,15 +274,6 @@ 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 }),
@@ -365,12 +289,11 @@ 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 isOutlineEnabled(props: PostprocessingProps) {
@@ -382,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;
@@ -430,9 +350,6 @@ export class PostprocessingPass {
this.outlinesTarget = webgl.createRenderTarget(width, height, false);
this.outlinesRenderable = getOutlinesRenderable(webgl, depthTextureOpaque, depthTextureTransparent);
this.shadowsTarget = webgl.createRenderTarget(width, height, false);
this.shadowsRenderable = getShadowsRenderable(webgl, depthTextureOpaque);
this.ssaoFramebuffer = webgl.resources.framebuffer();
this.ssaoBlurFirstPassFramebuffer = webgl.resources.framebuffer();
this.ssaoBlurSecondPassFramebuffer = webgl.resources.framebuffer();
@@ -456,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);
this.renderable = getPostprocessingRenderable(webgl, colorTarget.texture, depthTextureOpaque, depthTextureTransparent, this.outlinesTarget.texture, this.ssaoDepthTexture);
this.background = new BackgroundPass(webgl, assetManager, width, height);
}
@@ -472,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));
@@ -489,28 +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;
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),
@@ -582,38 +494,6 @@ 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 } = props.outline.params;
// orthographic needs lower threshold
@@ -642,18 +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 (needsUpdateShadows) {
this.shadowsRenderable.update();
}
if (needsUpdateSsao) {
this.ssaoRenderable.update();
}
@@ -691,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

@@ -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

@@ -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

@@ -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

@@ -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;
@@ -121,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

@@ -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

@@ -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];

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

@@ -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

@@ -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

@@ -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

@@ -62,7 +62,6 @@ export class QuickStyles extends PurePluginUIComponent {
name: 'on',
params: { bias: 0.8, blurKernelSize: 15, radius: 5, samples: 32, resolutionScale: 1 }
},
shadow: { name: 'off', params: {} },
}
});
}
@@ -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

@@ -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

@@ -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

@@ -247,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;
}
@@ -322,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;
}

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,
@@ -105,72 +104,4 @@ export function MolecularSurfaceMeshVisual(materialId: number): UnitsVisual<Mole
(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.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);
}

View File

@@ -151,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) {
@@ -168,25 +168,24 @@ function filterUnitId(id: AssignableArrayLike<number>, elements: SortedArray, in
export function getUnitConformationAndRadius(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: CommonSurfaceProps) {
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 || 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 (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);
@@ -199,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) => {
@@ -214,36 +213,25 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, s
return { position, boundary, radius };
}
export function getStructureConformationAndRadius(structure: Structure, sizeTheme: SizeTheme<any>, props: CommonSurfaceProps) {
const { ignoreHydrogens, 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 || 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) {
@@ -251,30 +239,17 @@ export function getStructureConformationAndRadius(structure: Structure, sizeThem
if (ignoreHydrogens && isHydrogen(unit, eI)) 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);
@@ -300,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

@@ -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) => {

View File

@@ -1,8 +1,7 @@
/**
* Copyright (c) 2018-2022 Mol* contributors, licensed under MIT, See LICENSE file for more info.
* Copyright (c) 2018 Mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { UniqueArray } from '../../../mol-data/generic';
@@ -206,7 +205,6 @@ export const SymbolTable = [
Alias(MolScript.structureQuery.atomProperty.core.z, 'atom.z'),
Alias(MolScript.structureQuery.atomProperty.core.sourceIndex, 'atom.src-index'),
Alias(MolScript.structureQuery.atomProperty.core.operatorName, 'atom.op-name'),
Alias(MolScript.structureQuery.atomProperty.core.operatorKey, 'atom.op-key'),
Alias(MolScript.structureQuery.atomProperty.core.modelIndex, 'atom.model-index'),
Alias(MolScript.structureQuery.atomProperty.core.modelLabel, 'atom.model-label'),
Alias(MolScript.structureQuery.atomProperty.core.atomKey, 'atom.key'),
@@ -255,7 +253,6 @@ export const SymbolTable = [
'Bond Properties',
Alias(MolScript.structureQuery.bondProperty.order, 'bond.order'),
Alias(MolScript.structureQuery.bondProperty.length, 'bond.length'),
Alias(MolScript.structureQuery.bondProperty.key, 'bond.key'),
Alias(MolScript.structureQuery.bondProperty.atomA, 'bond.atom-a'),
Alias(MolScript.structureQuery.bondProperty.atomB, 'bond.atom-b'),
Macro(MSymbol('bond.is', Arguments.List(StructureQueryTypes.BondFlag), Type.Bool,

View File

@@ -40,7 +40,6 @@ import { VolumeValueColorThemeProvider } from './color/volume-value';
import { Vec3, Vec4 } from '../mol-math/linear-algebra';
import { ModelIndexColorThemeProvider } from './color/model-index';
import { StructureIndexColorThemeProvider } from './color/structure-index';
import { ExternalVolumeColorThemeProvider } from './color/external-volume';
export type LocationColor = (location: Location, isSecondary: boolean) => Color
@@ -153,7 +152,6 @@ namespace ColorTheme {
'unit-index': UnitIndexColorThemeProvider,
'uniform': UniformColorThemeProvider,
'volume-value': VolumeValueColorThemeProvider,
'external-volume': ExternalVolumeColorThemeProvider,
};
type _BuiltIn = typeof BuiltIn
export type BuiltIn = keyof _BuiltIn

View File

@@ -1,159 +0,0 @@
/**
* Copyright (c) 2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { Color, ColorScale } from '../../mol-util/color';
import { Location } from '../../mol-model/location';
import { ColorTheme } from '../color';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { ThemeDataContext } from '../theme';
import { Grid, Volume } from '../../mol-model/volume';
import { type PluginContext } from '../../mol-plugin/context';
import { isPositionLocation } from '../../mol-geo/util/location-iterator';
import { Mat4, Vec3 } from '../../mol-math/linear-algebra';
import { lerp } from '../../mol-math/interpolate';
const Description = `Assigns a color based volume value at a given vertex.`;
export const ExternalVolumeColorThemeParams = {
volume: PD.ValueRef<Volume>(
(ctx: PluginContext) => {
const volumes = ctx.state.data.selectQ(q => q.root.subtree().filter(c => Volume.is(c.obj?.data)));
return volumes.map(v => [v.transform.ref, v.obj?.label ?? '<unknown>'] as [string, string]);
},
(ref, getData) => getData(ref),
),
coloring: PD.MappedStatic('absolute-value', {
'absolute-value': PD.Group({
domain: PD.MappedStatic('auto', {
custom: PD.Interval([-1, 1]),
auto: PD.Group({
symmetric: PD.Boolean(false, { description: 'If true the automatic range is determined as [-|max|, |max|].' })
})
}),
list: PD.ColorList('red-white-blue', { presetKind: 'scale' })
}),
'relative-value': PD.Group({
domain: PD.MappedStatic('auto', {
custom: PD.Interval([-1, 1]),
auto: PD.Group({
symmetric: PD.Boolean(false, { description: 'If true the automatic range is determined as [-|max|, |max|].' })
})
}),
list: PD.ColorList('red-white-blue', { presetKind: 'scale' })
})
}),
defaultColor: PD.Color(Color(0xcccccc)),
};
export type ExternalVolumeColorThemeParams = typeof ExternalVolumeColorThemeParams
export function ExternalVolumeColorTheme(ctx: ThemeDataContext, props: PD.Values<ExternalVolumeColorThemeParams>): ColorTheme<ExternalVolumeColorThemeParams> {
let volume: Volume | undefined;
try {
volume = props.volume.getValue();
} catch {
// .getValue() is resolved during state reconciliation => would throw from UI
}
// NOTE: this will currently be slow for with GPU/texture meshes due to slow iteration
// TODO: create texture to be able to do the sampling on the GPU
let color;
if (volume) {
const coloring = props.coloring.params;
const { stats } = volume.grid;
const domain: [number, number] = coloring.domain.name === 'custom' ? coloring.domain.params : [stats.min, stats.max];
const isRelative = props.coloring.name === 'relative-value';
if (coloring.domain.name === 'auto' && isRelative) {
domain[0] = (domain[0] - stats.mean) / stats.sigma;
domain[1] = (domain[1] - stats.mean) / stats.sigma;
}
if (props.coloring.params.domain.name === 'auto' && props.coloring.params.domain.params.symmetric) {
const max = Math.max(Math.abs(domain[0]), Math.abs(domain[1]));
domain[0] = -max;
domain[1] = max;
}
const scale = ColorScale.create({ domain, listOrName: coloring.list.colors });
const cartnToGrid = Grid.getGridToCartesianTransform(volume.grid);
Mat4.invert(cartnToGrid, cartnToGrid);
const gridCoords = Vec3();
const { dimensions, get } = volume.grid.cells.space;
const data = volume.grid.cells.data;
const [mi, mj, mk] = dimensions;
color = (location: Location): Color => {
if (!isPositionLocation(location)) {
return props.defaultColor;
}
Vec3.copy(gridCoords, location.position);
Vec3.transformMat4(gridCoords, gridCoords, cartnToGrid);
const i = Math.floor(gridCoords[0]);
const j = Math.floor(gridCoords[1]);
const k = Math.floor(gridCoords[2]);
if (i < 0 || i >= mi || j < 0 || j >= mj || k < 0 || k >= mk) {
return props.defaultColor;
}
const u = gridCoords[0] - i;
const v = gridCoords[1] - j;
const w = gridCoords[2] - k;
// Tri-linear interpolation for the value
const ii = Math.min(i + 1, mi - 1);
const jj = Math.min(j + 1, mj - 1);
const kk = Math.min(k + 1, mk - 1);
let a = get(data, i, j, k);
let b = get(data, ii, j, k);
let c = get(data, i, jj, k);
let d = get(data, ii, jj, k);
const x = lerp(lerp(a, b, u), lerp(c, d, u), v);
a = get(data, i, j, kk);
b = get(data, ii, j, kk);
c = get(data, i, jj, kk);
d = get(data, ii, jj, kk);
const y = lerp(lerp(a, b, u), lerp(c, d, u), v);
let value = lerp(x, y, w);
if (isRelative) {
value = (value - stats.mean) / stats.sigma;
}
return scale.color(value);
};
} else {
color = () => props.defaultColor;
}
return {
factory: ExternalVolumeColorTheme,
granularity: 'vertex',
preferSmoothing: true,
color,
props,
description: Description,
// TODO: figure out how to do legend for this
};
}
export const ExternalVolumeColorThemeProvider: ColorTheme.Provider<ExternalVolumeColorThemeParams, 'external-volume'> = {
name: 'external-volume',
label: 'External Volume',
category: ColorTheme.Category.Misc,
factory: ExternalVolumeColorTheme,
getParams: () => ExternalVolumeColorThemeParams,
defaultValues: PD.getDefaultValues(ExternalVolumeColorThemeParams),
isApplicable: (ctx: ThemeDataContext) => true,
};

View File

@@ -290,9 +290,9 @@ export namespace ParamDefinition {
// getValue needs to be assigned by a runtime because it might not be serializable
export interface ValueRef<T = any> extends Base<{ ref: string, getValue: () => T }> {
type: 'value-ref',
resolveRef: (ref: string, getData: (ref: string) => any) => T,
resolveRef: (ref: string) => T,
// a provider because the list changes over time
getOptions: (ctx: any) => Select<string>['options'],
getOptions: () => Select<string>['options'],
}
export function ValueRef<T>(getOptions: ValueRef['getOptions'], resolveRef: ValueRef<T>['resolveRef'], info?: Info & { defaultRef?: string }) {
return setInfo<ValueRef<T>>({ type: 'value-ref', defaultValue: { ref: info?.defaultRef ?? '', getValue: unsetGetValue as any }, getOptions, resolveRef }, info);
@@ -365,8 +365,8 @@ export namespace ParamDefinition {
return d as Values<T>;
}
function _resolveRef(resolve: (ref: string, getData: (ref: string) => any) => any, ref: string, getData: (ref: string) => any) {
return () => resolve(ref, getData);
function _resolveRef(resolve: (ref: string) => any, ref: string) {
return () => resolve(ref);
}
function resolveRefValue(p: Any, value: any, getData: (ref: string) => any) {
@@ -375,11 +375,11 @@ export namespace ParamDefinition {
if (p.type === 'value-ref') {
const v = value as ValueRef['defaultValue'];
if (!v.ref) v.getValue = () => { throw new Error('Unset ref in ValueRef value.'); };
else v.getValue = _resolveRef(p.resolveRef, v.ref, getData);
else v.getValue = _resolveRef(p.resolveRef, v.ref);
} else if (p.type === 'data-ref') {
const v = value as ValueRef['defaultValue'];
if (!v.ref) v.getValue = () => { throw new Error('Unset ref in ValueRef value.'); };
else v.getValue = _resolveRef(getData, v.ref, getData);
else v.getValue = _resolveRef(getData, v.ref);
} else if (p.type === 'group') {
resolveRefs(p.params, value, getData);
} else if (p.type === 'mapped') {