Compare commits

...

24 Commits

Author SHA1 Message Date
Alexander Rose
4d0f0ceebf 3.0.0-dev.3 2021-12-04 22:23:51 -08:00
Alexander Rose
14abcddfcf changelog 2021-12-04 22:17:24 -08:00
Alexander Rose
704cc96a9f Merge pull request #300 from sukolsak/fix-export
Fix USDZ and OBJ export
2021-12-04 22:13:41 -08:00
Sukolsak Sakshuwong
b51f610173 fix USDZ and OBJ export 2021-12-04 20:08:15 -08:00
dsehnal
470280ea1a changelog and update eslint 2021-12-01 13:29:02 +01:00
dsehnal
dafb5a8299 3.0.0-dev.2 2021-12-01 13:26:08 +01:00
dsehnal
4a1af03744 package.json fix 2021-12-01 13:23:50 +01:00
dsehnal
bb176f1efb 3.0.0-dev.1 2021-12-01 13:17:15 +01:00
dsehnal
a53bcde973 npmignore tweaks 2021-12-01 13:14:28 +01:00
David Sehnal
1a8dc2c637 Merge pull request #295 from molstar/material-object
Refactor Material Representation
2021-11-29 18:04:52 +01:00
dsehnal
f96211ff91 comment 2021-11-29 18:04:23 +01:00
dsehnal
77f9c02785 udpate presets 2021-11-29 18:01:41 +01:00
dsehnal
7910b65fdc Merge branch 'master' of https://github.com/molstar/molstar 2021-11-29 14:49:53 +01:00
dsehnal
eb4fc4588d remove console.log 2021-11-29 14:49:51 +01:00
David Sehnal
5430674071 Merge pull request #294 from MadCatX/fixtypo
Fix typo in README
2021-11-29 14:10:20 +01:00
dsehnal
17e67e3b79 Refactor Material representation 2021-11-29 14:09:56 +01:00
dsehnal
e87a0d72e4 Fix docking viewer material usage 2021-11-29 12:48:26 +01:00
dsehnal
67d3c65907 ParamDefinition.Group.presets support 2021-11-29 12:35:57 +01:00
dsehnal
564a5486c9 StructureComponentManager.Options state saving support 2021-11-29 11:57:37 +01:00
Michal Malý
9ce11c4c32 Fix typo in README 2021-11-29 11:41:57 +01:00
dsehnal
5e97b551a5 changelog 2021-11-29 11:10:30 +01:00
David Sehnal
77536e75af Merge pull request #292 from MadCatX/provide-rebuild-cmd
Add packaging command to force a full rebuild
2021-11-29 11:05:44 +01:00
Michal Malý
3a6ab55266 Add a cleanup packaging script 2021-11-28 22:29:50 +01:00
Michal Malý
aaec452bc2 Add packaging command to force a full rebuild 2021-11-28 13:28:06 +01:00
18 changed files with 233 additions and 150 deletions

View File

@@ -1 +1,5 @@
lib/tsconfig.commonjs.tsbuildinfo
tests
perf-tests
_spec
*.tsbuildinfo
*.js.map

View File

@@ -6,11 +6,22 @@ Note that since we don't clearly distinguish between a public and private interf
## [Unreleased]
## [v3.0.0-dev.3] - 2021-12-4
- Fix OBJ and USDZ export
## [v3.0.0-dev.2] - 2021-12-1
- Do not include tests and source maps in NPM package
## [v3.0.0-dev.0] - 2021-11-28
- Add multiple lights support (with color, intensity, and direction parameters)
- [Breaking] Add per-object material rendering properties
- ``SimpleSettingsParams.lighting.renderStyle`` and ``RendererParams.style`` were removed
- Add substance theme with per-group material rendering properties
- ``StructureComponentManager.Options`` state saving support
- ``ParamDefinition.Group.presets`` support
## [v2.4.1] - 2021-11-28

View File

@@ -68,6 +68,17 @@ If working on just the viewer, ``npm run watch-viewer`` will provide shorter com
Debug/production mode in browsers can be turned on/off during runtime by calling ``setMolStarDebugMode(true/false, true/false)`` from the dev console.
### Cleaning and forcing a full rebuild
npm run clean
Wipes the `build` and `lib` directories and `.tsbuildinfo` files.
npm run rebuild
Runs the cleanup script prior to building the project, forcing a full rebuild of the project.
Use these commands to resolve occassional build failures which may arise after some dependency updates. Once done, `npm run build` should work again. Note that full rebuilds take more time to complete.
### Build for production:
NODE_ENV=production npm run build

144
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "molstar",
"version": "3.0.0-dev.0",
"version": "3.0.0-dev.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "molstar",
"version": "3.0.0-dev.0",
"version": "3.0.0-dev.3",
"license": "MIT",
"dependencies": {
"@types/argparse": "^2.0.10",
@@ -56,8 +56,8 @@
"@types/cors": "^2.8.12",
"@types/gl": "^4.1.0",
"@types/jest": "^27.0.3",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@typescript-eslint/eslint-plugin": "^5.5.0",
"@typescript-eslint/parser": "^5.5.0",
"benchmark": "^2.1.4",
"concurrently": "^6.4.0",
"cpx2": "^4.0.0",
@@ -2885,13 +2885,13 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz",
"integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==",
"dev": true,
"dependencies": {
"@typescript-eslint/experimental-utils": "5.4.0",
"@typescript-eslint/scope-manager": "5.4.0",
"@typescript-eslint/experimental-utils": "5.5.0",
"@typescript-eslint/scope-manager": "5.5.0",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
@@ -2917,15 +2917,15 @@
}
},
"node_modules/@typescript-eslint/experimental-utils": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz",
"integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz",
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.4.0",
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/typescript-estree": "5.4.0",
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/typescript-estree": "5.5.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
},
@@ -2941,14 +2941,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz",
"integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.4.0",
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/typescript-estree": "5.4.0",
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/typescript-estree": "5.5.0",
"debug": "^4.3.2"
},
"engines": {
@@ -2968,13 +2968,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz",
"integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz",
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/visitor-keys": "5.4.0"
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/visitor-keys": "5.5.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -2985,9 +2985,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz",
"integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz",
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -2998,13 +2998,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz",
"integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz",
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/visitor-keys": "5.4.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/visitor-keys": "5.5.0",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
@@ -3025,12 +3025,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz",
"integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz",
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/types": "5.5.0",
"eslint-visitor-keys": "^3.0.0"
},
"engines": {
@@ -16064,13 +16064,13 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz",
"integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "5.4.0",
"@typescript-eslint/scope-manager": "5.4.0",
"@typescript-eslint/experimental-utils": "5.5.0",
"@typescript-eslint/scope-manager": "5.5.0",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
@@ -16080,55 +16080,55 @@
}
},
"@typescript-eslint/experimental-utils": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz",
"integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz",
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.4.0",
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/typescript-estree": "5.4.0",
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/typescript-estree": "5.5.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
}
},
"@typescript-eslint/parser": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz",
"integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.4.0",
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/typescript-estree": "5.4.0",
"@typescript-eslint/scope-manager": "5.5.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/typescript-estree": "5.5.0",
"debug": "^4.3.2"
}
},
"@typescript-eslint/scope-manager": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz",
"integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz",
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/visitor-keys": "5.4.0"
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/visitor-keys": "5.5.0"
}
},
"@typescript-eslint/types": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz",
"integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz",
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz",
"integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz",
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/visitor-keys": "5.4.0",
"@typescript-eslint/types": "5.5.0",
"@typescript-eslint/visitor-keys": "5.5.0",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
@@ -16137,12 +16137,12 @@
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz",
"integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==",
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz",
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.4.0",
"@typescript-eslint/types": "5.5.0",
"eslint-visitor-keys": "^3.0.0"
}
},

View File

@@ -1,6 +1,6 @@
{
"name": "molstar",
"version": "3.0.0-dev.0",
"version": "3.0.0-dev.3",
"description": "A comprehensive macromolecular library.",
"homepage": "https://github.com/molstar/molstar#readme",
"repository": {
@@ -16,6 +16,8 @@
"test": "npm run lint && jest",
"jest": "jest",
"build": "npm run build-tsc && npm run build-extra && npm run build-webpack",
"clean": "node ./scripts/clean.js",
"rebuild": "npm run clean && npm run build",
"build-viewer": "npm run build-tsc && npm run build-extra && npm run build-webpack-viewer",
"build-tsc": "concurrently \"tsc --incremental\" \"tsc --build tsconfig.commonjs.json --incremental\"",
"build-extra": "cpx \"src/**/*.{scss,html,ico}\" lib/",
@@ -36,7 +38,7 @@
"volume-server-test": "node lib/commonjs/servers/volume/server.js --idMap em 'test/${id}.mdb' --defaultPort 1336",
"plugin-state": "node lib/commonjs/servers/plugin-state/index.js --working-folder ./build/state --port 1339",
"preversion": "npm run test",
"version": "npm run build",
"version": "npm run rebuild && cpx .npmignore lib/",
"postversion": "git push && git push --tags"
},
"files": [
@@ -98,8 +100,8 @@
"@types/cors": "^2.8.12",
"@types/gl": "^4.1.0",
"@types/jest": "^27.0.3",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@typescript-eslint/eslint-plugin": "^5.5.0",
"@typescript-eslint/parser": "^5.5.0",
"benchmark": "^2.1.4",
"concurrently": "^6.4.0",
"cpx2": "^4.0.0",

19
scripts/clean.js Normal file
View File

@@ -0,0 +1,19 @@
/**
* Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Michal Malý <malym@ibt.cas.cz>
*/
const fs = require('fs');
const path = require('path');
const toClean = [
path.resolve(__dirname, '../build'),
path.resolve(__dirname, '../lib'),
path.resolve(__dirname, '../tsconfig.tsbuildinfo'),
];
toClean.forEach(ph => {
if (fs.existsSync(ph))
fs.rm(ph, { recursive: true }, err => { if (err) console.warn(`Failed to delete ${ph}: ${err}`); });
});

View File

@@ -21,6 +21,7 @@ import { PluginContext } from '../../mol-plugin/context';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { StateObjectRef } from '../../mol-state';
import { Color } from '../../mol-util/color';
import { Material } from '../../mol-util/material';
function shinyStyle(plugin: PluginContext) {
return PluginCommands.Canvas3D.SetSettings(plugin, { settings: {
@@ -75,7 +76,7 @@ const PresetParams = {
...StructureRepresentationPresetProvider.CommonParams,
};
const CustomMaterial = Material({ roughness: 0.2, metalness: 0 });
export const StructurePreset = StructureRepresentationPresetProvider({
id: 'preset-structure',
@@ -92,8 +93,8 @@ export const StructurePreset = StructureRepresentationPresetProvider({
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
const representations = {
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, roughness: 0.2, sizeFactor: 0.35 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
polymer: builder.buildRepresentation(update, components.polymer, { type: 'cartoon', typeParams: { ...typeParams, roughness: 0.2 }, color: 'chain-id', colorParams: { palette: (plugin.customState as any).colorPalette } }, { tag: 'polymer' }),
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, material: CustomMaterial, sizeFactor: 0.35 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
polymer: builder.buildRepresentation(update, components.polymer, { type: 'cartoon', typeParams: { ...typeParams, material: CustomMaterial }, color: 'chain-id', colorParams: { palette: (plugin.customState as any).colorPalette } }, { tag: 'polymer' }),
};
await update.commit({ revertOnError: true });
@@ -147,8 +148,8 @@ const SurfacePreset = StructureRepresentationPresetProvider({
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
const representations = {
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, roughness: 0.2, sizeFactor: 0.26 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
polymer: builder.buildRepresentation(update, components.polymer, { type: 'molecular-surface', typeParams: { ...typeParams, roughness: 0.2, quality: 'custom', resolution: 0.5, doubleSided: true }, color: 'partial-charge' }, { tag: 'polymer' }),
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, material: CustomMaterial, sizeFactor: 0.26 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
polymer: builder.buildRepresentation(update, components.polymer, { type: 'molecular-surface', typeParams: { ...typeParams, material: CustomMaterial, quality: 'custom', resolution: 0.5, doubleSided: true }, color: 'partial-charge' }, { tag: 'polymer' }),
};
await update.commit({ revertOnError: true });
@@ -175,8 +176,8 @@ const PocketPreset = StructureRepresentationPresetProvider({
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
const representations = {
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, roughness: 0.2, sizeFactor: 0.26 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
surroundings: builder.buildRepresentation(update, components.surroundings, { type: 'molecular-surface', typeParams: { ...typeParams, roughness: 0.2, includeParent: true, quality: 'custom', resolution: 0.2, doubleSided: true }, color: 'partial-charge' }, { tag: 'surroundings' }),
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, material: CustomMaterial, sizeFactor: 0.26 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
surroundings: builder.buildRepresentation(update, components.surroundings, { type: 'molecular-surface', typeParams: { ...typeParams, material: CustomMaterial, includeParent: true, quality: 'custom', resolution: 0.2, doubleSided: true }, color: 'partial-charge' }, { tag: 'surroundings' }),
};
await update.commit({ revertOnError: true });
@@ -204,10 +205,10 @@ const InteractionsPreset = StructureRepresentationPresetProvider({
const { update, builder, typeParams } = StructureRepresentationPresetProvider.reprBuilder(plugin, params);
const representations = {
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, roughness: 0.2, sizeFactor: 0.3 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
ballAndStick: builder.buildRepresentation(update, components.surroundings, { type: 'ball-and-stick', typeParams: { ...typeParams, roughness: 0.2, sizeFactor: 0.1, sizeAspectRatio: 1 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ball-and-stick' }),
interactions: builder.buildRepresentation(update, components.interactions, { type: InteractionsRepresentationProvider, typeParams: { ...typeParams, roughness: 0.2 }, color: InteractionTypeColorThemeProvider }, { tag: 'interactions' }),
label: builder.buildRepresentation(update, components.surroundings, { type: 'label', typeParams: { ...typeParams, roughness: 0.2, background: false, borderWidth: 0.1 }, color: 'uniform', colorParams: { value: Color(0x000000) } }, { tag: 'label' }),
ligand: builder.buildRepresentation(update, components.ligand, { type: 'ball-and-stick', typeParams: { ...typeParams, material: CustomMaterial, sizeFactor: 0.3 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ligand' }),
ballAndStick: builder.buildRepresentation(update, components.surroundings, { type: 'ball-and-stick', typeParams: { ...typeParams, material: CustomMaterial, sizeFactor: 0.1, sizeAspectRatio: 1 }, color: 'element-symbol', colorParams: { carbonColor: { name: 'element-symbol', params: {} } } }, { tag: 'ball-and-stick' }),
interactions: builder.buildRepresentation(update, components.interactions, { type: InteractionsRepresentationProvider, typeParams: { ...typeParams, material: CustomMaterial }, color: InteractionTypeColorThemeProvider }, { tag: 'interactions' }),
label: builder.buildRepresentation(update, components.surroundings, { type: 'label', typeParams: { ...typeParams, material: CustomMaterial, background: false, borderWidth: 0.1 }, color: 'uniform', colorParams: { value: Color(0x000000) } }, { tag: 'label' }),
};
await update.commit({ revertOnError: true });

View File

@@ -145,7 +145,7 @@ export class ObjExporter extends MeshExporter<ObjData> {
const color = ObjExporter.getColor(v, geoData, interpolatedColors, interpolatedOverpaint);
Color.toArray(color, quantizedColors, i);
}
ObjExporter.quantizeColors(quantizedColors, mesh!.vertexCount);
ObjExporter.quantizeColors(quantizedColors, vertexCount);
// face
for (let i = 0; i < drawCount; i += 3) {

View File

@@ -149,7 +149,7 @@ def Material "material${materialKey}"
const color = UsdzExporter.getColor(v, geoData, interpolatedColors, interpolatedOverpaint);
Color.toArray(color, quantizedColors, i);
}
UsdzExporter.quantizeColors(quantizedColors, mesh!.vertexCount);
UsdzExporter.quantizeColors(quantizedColors, vertexCount);
// material
const faceIndicesByMaterial = new Map<number, number[]>();

View File

@@ -97,24 +97,22 @@ export namespace BaseGeometry {
}
export function createValues(props: PD.Values<Params>, counts: Counts) {
const { metalness, roughness } = Material.toObjectNormalized(props.material);
return {
alpha: ValueCell.create(props.alpha),
uAlpha: ValueCell.create(props.alpha),
uVertexCount: ValueCell.create(counts.vertexCount),
uGroupCount: ValueCell.create(counts.groupCount),
drawCount: ValueCell.create(counts.drawCount),
uMetalness: ValueCell.create(metalness),
uRoughness: ValueCell.create(roughness),
uMetalness: ValueCell.create(props.material.metalness),
uRoughness: ValueCell.create(props.material.roughness),
dLightCount: ValueCell.create(1),
};
}
export function updateValues(values: BaseValues, props: PD.Values<Params>) {
const { metalness, roughness } = Material.toObjectNormalized(props.material);
ValueCell.updateIfChanged(values.alpha, props.alpha); // `uAlpha` is set in renderable.render
ValueCell.updateIfChanged(values.uMetalness, metalness);
ValueCell.updateIfChanged(values.uRoughness, roughness);
ValueCell.updateIfChanged(values.uMetalness, props.material.metalness);
ValueCell.updateIfChanged(values.uRoughness, props.material.roughness);
}
export function createRenderableState(props: Partial<PD.Values<Params>> = {}): RenderableState {

View File

@@ -18,7 +18,7 @@ import { Material } from '../../mol-util/material';
type SubstanceEachReprCallback = (update: StateBuilder.Root, repr: StateObjectCell<PluginStateObject.Molecule.Structure.Representation3D, StateTransform<typeof StateTransforms.Representation.StructureRepresentation3D>>, substance?: StateObjectCell<any, StateTransform<typeof StateTransforms.Representation.SubstanceStructureRepresentation3DFromBundle>>) => Promise<void>
const SubstanceManagerTag = 'substance-controls';
export async function setStructureSubstance(plugin: PluginContext, components: StructureComponentRef[], material: Material | -1, lociGetter: (structure: Structure) => Promise<StructureElement.Loci | EmptyLoci>, types?: string[]) {
export async function setStructureSubstance(plugin: PluginContext, components: StructureComponentRef[], material: Material | undefined, lociGetter: (structure: Structure) => Promise<StructureElement.Loci | EmptyLoci>, types?: string[]) {
await eachRepr(plugin, components, async (update, repr, substanceCell) => {
if (types && types.length > 0 && !types.includes(repr.params!.values.type.name)) return;
@@ -30,8 +30,8 @@ export async function setStructureSubstance(plugin: PluginContext, components: S
const layer = {
bundle: StructureElement.Bundle.fromLoci(loci),
material: material === -1 ? Material(0) : material,
clear: material === -1
material: material ?? Material(),
clear: !material
};
if (substanceCell) {

View File

@@ -388,7 +388,7 @@ class StructureComponentManager extends StatefulPluginComponent<StructureCompone
const p = params.action.params;
await setStructureSubstance(this.plugin, s.components, p.material, getLoci, params.representations);
} else if (params.action.name === 'resetMaterial') {
await setStructureSubstance(this.plugin, s.components, -1, getLoci, params.representations);
await setStructureSubstance(this.plugin, s.components, void 0, getLoci, params.representations);
} else if (params.action.name === 'clipping') {
const p = params.action.params;
await setStructureClipping(this.plugin, s.components, Clipping.Groups.fromNames(p.excludeGroups), getLoci, params.representations);

View File

@@ -547,7 +547,7 @@ const SubstanceStructureRepresentation3DFromScript = PluginStateTransform.BuiltI
}, e => `${e.clear ? 'Clear' : Material.toString(e.material)}`, {
defaultValue: [{
script: Script('(sel.atom.all)', 'mol-script'),
material: Material.fromNormalized(0, 1),
material: Material({ roughness: 1 }),
clear: false
}]
}),
@@ -604,7 +604,7 @@ const SubstanceStructureRepresentation3DFromBundle = PluginStateTransform.BuiltI
}, e => `${e.clear ? 'Clear' : Material.toString(e.material)}`, {
defaultValue: [{
bundle: StructureElement.Bundle.Empty,
material: Material.fromNormalized(0, 1),
material: Material({ roughness: 1 }),
clear: false
}],
isHidden: true

View File

@@ -19,7 +19,7 @@ import { PluginUIComponent } from '../base';
import { ActionMenu } from './action-menu';
import { ColorOptions, ColorValueOption, CombinedColorControl } from './color';
import { Button, ControlGroup, ControlRow, ExpandGroup, IconButton, TextInput, ToggleButton } from './common';
import { Icon, HelpOutlineSvg, CheckSvg, ClearSvg, BookmarksOutlinedSvg, MoreHorizSvg, ArrowDropDownSvg, ArrowRightSvg, ArrowDownwardSvg, ArrowUpwardSvg, DeleteOutlinedSvg } from './icons';
import { Icon, HelpOutlineSvg, CheckSvg, ClearSvg, BookmarksOutlinedSvg, MoreHorizSvg, ArrowDropDownSvg, ArrowRightSvg, ArrowDownwardSvg, ArrowUpwardSvg, DeleteOutlinedSvg, TuneSvg } from './icons';
import { legendFor } from './legend';
import { LineGraphComponent } from './line-graph/line-graph-component';
import { Slider, Slider2 } from './slider';
@@ -1079,8 +1079,8 @@ export class MultiSelectControl extends React.PureComponent<ParamProps<PD.MultiS
}
}
export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>> & { inMapped?: boolean }, { isExpanded: boolean, showHelp: boolean }> {
state = { isExpanded: !!this.props.param.isExpanded, showHelp: false }
export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>> & { inMapped?: boolean }, { isExpanded: boolean, showPresets: boolean, showHelp: boolean }> {
state = { isExpanded: !!this.props.param.isExpanded, showPresets: false, showHelp: false }
change(value: any) {
this.props.onChange({ name: this.props.name, param: this.props.param, value });
@@ -1091,6 +1091,29 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>
}
toggleExpanded = () => this.setState({ isExpanded: !this.state.isExpanded });
toggleShowPresets = () => this.setState({ showPresets: !this.state.showPresets });
presetItems = memoizeLatest((param: PD.Group<any>) => ActionMenu.createItemsFromSelectOptions(param.presets ?? []));
onSelectPreset: ActionMenu.OnSelect = item => {
this.setState({ showPresets: false });
this.change(item?.value);
}
presets() {
if (!this.props.param.presets) return null;
const label = this.props.param.label || camelCaseToWords(this.props.name);
return <div className='msp-control-group-wrapper'>
<div className='msp-control-group-header'>
<button className='msp-btn msp-form-control msp-btn-block' onClick={this.toggleShowPresets}>
<Icon svg={TuneSvg} />
{label} Presets
</button>
</div>
{this.state.showPresets && <ActionMenu items={this.presetItems(this.props.param)} onSelect={this.onSelectPreset} />}
</div>;
}
pivoted() {
const key = this.props.param.pivot as string;
@@ -1116,6 +1139,7 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>
{ctrl}
<IconButton svg={MoreHorizSvg} onClick={this.toggleExpanded} toggleState={this.state.isExpanded} title={`More Options`} />
<div className='msp-control-offset'>
{this.presets()}
<ParameterControls params={filtered} onEnter={this.props.onEnter} values={this.props.value} onChange={this.onChangeParam} isDisabled={this.props.isDisabled} />
</div>
</div>;
@@ -1149,6 +1173,7 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>
</button>
</div>
{this.state.isExpanded && <div className='msp-control-offset'>
{this.presets()}
{controls}
</div>}
</div>;

View File

@@ -20,6 +20,7 @@ import { merge } from 'rxjs';
import { PluginContext } from './context';
import { PluginComponent } from '../mol-plugin-state/component';
import { PluginConfig } from './config';
import { StructureComponentManager } from '../mol-plugin-state/manager/structure/component';
export { PluginState };
@@ -64,6 +65,9 @@ class PluginState extends PluginComponent {
canvas3d: p.canvas3d ? { props: this.plugin.canvas3d?.props } : void 0,
interactivity: p.interactivity ? { props: this.plugin.managers.interactivity.props } : void 0,
structureFocus: this.plugin.managers.structure.focus.getSnapshot(),
structureComponentManager: p.componentManager ? {
options: this.plugin.managers.structure.component.state.options
} : void 0,
durationInMs: p?.durationInMs
};
}
@@ -71,6 +75,8 @@ class PluginState extends PluginComponent {
async setSnapshot(snapshot: PluginState.Snapshot) {
await this.animation.stop();
// this needs to go 1st since these changes are already baked into the behavior and data state
if (snapshot.structureComponentManager?.options) await this.plugin.managers.structure.component.setOptions(snapshot.structureComponentManager?.options);
if (snapshot.behaviour) await this.plugin.runTask(this.behaviors.setSnapshot(snapshot.behaviour));
if (snapshot.data) await this.plugin.runTask(this.data.setSnapshot(snapshot.data));
if (snapshot.canvas3d?.props) {
@@ -139,6 +145,7 @@ namespace PluginState {
durationInMs: PD.Numeric(1500, { min: 100, max: 15000, step: 100 }, { label: 'Duration in ms' }),
data: PD.Boolean(true),
behavior: PD.Boolean(false),
componentManager: PD.Boolean(true),
animation: PD.Boolean(true),
startAnimation: PD.Boolean(false),
canvas3d: PD.Boolean(true),
@@ -172,6 +179,9 @@ namespace PluginState {
props?: InteractivityManager.Props
},
structureFocus?: StructureFocusSnapshot,
structureComponentManager?: {
options?: StructureComponentManager.Options
},
durationInMs?: number
}

View File

@@ -8,6 +8,7 @@ import { Loci } from '../mol-model/loci';
import { Structure, StructureElement } from '../mol-model/structure';
import { Script } from '../mol-script/script';
import { Material } from '../mol-util/material';
import { shallowEqual } from '../mol-util/object';
export { Substance };
@@ -26,7 +27,7 @@ namespace Substance {
if (sA.layers.length !== sB.layers.length) return false;
for (let i = 0, il = sA.layers.length; i < il; ++i) {
if (sA.layers[i].clear !== sB.layers[i].clear) return false;
if (sA.layers[i].material !== sB.layers[i].material) return false;
if (!shallowEqual(sA.layers[i].material, sB.layers[i].material)) return false;
if (!Loci.areEqual(sA.layers[i].loci, sB.layers[i].loci)) return false;
}
return true;
@@ -51,25 +52,32 @@ namespace Substance {
export function merge(substance: Substance): Substance {
if (isEmpty(substance)) return substance;
const { structure } = substance.layers[0].loci;
const map = new Map<Material | -1, StructureElement.Loci>();
let clearLoci: StructureElement.Loci | undefined = void 0;
const map = new Map<Material, StructureElement.Loci>();
let shadowed = StructureElement.Loci.none(structure);
for (let i = 0, il = substance.layers.length; i < il; ++i) {
let { loci, material, clear } = substance.layers[il - i - 1]; // process from end
loci = StructureElement.Loci.subtract(loci, shadowed);
shadowed = StructureElement.Loci.union(loci, shadowed);
if (!StructureElement.Loci.isEmpty(loci)) {
const materialOrClear = clear ? -1 : material;
if (map.has(materialOrClear)) {
loci = StructureElement.Loci.union(loci, map.get(materialOrClear)!);
if (clear) {
clearLoci = clearLoci
? StructureElement.Loci.union(loci, clearLoci)
: loci;
} else {
if (map.has(material)) {
loci = StructureElement.Loci.union(loci, map.get(material)!);
}
map.set(material, loci);
}
map.set(materialOrClear, loci);
}
}
const layers: Substance.Layer[] = [];
map.forEach((loci, materialOrClear) => {
const clear = materialOrClear === -1;
const material = clear ? Material(0) : materialOrClear;
layers.push({ loci, material, clear });
if (clearLoci) {
layers.push({ loci: clearLoci, material: Material(), clear: true });
}
map.forEach((loci, material) => {
layers.push({ loci, material, clear: false });
});
return { layers };
}

View File

@@ -6,51 +6,43 @@
import { NumberArray } from './type-helpers';
import { ParamDefinition as PD } from './param-definition';
import { toFixed } from './number';
/** Material properties expressed as a single number */
export type Material = { readonly '@type': 'material' } & number
export interface Material {
/** Normalized to [0, 1] range */
metalness: number,
/** Normalized to [0, 1] range */
roughness: number
}
export function Material(hex: number) { return hex as Material; }
export function Material(values?: Partial<Material>) {
return { ...Material.Zero, ...values };
}
export namespace Material {
export function fromNormalized(metalness: number, roughness: number): Material {
return (((metalness * 255) << 16) | ((roughness * 255) << 8)) as Material;
}
export function fromObjectNormalized(v: { metalness: number, roughness: number }): Material {
return fromNormalized(v.metalness, v.roughness);
}
export function toObjectNormalized(material: Material, fractionDigits?: number) {
const metalness = (material >> 16 & 255) / 255;
const roughness = (material >> 8 & 255) / 255;
return {
metalness: fractionDigits ? toFixed(metalness, fractionDigits) : metalness,
roughness: fractionDigits ? toFixed(roughness, fractionDigits) : roughness
};
}
export const Zero: Material = { metalness: 0, roughness: 0 };
export function toArray(material: Material, array: NumberArray, offset: number) {
array[offset] = (material >> 16 & 255);
array[offset + 1] = (material >> 8 & 255);
array[offset] = material.metalness * 255;
array[offset + 1] = material.roughness * 255;
return array;
}
export function toString(material: Material) {
const metalness = (material >> 16 & 255) / 255;
const roughness = (material >> 8 & 255) / 255;
return `M ${metalness} | R ${roughness}`;
export function toString({ metalness, roughness }: Material) {
return `M ${metalness.toFixed(2)} | R ${roughness.toFixed(2)}`;
}
export function getParam(info?: { isExpanded?: boolean, isFlat?: boolean }) {
return PD.Converted(
(v: Material) => toObjectNormalized(v, 2),
(v: { metalness: number, roughness: number }) => fromObjectNormalized(v),
PD.Group({
metalness: PD.Numeric(0, { min: 0, max: 1, step: 0.01 }),
roughness: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }),
}, info)
);
return PD.Group({
metalness: PD.Numeric(0, { min: 0, max: 1, step: 0.01 }),
roughness: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }),
}, {
...info,
presets: [
[{ metalness: 0, roughness: 1 }, 'Matte'],
[{ metalness: 0, roughness: 0.2 }, 'Plastic'],
[{ metalness: 0, roughness: 0.6 }, 'Glossy'],
[{ metalness: 1.0, roughness: 0.6 }, 'Metallic'],
]
});
}
}

View File

@@ -225,12 +225,14 @@ export namespace ParamDefinition {
export interface Group<T> extends Base<T> {
type: 'group',
params: Params,
presets?: Select<T>['options'],
isExpanded?: boolean,
isFlat?: boolean,
pivot?: keyof T
}
export function Group<T>(params: For<T>, info?: Info & { isExpanded?: boolean, isFlat?: boolean, customDefault?: any, pivot?: keyof T }): Group<Normalize<T>> {
export function Group<T>(params: For<T>, info?: Info & { isExpanded?: boolean, isFlat?: boolean, customDefault?: any, pivot?: keyof T, presets?: Select<T>['options'] }): Group<Normalize<T>> {
const ret = setInfo<Group<Normalize<T>>>({ type: 'group', defaultValue: info?.customDefault || getDefaultValues(params as any as Params) as any, params: params as any as Params }, info);
if (info?.presets) ret.presets = info.presets;
if (info?.isExpanded) ret.isExpanded = info.isExpanded;
if (info?.isFlat) ret.isFlat = info.isFlat;
if (info?.pivot) ret.pivot = info.pivot as any;