@@ -2,10 +2,16 @@ import React from "react";
22
33import * as $3Dmol from "3dmol" ;
44
5+ import * as math from "mathjs" ;
6+
57import { covalentRadii } from "./bondLengths" ;
68
79import "./Visualizer3dmol.css" ;
810
11+ function mod ( n , m ) {
12+ return ( ( n % m ) + m ) % m ;
13+ }
14+
915// override the covalent bond detection based on examples in MC3D
1016const overrideBondLengths = {
1117 // uuid = "aaea1e0f-337c-453f-a23a-acc06ddc93c9"; // BaTiO3 mc3d-46554/pbe
@@ -64,9 +70,126 @@ class Visualizer3dmol extends React.Component {
6470 }
6571 }
6672
73+ custom3dmolSetup ( ) {
74+ this . model = this . viewer . addModel ( ) ;
75+
76+ if ( this . props . cifText ) {
77+ let loadedCif = $3Dmol . Parsers . CIF ( this . props . cifText ) ;
78+ let loadedAtoms = loadedCif [ 0 ] ;
79+ let cellData = loadedCif [ "modelData" ] [ 0 ] [ "cryst" ] ;
80+
81+ this . model . setCrystData (
82+ cellData . a ,
83+ cellData . b ,
84+ cellData . c ,
85+ cellData . alpha ,
86+ cellData . beta ,
87+ cellData . gamma ,
88+ ) ;
89+
90+ let cellMatrix = this . model . modelData . cryst . matrix ;
91+
92+ let fracConversionMatrix = new $3Dmol . Matrix3 ( ) . getInverse3 ( cellMatrix ) ;
93+
94+ let final_atoms = [ ] ;
95+
96+ // console.log("loadedAtoms", loadedAtoms);
97+ // loadedAtoms = [
98+ // {
99+ // elem: "C",
100+ // x: 0.1,
101+ // y: 0.1,
102+ // z: 50.0,
103+ // },
104+ // ];
105+
106+ // in case of packed cell, make sure all the initially specified atoms
107+ // are folded back to the unit cell
108+ let atoms = [ ] ;
109+ loadedAtoms . forEach ( ( atom ) => {
110+ let cart = new $3Dmol . Vector3 ( atom . x , atom . y , atom . z ) ;
111+ if ( this . props . viewerParams . packedCell ) {
112+ let frac = cart . clone ( ) . applyMatrix3 ( fracConversionMatrix ) ;
113+ let folded_frac = new $3Dmol . Vector3 (
114+ mod ( frac . x , 1 ) ,
115+ mod ( frac . y , 1 ) ,
116+ mod ( frac . z , 1 ) ,
117+ ) ;
118+ // convert back to cartesian
119+ cart = folded_frac . applyMatrix3 ( cellMatrix ) ;
120+ }
121+ atoms . push ( {
122+ elem : atom . elem ,
123+ x : cart . x ,
124+ y : cart . y ,
125+ z : cart . z ,
126+ } ) ;
127+ } ) ;
128+
129+ // Build the supercell
130+
131+ let sc = this . props . viewerParams . supercell ;
132+ for ( let i = - 1 ; i < sc [ 0 ] + 1 ; i ++ ) {
133+ for ( let j = - 1 ; j < sc [ 1 ] + 1 ; j ++ ) {
134+ for ( let k = - 1 ; k < sc [ 2 ] + 1 ; k ++ ) {
135+ let offset = new $3Dmol . Vector3 ( i , j , k ) ;
136+ offset . applyMatrix3 ( cellMatrix ) ;
137+
138+ // prettier-ignore
139+ if (
140+ i == - 1 || i == sc [ 0 ] ||
141+ j == - 1 || j == sc [ 1 ] ||
142+ k == - 1 || k == sc [ 2 ]
143+ ) {
144+ // we are outside the specified supercell.
145+ // in case of packed cell, add all atoms from the
146+ // neighboring cells that are exactly on edges
147+ if ( this . props . viewerParams . packedCell ) {
148+ atoms . forEach ( ( atom ) => {
149+ let cart = new $3Dmol . Vector3 ( atom . x , atom . y , atom . z ) ;
150+ cart . add ( offset ) ;
151+ let frac = cart . clone ( ) . applyMatrix3 ( fracConversionMatrix ) ;
152+
153+ // prettier-ignore
154+ if (
155+ frac . x > - 0.0001 && frac . x < sc [ 0 ] + 0.0001 &&
156+ frac . y > - 0.0001 && frac . y < sc [ 1 ] + 0.0001 &&
157+ frac . z > - 0.0001 && frac . z < sc [ 2 ] + 0.0001
158+ ) {
159+ final_atoms . push ( {
160+ elem : atom . elem ,
161+ x : cart . x ,
162+ y : cart . y ,
163+ z : cart . z ,
164+ } ) ;
165+ }
166+ } ) ;
167+ } else {
168+ // in "non-packed" case, skip these edge cells
169+ continue
170+ }
171+ } else {
172+ atoms . forEach ( ( atom ) => {
173+ final_atoms . push ( {
174+ elem : atom . elem ,
175+ x : atom . x + offset . x ,
176+ y : atom . y + offset . y ,
177+ z : atom . z + offset . z ,
178+ } ) ;
179+ } ) ;
180+ }
181+ }
182+ }
183+ }
184+
185+ this . model . addAtoms ( final_atoms ) ;
186+ }
187+ }
188+
67189 updateView ( ) {
68190 this . viewer . removeAllModels ( ) ;
69- this . model = this . viewer . addModel ( this . props . cifText , "cif" ) ;
191+ // this.model = this.viewer.addModel(this.props.cifText, "cif");
192+ this . custom3dmolSetup ( ) ;
70193
71194 let style = {
72195 sphere : { scale : 0.3 , colorscheme : "Jmol" } ,
@@ -81,8 +204,8 @@ class Visualizer3dmol extends React.Component {
81204 this . viewer . setStyle ( style ) ;
82205
83206 this . viewer . addUnitCell ( this . model ) ;
84- let sc = this . props . viewerParams . supercell ;
85- this . viewer . replicateUnitCell ( sc [ 0 ] , sc [ 1 ] , sc [ 2 ] , this . model ) ;
207+ // let sc = this.props.viewerParams.supercell;
208+ // this.viewer.replicateUnitCell(sc[0], sc[1], sc[2], this.model);
86209
87210 this . model . assignBonds ( ) ;
88211
0 commit comments