Skip to content

Commit

Permalink
Merge branch 'master' of github.com:3dmol/3Dmol.js
Browse files Browse the repository at this point in the history
  • Loading branch information
dkoes committed Mar 13, 2024
2 parents 49cf49f + 8549c59 commit c9eaf10
Show file tree
Hide file tree
Showing 20 changed files with 12,278 additions and 23 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "3dmol",
"version": "2.0.6",
"version": "2.1.0",
"description": "JavaScript/TypeScript molecular visualization library",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion py3Dmol/py3Dmol/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class view(object):
the exception that the functions all return None.
http://3dmol.org/doc/GLViewer.html
'''
def __init__(self,query='',width=640,height=480,viewergrid=None,data=None,style=None,linked=True,options=dict(),js='https://cdnjs.cloudflare.com/ajax/libs/3Dmol/2.0.5/3Dmol-min.js'):
def __init__(self,query='',width=640,height=480,viewergrid=None,data=None,style=None,linked=True,options=dict(),js='https://cdnjs.cloudflare.com/ajax/libs/3Dmol/2.1.0/3Dmol-min.js'):
'''Create a 3Dmol.js view.
width -- width in pixels of container
height -- height in pixels of container
Expand Down
2 changes: 1 addition & 1 deletion py3Dmol/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
# Keep version in synce with 3Dmol.js version. Use "postX" suffix if needed
version='2.0.4',
version='2.1.0',

description='An IPython interface for embedding 3Dmol.js views in Jupyter notebooks',
long_description=long_description,
Expand Down
2 changes: 1 addition & 1 deletion src/GLModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2146,7 +2146,7 @@ export class GLModel {
* consider valence constraints and will only create single bonds.
*/
public assignBonds() {
assignBonds(this.atoms);
assignBonds(this.atoms, {assignBonds: true});
}

/** Remove specified atoms from model
Expand Down
33 changes: 30 additions & 3 deletions src/GLViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1311,10 +1311,24 @@ export class GLViewer {
let regen = false;
if (this.renderer.isLost() && this.WIDTH > 0 && this.HEIGHT > 0) {
//create new context
this.container.querySelector('canvas').remove(); //remove existing
let resetcanvas = false;
let currentcanvas = this.container.querySelector('canvas');
if(currentcanvas && currentcanvas != this.renderer.getCanvas()) {
//canvas has been replaced, use new one
this.config.canvas = currentcanvas;
} else {
currentcanvas.remove(); //remove existing
if(this.config && this.config.canvas != undefined) {
delete this.config.canvas;
resetcanvas = true;
}
}
this.setupRenderer();
this.initContainer(this.container);
regen = true;
if(resetcanvas) {
this.config.canvas = this.renderer.getCanvas();
}
}
if (this.WIDTH == 0 || this.HEIGHT == 0) {
if (this.animated) this._viewer.pauseAnimate();
Expand All @@ -1327,6 +1341,13 @@ export class GLViewer {
if (regen) { //restored rendere, need to regenerate scene
let options = this.renderer.supportedExtensions();
options.regen = true;
if(this.viewers) {
for(let i = 0, n = this.viewers.length; i < n; i++) {
for(let j = 0, m = this.viewers[i].length; j < m; j++) {
this.viewers[i][j].render(null, options);
}
}
}
this._viewer.render(null, options);
} else {
this.show();
Expand Down Expand Up @@ -1676,6 +1697,12 @@ export class GLViewer {
}

for (i = 0; i < this.labels.length; i++) {
if(exts.regen) {
this.labels[i].dispose();
this.modelGroup.remove(this.labels[i].sprite);
this.labels[i].setContext();
this.modelGroup.add(this.labels[i].sprite);
}
if (this.labels[i] && typeof (this.labels[i].frame) != 'undefined' && this.labels[i].frame >= 0) { //exists and has frame specifier
this.modelGroup.remove(this.labels[i].sprite);
if (this.viewer_frame < 0 || this.labels[i].frame == this.viewer_frame) {
Expand All @@ -1693,15 +1720,15 @@ export class GLViewer {
// async surface generation can cause
// the geometry to be webgl initialized before it is fully
// formed; force various recalculations until full surface
// is
// available
// is available
if (!surfArr[n].finished || exts.regen) {
geo.verticesNeedUpdate = true;
geo.elementsNeedUpdate = true;
geo.normalsNeedUpdate = true;
geo.colorsNeedUpdate = true;
geo.buffersNeedUpdate = true;
geo.boundingSphere = null;
surfArr[n].mat.needsUpdate = true;

if (surfArr[n].done)
surfArr[n].finished = true;
Expand Down
4 changes: 4 additions & 0 deletions src/WebGL/Renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ export class Renderer {
return this._gl;
}

getCanvas() {
return this._canvas;
}

isLost() {
return this._gl.isContextLost();
}
Expand Down
4 changes: 2 additions & 2 deletions src/parsers/CIF.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ export function CIF(str: string, options: ParserOptionsSpec = {}) {
}
for (let i = 0; i < atoms.length; i++) {
if (assignbonds && !(options.duplicateAssemblyAtoms && !options.dontConnectDuplicatedAtoms)) {
assignPDBBonds(atoms[i]);
assignPDBBonds(atoms[i], options);
}
computeSecondaryStructure(atoms[i],options.hbondCutoff);
processSymmetries(
Expand All @@ -421,7 +421,7 @@ export function CIF(str: string, options: ParserOptionsSpec = {}) {
!options.dontConnectDuplicatedAtoms &&
assignbonds
)
assignPDBBonds(atoms[i]);
assignPDBBonds(atoms[i],options);
}

return atoms;
Expand Down
2 changes: 1 addition & 1 deletion src/parsers/CUBE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export function CUBE(str: string, options: ParserOptionsSpec) {

if(assignbonds) {
for (let i = 0; i < atoms.length; i++)
assignBonds(atoms[i]);
assignBonds(atoms[i], options);
}
return atoms;
};
5 changes: 3 additions & 2 deletions src/parsers/GRO.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ParserOptionsSpec } from "./ParserOptionsSpec";
import { assignPDBBonds } from "./utils/assignPDBBonds";
import { atomNameToElem } from "./utils/atomNameToElem";

Expand All @@ -11,7 +12,7 @@ import { atomNameToElem } from "./utils/atomNameToElem";
* @category Parsers
*/

export function GRO(str: string /*, options*/) {
export function GRO(str: string, options: ParserOptionsSpec) {
var allatoms: any[][] & Record<string, any> = [];
var lines = str.split(/\r?\n|\r/);
while (lines.length > 0) {
Expand Down Expand Up @@ -62,7 +63,7 @@ export function GRO(str: string /*, options*/) {
}

for (let i = 0; i < allatoms.length; i++) {
assignPDBBonds(allatoms[i]);
assignPDBBonds(allatoms[i], options);
}
return allatoms;
}
2 changes: 1 addition & 1 deletion src/parsers/LAMMPSTRJ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function LAMMPSTRJ(str: string, options: ParserOptionsSpec) {
start = offset + atomCount - 1;
}
if (options.assignBonds) {
for (var i = 0; i < atoms.length; i++) assignBonds(atoms[i]);
for (var i = 0; i < atoms.length; i++) assignBonds(atoms[i], options);
}
return atoms;
}
2 changes: 1 addition & 1 deletion src/parsers/PQR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export function PQR(str: string, options: ParserOptionsSpec) {

// assign bonds - yuck, can't count on connect records
for (let i = 0; i < atoms.length; i++) {
assignPDBBonds(atoms[i]);
assignPDBBonds(atoms[i],options);
if (computeStruct)
computeSecondaryStructure(atoms[i],options.hbondCutoff);
}
Expand Down
2 changes: 2 additions & 0 deletions src/parsers/ParserOptionsSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ import { AtomStyleSpec } from "GLModel";
assemblyIndex?: number;
/** for formats without explicit bonds (e.g. PDB, xyz) infer bonding (default true). */
assignBonds?: boolean;
/** for formats without explicit bonds, if assigning bonds to not assign bonds to common cations */
unboundCations?: boolean;
/** set model to this style after parsing */
style?: AtomStyleSpec;
};
2 changes: 1 addition & 1 deletion src/parsers/XYZ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function XYZ(str: string, options: ParserOptionsSpec) {

if (assignbonds) {
for (let i = 0; i < atoms.length; i++) {
assignBonds(atoms[i]);
assignBonds(atoms[i], options);
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/parsers/utils/areConnected.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { AtomSpec } from "specs";
import { bondLength } from "./bondLength";
import { ParserOptionsSpec } from "parsers/ParserOptionsSpec";

const cations = new Set(["Na","K","Ca","Mg","Mn","Sr"]);

/*
* Return true if atom1 and atom2 are probably bonded to each other based on distance alone
*/
export function areConnected(atom1: AtomSpec, atom2: AtomSpec) {
export function areConnected(atom1: AtomSpec, atom2: AtomSpec, options: ParserOptionsSpec) {
if(options && options.unboundCations && (cations.has(atom1.elem) || cations.has(atom2.elem))) {
return false;
}
let maxsq = bondLength(atom1.elem) + bondLength(atom2.elem);
maxsq += 0.25; // fudge factor, especially important for md frames, also see 1i3d
maxsq *= maxsq;
Expand Down
7 changes: 4 additions & 3 deletions src/parsers/utils/assignBonds.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AtomSpec } from "specs";
import { areConnected } from "./areConnected";
import { ParserOptionsSpec } from "parsers/ParserOptionsSpec";

/**
* @param {AtomSpec[]} atoms
Expand All @@ -21,7 +22,7 @@ const OFFSETS = [
];
const MAX_BOND_LENGTH = 4.95; // (largest bond length, Cs) 2.25 * 2 * 1.1 (fudge factor)

export function assignBonds(atoms: AtomSpec[]) {
export function assignBonds(atoms: AtomSpec[], options: ParserOptionsSpec) {
// Assign bonds - yuck, can't count on connect records

for (let i = 0, n = atoms.length; i < n; i++) {
Expand Down Expand Up @@ -70,7 +71,7 @@ export function assignBonds(atoms: AtomSpec[]) {
for (let j = 0; j < otherPoints.length; j++) {
const atom2 = otherPoints[j];

if (areConnected(atom1, atom2)) {
if (areConnected(atom1, atom2, options)) {
//gracefully handle one-sided bonds
const a2i = atom1.bonds.indexOf(atom2.index);
const a1i = atom2.bonds.indexOf(atom1.index);
Expand Down Expand Up @@ -103,7 +104,7 @@ export function assignBonds(atoms: AtomSpec[]) {
const atom1 = points[i];
for (let j = i + 1; j < points.length; j++) {
const atom2 = points[j];
if (areConnected(atom1, atom2)) {
if (areConnected(atom1, atom2,options)) {
if (atom1.bonds.indexOf(atom2.index) == -1) {
atom1.bonds.push(atom2.index);
atom1.bondOrder.push(1);
Expand Down
8 changes: 5 additions & 3 deletions src/parsers/utils/assignPDBBonds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { AtomSpec } from "specs";
import { areConnected } from "./areConnected";
import { assignBonds } from "./assignBonds";
import { standardResidues } from "./standardResidues";
import { ParserOptionsSpec } from "parsers/ParserOptionsSpec";


/**
* @param {AtomSpec[]}
* atomsarray
*/

export function assignPDBBonds(atomsarray: AtomSpec[]) {
export function assignPDBBonds(atomsarray: AtomSpec[], options: ParserOptionsSpec) {
// assign bonds - yuck, can't count on connect records
const protatoms: Array<AtomSpec> = [];
const hetatoms: Array<AtomSpec> = [];
Expand All @@ -21,7 +23,7 @@ export function assignPDBBonds(atomsarray: AtomSpec[]) {
else protatoms.push(atom);
}

assignBonds(hetatoms);
assignBonds(hetatoms, options);

// sort by resid
protatoms.sort(function (a, b) {
Expand Down Expand Up @@ -50,7 +52,7 @@ export function assignPDBBonds(atomsarray: AtomSpec[]) {
const aj = protatoms[j];
if (aj.chain !== ai.chain || aj.resi - ai.resi > 1) break;

if (areConnected(ai, aj)) {
if (areConnected(ai, aj, options)) {
if (ai.bonds.indexOf(aj.index) === -1) {
// only add if not already there
ai.bonds.push(aj.index);
Expand Down
2 changes: 1 addition & 1 deletion src/parsers/utils/getSinglePDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export function getSinglePDB(
//fix any "one-way" bonds in CONECT records
validateBonds(atoms, serialToIndex);
// assign bonds - yuck, can't count on connect records
if (assignbonds) assignPDBBonds(atoms);
if (assignbonds) assignPDBBonds(atoms, options);

if (!noAssembly)
processSymmetries(modelData.symmetries, atoms, options, modelData.cryst);
Expand Down
Loading

0 comments on commit c9eaf10

Please sign in to comment.