@ccp-nc/crystvis-js 0.4.13 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +0 -0
- package/.github/workflows/test-mocha.yml +1 -1
- package/.vscode/settings.json +1 -2
- package/LICENSE +0 -0
- package/README.html +0 -0
- package/README.md +2 -2
- package/demo/index.html +14 -0
- package/demo/main.js +12 -0
- package/docs/.nojekyll +0 -0
- package/docs-tutorials/Events.md +0 -0
- package/docs-tutorials/Queries.md +0 -0
- package/fonts/OpenSans/OFL.txt +93 -0
- package/fonts/OpenSans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- package/fonts/OpenSans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
- package/fonts/OpenSans/README.txt +100 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-Bold.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-BoldItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-ExtraBold.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-ExtraBoldItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-Italic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-Light.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-LightItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-Medium.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-MediumItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-Regular.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-SemiBold.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans/OpenSans-SemiBoldItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Bold.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-BoldItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-ExtraBold.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-ExtraBoldItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Italic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Light.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-LightItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Medium.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-MediumItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Regular.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-SemiBold.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-SemiBoldItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Bold.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-BoldItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-ExtraBold.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-ExtraBoldItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Italic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Light.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-LightItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Medium.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-MediumItalic.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Regular.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-SemiBold.ttf +0 -0
- package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-SemiBoldItalic.ttf +0 -0
- package/fonts/Rubik/OFL.txt +0 -0
- package/fonts/Rubik/README.txt +0 -0
- package/fonts/Rubik/Rubik-Italic-VariableFont_wght.ttf +0 -0
- package/fonts/Rubik/Rubik-VariableFont_wght.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Black.ttf +0 -0
- package/fonts/Rubik/static/Rubik-BlackItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Bold.ttf +0 -0
- package/fonts/Rubik/static/Rubik-BoldItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-ExtraBold.ttf +0 -0
- package/fonts/Rubik/static/Rubik-ExtraBoldItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Italic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Light.ttf +0 -0
- package/fonts/Rubik/static/Rubik-LightItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Medium.ttf +0 -0
- package/fonts/Rubik/static/Rubik-MediumItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Regular.ttf +0 -0
- package/fonts/Rubik/static/Rubik-SemiBold.ttf +0 -0
- package/fonts/Rubik/static/Rubik-SemiBoldItalic.ttf +0 -0
- package/index.html +0 -0
- package/index.js +0 -0
- package/jsconf.json +0 -0
- package/lib/assets/fonts/OpenSans-Medium.fnt +157 -0
- package/lib/assets/fonts/OpenSans-Medium.png +0 -0
- package/lib/assets/fonts/Rubik-Medium.fnt +141 -89
- package/lib/assets/fonts/Rubik-Medium.png +0 -0
- package/lib/assets/fonts/bmpfonts.in.js +6 -1
- package/lib/assets/fonts/bmpfonts.js +10 -2
- package/lib/assets/fonts/font.js +0 -0
- package/lib/assets/fonts/index.js +4 -2
- package/lib/assets/fonts/threebmfont.js +0 -0
- package/lib/data.js +0 -0
- package/lib/formats/cell.js +26 -3
- package/lib/formats/cif.js +1 -1
- package/lib/formats/magres.js +37 -3
- package/lib/formats/xyz.js +7 -2
- package/lib/loader.js +0 -0
- package/lib/model.js +83 -8
- package/lib/modelview.js +35 -0
- package/lib/nmrdata.js +0 -0
- package/lib/primitives/atoms.js +0 -0
- package/lib/primitives/cell.js +25 -3
- package/lib/primitives/dither.js +0 -0
- package/lib/primitives/ellipsoid.js +29 -9
- package/lib/primitives/geometries.js +0 -0
- package/lib/primitives/isosurface.js +0 -0
- package/lib/primitives/shapes.js +0 -0
- package/lib/primitives/sprites.js +2 -2
- package/lib/query.js +0 -0
- package/lib/render.js +107 -5
- package/lib/selbox.js +0 -0
- package/lib/shaders/aura.frag +0 -0
- package/lib/shaders/aura.vert +0 -0
- package/lib/shaders/dither.frag +0 -0
- package/lib/shaders/dither.vert +0 -0
- package/lib/shaders/index.in.js +0 -0
- package/lib/shaders/index.js +0 -0
- package/lib/shaders/msdf300.frag +0 -0
- package/lib/shaders/msdf300.vert +0 -0
- package/lib/tensor.js +1 -1
- package/lib/utils.js +22 -1
- package/lib/visualizer.js +95 -4
- package/package.json +18 -18
- package/scripts/build-bundle.js +0 -0
- package/scripts/build-fonts.js +8 -3
- package/scripts/build-resources.js +0 -0
- package/scripts/plugins-shim.js +0 -0
- package/test/chemdata.js +1 -1
- package/test/data/CHA.cif +0 -0
- package/test/data/H2O.xyz +0 -0
- package/test/data/H2_bound.xyz +0 -0
- package/test/data/bohr.cell +11 -0
- package/test/data/ethanol.cell +0 -0
- package/test/data/example_single.cif +0 -0
- package/test/data/frac.cell +0 -0
- package/test/data/org.cif +0 -0
- package/test/data/pyridine.xyz +1 -1
- package/test/data/pyridine_nocell.xyz +13 -0
- package/test/data/si8.xyz +0 -0
- package/test/data/si8_noisy.xyz +10 -0
- package/test/loader.js +22 -1
- package/test/model.js +40 -9
- package/test/query.js +1 -1
- package/test/tensor.js +1 -1
- package/test/test-html/examples.js +0 -0
- package/test/test-html/index.html +0 -0
- package/test/test-html/index.js +35 -5
- package/tools/compile_colors.py +0 -0
- package/tools/compile_periodic.py +0 -0
- package/tools/ptable.json +0 -0
- package/tools/test +0 -0
package/lib/assets/fonts/font.js
CHANGED
|
File without changes
|
|
@@ -7,8 +7,10 @@ import {
|
|
|
7
7
|
import * as Fonts from './bmpfonts.js';
|
|
8
8
|
|
|
9
9
|
// Load the actual fonts
|
|
10
|
-
|
|
10
|
+
// For some reason if I load more than one font at a time, it breaks...
|
|
11
|
+
// const RubikMedium = new BitmapFont(Fonts.rubikMediumFont, Fonts.rubikMediumTexture);
|
|
12
|
+
const OpenSans = new BitmapFont(Fonts.openSansFont, Fonts.openSansTexture);
|
|
11
13
|
|
|
12
14
|
export {
|
|
13
|
-
|
|
15
|
+
OpenSans
|
|
14
16
|
};
|
|
File without changes
|
package/lib/data.js
CHANGED
|
File without changes
|
package/lib/formats/cell.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import _ from 'lodash';
|
|
9
9
|
import {
|
|
10
10
|
Atoms
|
|
11
|
-
} from 'crystcif-parse';
|
|
11
|
+
} from '@ccp-nc/crystcif-parse';
|
|
12
12
|
|
|
13
13
|
function cellBlocks(lines, units={}) {
|
|
14
14
|
const block_re = /%BLOCK\s+([A-Z_]+)/;
|
|
@@ -56,8 +56,14 @@ function load(contents, filename='cell') {
|
|
|
56
56
|
|
|
57
57
|
// Admissible units
|
|
58
58
|
const units = {
|
|
59
|
-
'LATTICE_CART':
|
|
60
|
-
'
|
|
59
|
+
'LATTICE_CART': ['ang', 'bohr'],
|
|
60
|
+
'LATTICE_ABC': ['ang', 'bohr'],
|
|
61
|
+
'POSITIONS_ABS': ['ang', 'bohr'],
|
|
62
|
+
};
|
|
63
|
+
// conversion factors
|
|
64
|
+
const unit_conv = {
|
|
65
|
+
'ang': 1.0,
|
|
66
|
+
'bohr': 0.5291772108 // CODATA 2002
|
|
61
67
|
};
|
|
62
68
|
|
|
63
69
|
// Find blocks
|
|
@@ -90,6 +96,17 @@ function load(contents, filename='cell') {
|
|
|
90
96
|
let cell = ccart? blocks['LATTICE_CART'].lines : blocks['LATTICE_ABC'].lines;
|
|
91
97
|
cell = cell.map((l) => (_.trim(l).split(/\s+/).map(parseFloat)));
|
|
92
98
|
|
|
99
|
+
// Scale cell by units
|
|
100
|
+
if (ccart) {
|
|
101
|
+
let u = blocks['LATTICE_CART']['units'] || 'ang';
|
|
102
|
+
cell = cell.map((l) => (l.map((x) => (x*unit_conv[u]))));
|
|
103
|
+
}
|
|
104
|
+
else if (cabc) {
|
|
105
|
+
let u = blocks['LATTICE_ABC']['units'] || 'ang';
|
|
106
|
+
// scale just the first row by units
|
|
107
|
+
cell[0] = cell[0].map((x) => (x*unit_conv[u]));
|
|
108
|
+
}
|
|
109
|
+
|
|
93
110
|
let elems = [];
|
|
94
111
|
let positions = [];
|
|
95
112
|
|
|
@@ -101,6 +118,12 @@ function load(contents, filename='cell') {
|
|
|
101
118
|
throw Error('Incomplete line in positions block');
|
|
102
119
|
elems.push(l[0]);
|
|
103
120
|
positions.push(l.slice(1,4).map(parseFloat));
|
|
121
|
+
// scale by units if in absolute units
|
|
122
|
+
if (pabs) {
|
|
123
|
+
// if units is not defined, assume angstroms
|
|
124
|
+
let u = blocks['POSITIONS_ABS']['units'] || 'ang';
|
|
125
|
+
positions[positions.length-1] = positions[positions.length-1].map((x) => (x*unit_conv[u]));
|
|
126
|
+
}
|
|
104
127
|
});
|
|
105
128
|
|
|
106
129
|
var a = new Atoms(elems, positions, cell, {}, pfrac);
|
package/lib/formats/cif.js
CHANGED
package/lib/formats/magres.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import _ from 'lodash';
|
|
9
9
|
import {
|
|
10
10
|
Atoms
|
|
11
|
-
} from 'crystcif-parse';
|
|
11
|
+
} from '@ccp-nc/crystcif-parse';
|
|
12
12
|
import {
|
|
13
13
|
TensorData
|
|
14
14
|
} from '../tensor.js';
|
|
@@ -50,6 +50,36 @@ function parseNoAtomLine(line, units) {
|
|
|
50
50
|
function parseOneAtomLine(line, units, labels) {
|
|
51
51
|
// Species label + index, then nine numbers
|
|
52
52
|
let sp = line[0];
|
|
53
|
+
// CASTEP <22.1.1 has a bug where species with in in-species index >99
|
|
54
|
+
// runs into the species label.
|
|
55
|
+
// To handle those cases, we need to check if the species label has
|
|
56
|
+
// an integer >99 at the end, and if so, remove it from the label
|
|
57
|
+
// and add it to the index.
|
|
58
|
+
|
|
59
|
+
// use regex to find any integer at the end of the species label
|
|
60
|
+
let sp_re = /([a-zA-Z]+)([0-9]+)$/;
|
|
61
|
+
let sp_match = sp.match(sp_re);
|
|
62
|
+
if (sp_match) {
|
|
63
|
+
// if the integer is >99 and the line has 10 elements instead of 11,
|
|
64
|
+
// remove it from the label and add it to the index
|
|
65
|
+
let rogue_int = parseInt(sp_match[2]);
|
|
66
|
+
if (rogue_int > 99 && line.length == 10) {
|
|
67
|
+
console.log(`
|
|
68
|
+
Badly formatted .magres file.
|
|
69
|
+
A line has a species label with an integer >99 at the end,
|
|
70
|
+
which suggests a writing-overflow (known bug in CASTEP).
|
|
71
|
+
e.g. 'Fe100' instead of 'Fe 100'.
|
|
72
|
+
The integer has been removed from the label and added to the index.
|
|
73
|
+
`)
|
|
74
|
+
|
|
75
|
+
sp = sp_match[1];
|
|
76
|
+
// insert the rogue integer into
|
|
77
|
+
// the line array at the correct position
|
|
78
|
+
line.splice(1, 0, rogue_int);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
53
83
|
let sp_i = parseInt(line[1]);
|
|
54
84
|
let i = _.findIndex(labels, function(x) {
|
|
55
85
|
return (x[0] == sp) && (x[1] == sp_i);
|
|
@@ -221,6 +251,11 @@ function load(contents, filename='magres') {
|
|
|
221
251
|
}
|
|
222
252
|
}
|
|
223
253
|
|
|
254
|
+
// Reject if we don't have a cell
|
|
255
|
+
if (!cell) {
|
|
256
|
+
throw Error('No unit cell found in Magres file. We only support Magres files with a Lattice block.');
|
|
257
|
+
}
|
|
258
|
+
|
|
224
259
|
// Read in the atom positions and species
|
|
225
260
|
let elems = [];
|
|
226
261
|
let pos = [];
|
|
@@ -243,8 +278,7 @@ function load(contents, filename='magres') {
|
|
|
243
278
|
elems.push(l[0]);
|
|
244
279
|
mlabels.push([l[1], parseInt(l[2])]);
|
|
245
280
|
labels.push(l[1]);
|
|
246
|
-
|
|
247
|
-
pos.push(_.map(l.splice(3), function(x) {
|
|
281
|
+
pos.push(_.map(l.slice(3,6), function(x) {
|
|
248
282
|
return parseFloat(x) * u;
|
|
249
283
|
}));
|
|
250
284
|
}
|
package/lib/formats/xyz.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import _ from 'lodash';
|
|
9
|
-
import { Atoms } from 'crystcif-parse';
|
|
9
|
+
import { Atoms } from '@ccp-nc/crystcif-parse';
|
|
10
10
|
|
|
11
11
|
function load(contents, filename='xyz') {
|
|
12
12
|
|
|
@@ -23,7 +23,7 @@ function load(contents, filename='xyz') {
|
|
|
23
23
|
let info = lines[1];
|
|
24
24
|
// Check if it's extended format
|
|
25
25
|
let ext = false;
|
|
26
|
-
let rext = /([A-Za-z]+)=(([A-Za-z0-9.:]+)|"([\s0-9.]+)")/g;
|
|
26
|
+
let rext = /([A-Za-z]+)=(([A-Za-z0-9.:]+)|"([\s0-9.e-]+)")/g;
|
|
27
27
|
let m = rext.exec(info);
|
|
28
28
|
let matches = [];
|
|
29
29
|
let cell = null;
|
|
@@ -108,6 +108,11 @@ function load(contents, filename='xyz') {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
// check if we have a cell
|
|
112
|
+
if (cell === null) {
|
|
113
|
+
throw Error('No cell found in XYZ file. Please use the Extended XYZ format.');
|
|
114
|
+
}
|
|
115
|
+
|
|
111
116
|
let a = new Atoms(elems, pos, cell, info);
|
|
112
117
|
if (ext) {
|
|
113
118
|
for (let i = 0; i < arrays.length; ++i) {
|
package/lib/loader.js
CHANGED
|
File without changes
|
package/lib/model.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
|
|
14
14
|
import {
|
|
15
15
|
Atoms as Atoms
|
|
16
|
-
} from 'crystcif-parse';
|
|
16
|
+
} from '@ccp-nc/crystcif-parse';
|
|
17
17
|
|
|
18
18
|
import * as utils from './utils.js';
|
|
19
19
|
import * as data from './data.js';
|
|
@@ -976,9 +976,27 @@ class Model {
|
|
|
976
976
|
return c;
|
|
977
977
|
});
|
|
978
978
|
|
|
979
|
+
let has_cif_labels = false;
|
|
980
|
+
|
|
979
981
|
// Crystallographic labels
|
|
980
982
|
if ('labels' in this._atoms_base._arrays) {
|
|
981
|
-
|
|
983
|
+
// If any of the labels don't match the element,
|
|
984
|
+
// then we're assuming they're crystallographic (CIF-style) labels
|
|
985
|
+
if (this._atoms_base._arrays['labels'].some((l, i) => {
|
|
986
|
+
return l !== this._elems[i];
|
|
987
|
+
})) {
|
|
988
|
+
// then use them
|
|
989
|
+
has_cif_labels = true;
|
|
990
|
+
this._labels = this._atoms_base._arrays['labels'];
|
|
991
|
+
} else {
|
|
992
|
+
// otherwise, build new ones and
|
|
993
|
+
// throw a warning to user syaing we're doing this
|
|
994
|
+
this._labels = [];
|
|
995
|
+
for (let i = 0; i < this._elems.length; ++i) {
|
|
996
|
+
this._labels.push(this._elems[i] + '_' + (this._species_indices[i]+1));
|
|
997
|
+
}
|
|
998
|
+
console.warn('No crystallographic labels found in CIF file. Building new ones.');
|
|
999
|
+
}
|
|
982
1000
|
}
|
|
983
1001
|
else {
|
|
984
1002
|
// Build them
|
|
@@ -988,13 +1006,15 @@ class Model {
|
|
|
988
1006
|
}
|
|
989
1007
|
}
|
|
990
1008
|
|
|
1009
|
+
this._has_cif_labels = has_cif_labels; // defaults to false
|
|
991
1010
|
|
|
992
1011
|
if (this._periodic) {
|
|
993
1012
|
// R matrix: indispensable for calculations of periodic distances
|
|
994
1013
|
this._r_matrix = mjs.multiply(this._cell, mjs.transpose(this._cell));
|
|
995
1014
|
var ediag = mjs.eigs(this._r_matrix);
|
|
996
|
-
// Sort by eigenvalue
|
|
997
|
-
|
|
1015
|
+
// Sort by eigenvalue
|
|
1016
|
+
var evecs = ediag.eigenvectors.map(e => e.vector);
|
|
1017
|
+
ediag = _.zip(ediag.values, evecs);
|
|
998
1018
|
ediag = _.sortBy(ediag, function(x) {
|
|
999
1019
|
return x[0];
|
|
1000
1020
|
});
|
|
@@ -1003,7 +1023,7 @@ class Model {
|
|
|
1003
1023
|
this._r_diag = {
|
|
1004
1024
|
values: ediag[0],
|
|
1005
1025
|
vectors: ediag[1],
|
|
1006
|
-
}
|
|
1026
|
+
};
|
|
1007
1027
|
|
|
1008
1028
|
this._supercell = supercell; // Default
|
|
1009
1029
|
this._supercell_grid = utils.supercellGrid(supercell);
|
|
@@ -1021,7 +1041,11 @@ class Model {
|
|
|
1021
1041
|
|
|
1022
1042
|
initMolecules(atoms, parameters.supercell);
|
|
1023
1043
|
|
|
1024
|
-
if
|
|
1044
|
+
// if parameters.molecularCrystal, is null, we need to check if the atoms
|
|
1045
|
+
// contains organic molecules -- i.e. if there is at least one C-H bond
|
|
1046
|
+
if (parameters.molecularCrystal || (parameters.molecularCrystal === null &&
|
|
1047
|
+
this._queryCHBond())) {
|
|
1048
|
+
this._molecularCrystal = true;
|
|
1025
1049
|
atoms = _.cloneDeep(atoms);
|
|
1026
1050
|
var pos = this.positions;
|
|
1027
1051
|
for (let i = 0; i < this.length; ++i) {
|
|
@@ -1248,7 +1272,7 @@ class Model {
|
|
|
1248
1272
|
if (this.periodic) {
|
|
1249
1273
|
// Create axes and box
|
|
1250
1274
|
if (!this._cartesian_box) {
|
|
1251
|
-
this._cartesian_box = new r.Primitives.BoxMesh(this.cell);
|
|
1275
|
+
this._cartesian_box = new r.Primitives.BoxMesh(this.cell, {color:r.theme.cell_line_color});
|
|
1252
1276
|
}
|
|
1253
1277
|
if (!this._cartesian_axes) {
|
|
1254
1278
|
this._cartesian_axes = new r.Primitives.AxesMesh(this.cell, {
|
|
@@ -1341,7 +1365,7 @@ class Model {
|
|
|
1341
1365
|
color: parameters.color,
|
|
1342
1366
|
fixScale: true,
|
|
1343
1367
|
faceCamera: true,
|
|
1344
|
-
height: LABEL_HEIGHT,
|
|
1368
|
+
height: parameters.height || LABEL_HEIGHT,
|
|
1345
1369
|
shift: [LABEL_HEIGHT, 0, 0],
|
|
1346
1370
|
onOverlay: parameters.onOverlay
|
|
1347
1371
|
});
|
|
@@ -1492,6 +1516,40 @@ class Model {
|
|
|
1492
1516
|
}
|
|
1493
1517
|
}
|
|
1494
1518
|
|
|
1519
|
+
/**
|
|
1520
|
+
* Check if any C-H bonds are present
|
|
1521
|
+
* @return {bool} Whether any C-H bonds are present
|
|
1522
|
+
* @private
|
|
1523
|
+
*/
|
|
1524
|
+
_queryCHBond() {
|
|
1525
|
+
// make sure bondmat is present
|
|
1526
|
+
if (!this._bondmat) {
|
|
1527
|
+
this._computeBonds();
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
var symbols = this._atoms_base.get_chemical_symbols();
|
|
1531
|
+
var bondmat = this._bondmat;
|
|
1532
|
+
var n = symbols.length;
|
|
1533
|
+
for (var i = 0; i < n; i++) {
|
|
1534
|
+
var bonds = bondmat[i];
|
|
1535
|
+
var a = symbols[i];
|
|
1536
|
+
if (a == 'C') {
|
|
1537
|
+
// loop over bonds and check if any are H
|
|
1538
|
+
for (var j = 0; j < n; j++) {
|
|
1539
|
+
// if bonds[j] is not an empty array
|
|
1540
|
+
if (bonds[j].length) {
|
|
1541
|
+
if (symbols[j] == 'H') {
|
|
1542
|
+
return true;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
return false;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1495
1553
|
/**
|
|
1496
1554
|
* Compute the molecules within the model. For internal use
|
|
1497
1555
|
* @private
|
|
@@ -1804,6 +1862,23 @@ class Model {
|
|
|
1804
1862
|
return this._queryIndices(indices);
|
|
1805
1863
|
}
|
|
1806
1864
|
|
|
1865
|
+
/**
|
|
1866
|
+
* @private
|
|
1867
|
+
*/
|
|
1868
|
+
_queryLabels(labels) {
|
|
1869
|
+
if (_.isString(labels)) {
|
|
1870
|
+
labels = [labels]; // A single label
|
|
1871
|
+
}
|
|
1872
|
+
var indices = _.reduce(this._labels, function(inds, s, i) {
|
|
1873
|
+
if (labels.indexOf(s) > -1) {
|
|
1874
|
+
inds.push(i);
|
|
1875
|
+
}
|
|
1876
|
+
return inds;
|
|
1877
|
+
}, []);
|
|
1878
|
+
|
|
1879
|
+
return this._queryIndices(indices);
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1807
1882
|
/**
|
|
1808
1883
|
* @private
|
|
1809
1884
|
*/
|
package/lib/modelview.js
CHANGED
|
@@ -169,6 +169,34 @@ class ModelView {
|
|
|
169
169
|
return new ModelView(this._model, indices);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Remove all atoms in mview from the current view
|
|
174
|
+
*/
|
|
175
|
+
remove(mview) {
|
|
176
|
+
if (this._model != mview._model)
|
|
177
|
+
throw 'The two ModelViews do not refer to the same Model';
|
|
178
|
+
return new ModelView(this._model,
|
|
179
|
+
_.differenceWith(this._indices, mview._indices));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Unique atoms in the current view (based on site labels)
|
|
184
|
+
*/
|
|
185
|
+
uniqueSites() {
|
|
186
|
+
// all labels:
|
|
187
|
+
var labels = this._images.map(function(a) { return a.crystLabel; });
|
|
188
|
+
var allIndices = this._indices;
|
|
189
|
+
|
|
190
|
+
// unique labels:
|
|
191
|
+
var ulabels = _.uniq(labels);
|
|
192
|
+
// indices of unique labels:
|
|
193
|
+
var uindices = ulabels.map(function(l) { return allIndices[labels.indexOf(l)]; });
|
|
194
|
+
// sort the uindices:
|
|
195
|
+
uindices.sort(function(a, b) { return a - b; });
|
|
196
|
+
// return the unique atoms:
|
|
197
|
+
return new ModelView(this._model, uindices);
|
|
198
|
+
}
|
|
199
|
+
|
|
172
200
|
/**
|
|
173
201
|
* Internal function used to turn a single value, array of values, or
|
|
174
202
|
* function into an array of values
|
|
@@ -220,6 +248,13 @@ class ModelView {
|
|
|
220
248
|
return this;
|
|
221
249
|
}
|
|
222
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Get sorted set of unique elements in the ModelView
|
|
253
|
+
*/
|
|
254
|
+
get elements() {
|
|
255
|
+
return _.uniq(this.map(a => a.element).sort());
|
|
256
|
+
}
|
|
257
|
+
|
|
223
258
|
/**
|
|
224
259
|
* Add labels to the atom images in this ModelView
|
|
225
260
|
*
|
package/lib/nmrdata.js
CHANGED
|
File without changes
|
package/lib/primitives/atoms.js
CHANGED
|
File without changes
|
package/lib/primitives/cell.js
CHANGED
|
@@ -8,6 +8,9 @@ import _ from 'lodash';
|
|
|
8
8
|
import * as THREE from 'three';
|
|
9
9
|
import { Vector3 } from 'three';
|
|
10
10
|
import { cellMatrix3 } from '../utils.js';
|
|
11
|
+
import { TextSprite } from './sprites.js';
|
|
12
|
+
|
|
13
|
+
const LABEL_HEIGHT = 0.04; // Height of the label
|
|
11
14
|
|
|
12
15
|
// Cell box
|
|
13
16
|
class BoxMesh extends THREE.LineSegments {
|
|
@@ -67,19 +70,21 @@ class AxesMesh extends THREE.Group {
|
|
|
67
70
|
*
|
|
68
71
|
* @param {Array} lattice Lattice parameters for the unit cell
|
|
69
72
|
* @param {Object} parameters Options:
|
|
70
|
-
* linewidth
|
|
73
|
+
* linewidth (NB: on most platforms linewidth will always be 1 regardless of the set value. This is a known issue with three.js)
|
|
71
74
|
* xColor
|
|
72
75
|
* yColor
|
|
73
76
|
* zColor
|
|
77
|
+
* labels: array of strings for the labels. Defaults to null, which means no labels
|
|
74
78
|
*
|
|
75
79
|
*/
|
|
76
80
|
constructor(lattice, parameters = {}) {
|
|
77
81
|
|
|
78
82
|
var defaults = {
|
|
79
|
-
linewidth: 1.2,
|
|
83
|
+
linewidth: 1.2, // this often is effectively 1.0. See: https://threejs.org/docs/?q=lineba#api/en/materials/LineBasicMaterial.linewidth
|
|
80
84
|
xColor: 0xff0000,
|
|
81
85
|
yColor: 0x00ff00,
|
|
82
|
-
zColor: 0x0000ff
|
|
86
|
+
zColor: 0x0000ff,
|
|
87
|
+
labels: null
|
|
83
88
|
};
|
|
84
89
|
|
|
85
90
|
parameters = _.merge(defaults, parameters);
|
|
@@ -112,6 +117,23 @@ class AxesMesh extends THREE.Group {
|
|
|
112
117
|
var arr = new THREE.ArrowHelper(dir, origin, l, colors[i]);
|
|
113
118
|
arr.line.material.linewidth = parameters.linewidth;
|
|
114
119
|
this.add(arr);
|
|
120
|
+
|
|
121
|
+
if (parameters.labels) {
|
|
122
|
+
// assert parameters.labels.length == 3
|
|
123
|
+
var label = parameters.labels[i];
|
|
124
|
+
var labelPos = dir.clone().multiplyScalar(l * 1.1);
|
|
125
|
+
var text = new TextSprite(label, {
|
|
126
|
+
position: labelPos,
|
|
127
|
+
color: colors[i],
|
|
128
|
+
height: LABEL_HEIGHT,
|
|
129
|
+
faceCamera: true,
|
|
130
|
+
fixScale: true,
|
|
131
|
+
shift: [0.0,0,0.0],
|
|
132
|
+
});
|
|
133
|
+
this.add(text);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
115
137
|
}
|
|
116
138
|
}
|
|
117
139
|
|
package/lib/primitives/dither.js
CHANGED
|
File without changes
|
|
@@ -31,6 +31,7 @@ class EllipsoidMesh extends THREE.Mesh {
|
|
|
31
31
|
color: 0xff0000,
|
|
32
32
|
opacity: 0.5,
|
|
33
33
|
opacityMode: EllipsoidMesh.DITHER,
|
|
34
|
+
showEllipsoid: true,
|
|
34
35
|
showCircles: true,
|
|
35
36
|
showAxes: true,
|
|
36
37
|
scalingFactor: 1.0
|
|
@@ -86,21 +87,36 @@ class EllipsoidMesh extends THREE.Mesh {
|
|
|
86
87
|
if (parameters.showAxes) {
|
|
87
88
|
|
|
88
89
|
let matline = new THREE.LineBasicMaterial({
|
|
89
|
-
color: new THREE.Color(
|
|
90
|
+
color: new THREE.Color(0xff0000),
|
|
90
91
|
});
|
|
91
92
|
|
|
92
93
|
let geoline = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-1, 0, 0),
|
|
93
94
|
new THREE.Vector3(1, 0, 0)
|
|
94
95
|
]);
|
|
96
|
+
|
|
97
|
+
// change the color of the x axis
|
|
98
|
+
matline = new THREE.LineBasicMaterial({
|
|
99
|
+
color: new THREE.Color(0xff0000),
|
|
100
|
+
});
|
|
101
|
+
let xseg = new THREE.LineSegments(geoline, matline);
|
|
102
|
+
this.add(xseg);
|
|
95
103
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
// change the color of the y axis
|
|
105
|
+
matline = new THREE.LineBasicMaterial({
|
|
106
|
+
color: new THREE.Color(0x00ff00),
|
|
107
|
+
});
|
|
108
|
+
let yseg = new THREE.LineSegments(geoline, matline);
|
|
109
|
+
yseg.rotateZ(Math.PI / 2.0);
|
|
110
|
+
this.add(yseg);
|
|
111
|
+
|
|
112
|
+
// change the color of the z axis
|
|
113
|
+
matline = new THREE.LineBasicMaterial({
|
|
114
|
+
color: new THREE.Color(0x0000ff),
|
|
115
|
+
});
|
|
116
|
+
// matline.color = new THREE.Color(0x0000ff);
|
|
117
|
+
let zseg = new THREE.LineSegments(geoline, matline);
|
|
118
|
+
zseg.rotateY(Math.PI / 2.0);
|
|
119
|
+
this.add(zseg);
|
|
104
120
|
}
|
|
105
121
|
|
|
106
122
|
let c0 = parameters.center;
|
|
@@ -115,6 +131,10 @@ class EllipsoidMesh extends THREE.Mesh {
|
|
|
115
131
|
this.eigenvalues = parameters.eigenvalues;
|
|
116
132
|
this.eigenvectors = parameters.eigenvectors;
|
|
117
133
|
|
|
134
|
+
// set material to be invisible if showEllipsoid is false
|
|
135
|
+
if (!parameters.showEllipsoid) {
|
|
136
|
+
material.visible = false;
|
|
137
|
+
}
|
|
118
138
|
this.renderOrder = 0.5;
|
|
119
139
|
}
|
|
120
140
|
|
|
File without changes
|
|
File without changes
|
package/lib/primitives/shapes.js
CHANGED
|
File without changes
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import _ from 'lodash';
|
|
8
8
|
import * as THREE from 'three';
|
|
9
9
|
import {
|
|
10
|
-
|
|
10
|
+
OpenSans
|
|
11
11
|
} from '../assets/fonts/index.js';
|
|
12
12
|
|
|
13
13
|
|
|
@@ -85,7 +85,7 @@ class TextSprite extends THREE.Mesh {
|
|
|
85
85
|
|
|
86
86
|
var defaults = {
|
|
87
87
|
position: [0, 0, 0],
|
|
88
|
-
font:
|
|
88
|
+
font: OpenSans,
|
|
89
89
|
color: 0xffffff,
|
|
90
90
|
opacity: 1.0,
|
|
91
91
|
height: 1.0,
|
package/lib/query.js
CHANGED
|
File without changes
|