"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "layer2/ObjectMolecule.cpp" between
pymol-open-source-2.2.0.tar.gz and pymol-open-source-2.3.0.tar.gz

About: PyMOL is a Python-enhanced molecular graphics tool. It excels at 3D visualization of proteins, small molecules, density, surfaces, and trajectories. It also includes molecular editing, ray tracing, and movies. Open Source version.

ObjectMolecule.cpp  (pymol-open-source-2.2.0):ObjectMolecule.cpp  (pymol-open-source-2.3.0)
skipping to change at line 25 skipping to change at line 25
*/ */
#include"os_python.h" #include"os_python.h"
#include"os_predef.h" #include"os_predef.h"
#include"os_std.h" #include"os_std.h"
#include"os_gl.h" #include"os_gl.h"
#include <algorithm> #include <algorithm>
#include <set> #include <set>
#ifdef _PYMOL_NO_CXX11
#define STD_MOVE(x) (x)
#else
#define STD_MOVE(x) std::move(x)
#endif
#include"Base.h" #include"Base.h"
#include"Debug.h" #include"Debug.h"
#include"Parse.h" #include"Parse.h"
#include"OOMac.h" #include"OOMac.h"
#include"Vector.h" #include"Vector.h"
#include"MemoryDebug.h" #include"MemoryDebug.h"
#include"Err.h" #include"Err.h"
#include"Map.h" #include"Map.h"
#include"Selector.h" #include"Selector.h"
#include"ObjectMolecule.h" #include"ObjectMolecule.h"
skipping to change at line 77 skipping to change at line 71
#define ntrim ParseNTrim #define ntrim ParseNTrim
#define nextline ParseNextLine #define nextline ParseNextLine
#define ncopy ParseNCopy #define ncopy ParseNCopy
#define nskip ParseNSkip #define nskip ParseNSkip
#ifndef NO_MMLIBS #ifndef NO_MMLIBS
#include "mmpymolx.h" #include "mmpymolx.h"
#endif #endif
void ObjectMoleculeCylinders(ObjectMolecule * I);
static static
CoordSet *ObjectMoleculeMMDStr2CoordSet(PyMOLGlobals * G, const char *buffer, CoordSet *ObjectMoleculeMMDStr2CoordSet(PyMOLGlobals * G, const char *buffer,
AtomInfoType ** atInfoPtr, const char ** restart); AtomInfoType ** atInfoPtr, const char ** restart);
int ObjectMoleculeDoesAtomNeighborSele(ObjectMolecule * I, int index, int sele); static
void ObjectMoleculeAppendAtoms(ObjectMolecule * I, AtomInfoType * atInfo,
CoordSet * cset);
void ObjectMoleculeSeleOp(ObjectMolecule * I, int sele, ObjectMoleculeOpRec * op
);
void ObjectMoleculeTransformTTTf(ObjectMolecule * I, float *ttt, int state); void ObjectMoleculeTransformTTTf(ObjectMolecule * I, float *ttt, int state);
static
int ObjectMoleculeGetAtomGeometry(ObjectMolecule * I, int state, int at); int ObjectMoleculeGetAtomGeometry(ObjectMolecule * I, int state, int at);
void ObjectMoleculeBracketResidue(ObjectMolecule * I, AtomInfoType * ai, int *st
,
int *nd);
int ObjectMoleculeAddSeleHydrogens(ObjectMolecule * I, int sele, int state);
void ObjectMoleculeInferAmineGeomFromBonds(ObjectMolecule * I, int state);
static
void ObjectMoleculeInferHBondFromChem(ObjectMolecule * I); void ObjectMoleculeInferHBondFromChem(ObjectMolecule * I);
/* /*
* Order function for sorting bonds by atom indices (ignores other properties * Order function for sorting bonds by atom indices (ignores other properties
* like bond order). * like bond order).
* *
* Pre-condition: index pairs are in order (index[0] < index[1]) * Pre-condition: index pairs are in order (index[0] < index[1])
*/ */
static static
int BondTypeInOrder(PyMOLGlobals * G, const BondType * bonds, int i1, int i2) { int BondTypeInOrder(PyMOLGlobals * G, const BondType * bonds, int i1, int i2) {
skipping to change at line 2424 skipping to change at line 2406
*atInfoPtr = atInfo; *atInfoPtr = atInfo;
return (cset); return (cset);
} }
/*========================================================================*/ /*========================================================================*/
static ObjectMolecule *ObjectMoleculeReadTOPStr(PyMOLGlobals * G, ObjectMolecule * I, static ObjectMolecule *ObjectMoleculeReadTOPStr(PyMOLGlobals * G, ObjectMolecule * I,
char *TOPStr, int frame, int discrete) char *TOPStr, int frame, int discrete)
{ {
CoordSet *cset = NULL; CoordSet *cset = NULL;
AtomInfoType *atInfo; pymol::vla<AtomInfoType> atInfo(1);
int ok = true; int ok = true;
int isNew = true; int isNew = true;
unsigned int nAtom = 0; unsigned int nAtom = 0;
if(!I) if(!I)
isNew = true; isNew = true;
else else
isNew = false; isNew = false;
if(ok) { if(ok) {
if(isNew) { if(isNew) {
I = (ObjectMolecule *) ObjectMoleculeNew(G, discrete); I = (ObjectMolecule *) ObjectMoleculeNew(G, discrete);
CHECKOK(ok, I); CHECKOK(ok, I);
if (ok) if (ok)
atInfo = I->AtomInfo; std::swap(atInfo, I->AtomInfo);
isNew = true;
} else { /* never */
atInfo = (AtomInfoType*) VLAMalloc(10, sizeof(AtomInfoType), 2, true);
/* autozero here is important */
CHECKOK(ok, atInfo);
isNew = false;
} }
if(ok && isNew) { if(ok && isNew) {
I->Obj.Color = AtomInfoUpdateAutoColor(G); I->Obj.Color = AtomInfoUpdateAutoColor(G);
} }
if (ok) if (ok)
cset = ObjectMoleculeTOPStr2CoordSet(G, TOPStr, &atInfo); cset = ObjectMoleculeTOPStr2CoordSet(G, TOPStr, &atInfo);
CHECKOK(ok, cset); CHECKOK(ok, cset);
} }
skipping to change at line 2472 skipping to change at line 2449
AtomInfoType *ai = atInfo; AtomInfoType *ai = atInfo;
for(a = 0; a < nAtom; a++) { for(a = 0; a < nAtom; a++) {
(ai++)->discrete_state = fp1; (ai++)->discrete_state = fp1;
} }
} }
cset->Obj = I; cset->Obj = I;
cset->enumIndices(); cset->enumIndices();
cset->invalidateRep(cRepAll, cRepInvRep); cset->invalidateRep(cRepAll, cRepInvRep);
if(isNew) { if(isNew) {
I->AtomInfo = atInfo; /* IMPORTANT to reassign: this VLA may have move d! */ std::swap(I->AtomInfo, atInfo);
} else if (ok){ } else if (ok){
ok &= ObjectMoleculeMerge(I, atInfo, cset, false, cAIC_AllMask, true); /* NOTE: will release atInfo */ ok &= ObjectMoleculeMerge(I, std::move(atInfo), cset, false, cAIC_AllMask, true);
} }
if(isNew) if(isNew)
I->NAtom = nAtom; I->NAtom = nAtom;
/* /*
if(frame<0) frame=I->NCSet; if(frame<0) frame=I->NCSet;
VLACheck(I->CSet,CoordSet*,frame); VLACheck(I->CSet,CoordSet*,frame);
if(I->NCSet<=frame) I->NCSet=frame+1; if(I->NCSet<=frame) I->NCSet=frame+1;
if(I->CSet[frame]) I->CSet[frame]->fFree(I->CSet[frame]); if(I->CSet[frame]) I->CSet[frame]->fFree(I->CSet[frame]);
I->CSet[frame] = cset; I->CSet[frame] = cset;
*/ */
skipping to change at line 3261 skipping to change at line 3238
LexAssign(G, ai->name, 0); LexAssign(G, ai->name, 0);
ai++; ai++;
} }
} }
} }
result = AtomInfoUniquefyNames(I->Obj.G, NULL, 0, I->AtomInfo, flag, I->NAtom) ; result = AtomInfoUniquefyNames(I->Obj.G, NULL, 0, I->AtomInfo, flag, I->NAtom) ;
return result; return result;
} }
/*========================================================================*/ /*========================================================================*/
int ObjectMoleculeAddSeleHydrogens(ObjectMolecule * I, int sele, int state)
{
int a, b;
int n, nn;
CoordSet *cs;
CoordSet *tcs;
int seleFlag = false;
AtomInfoType *ai, *nai, fakeH;
int repeatFlag = false;
int nH;
int *index;
float v[3], v0[3];
float d;
int ok = true;
UtilZeroMem(&fakeH, sizeof(AtomInfoType));
fakeH.protons = 1;
ai = I->AtomInfo;
for(a = 0; a < I->NAtom; a++) {
if(SelectorIsMember(I->Obj.G, ai->selEntry, sele)) {
seleFlag = true;
break;
}
ai++;
}
if(seleFlag) {
if(!ObjectMoleculeVerifyChemistry(I, state)) {
ErrMessage(I->Obj.G, " AddHydrogens", "missing chemical geometry informati
on.");
} else if(I->DiscreteFlag) {
ErrMessage(I->Obj.G, " AddHydrogens", "can't modify a discrete object.");
} else {
repeatFlag = true;
while(ok && repeatFlag) {
repeatFlag = false;
nH = 0;
if (ok)
ok &= ObjectMoleculeUpdateNeighbors(I);
nai = (AtomInfoType *) VLAMalloc(1000, sizeof(AtomInfoType), 1, true);
CHECKOK(ok, nai);
ai = I->AtomInfo;
for(a = 0; ok && a < I->NAtom; a++) {
if(SelectorIsMember(I->Obj.G, ai->selEntry, sele)) {
n = I->Neighbor[a];
nn = I->Neighbor[n++];
if(nn < ai->valence) {
VLACheck(nai, AtomInfoType, nH);
CHECKOK(ok, nai);
UtilNCopy((nai + nH)->elem, "H", 2);
(nai + nH)->geom = cAtomInfoSingle;
(nai + nH)->valence = 1;
(nai + nH)->temp1 = a; /* borrowing this field temporarily */
if (ok)
ok &= ObjectMoleculePrepareAtom(I, a, nai + nH);
nH++;
}
}
ai++;
}
if(nH) {
repeatFlag = true;
if (ok)
cs = CoordSetNew(I->Obj.G);
CHECKOK(ok, cs);
if (ok)
cs->Coord = VLAlloc(float, nH * 3);
CHECKOK(ok, cs->Coord);
if (ok){
cs->NIndex = nH;
index = Alloc(int, nH);
CHECKOK(ok, index);
if (ok){
for(a = 0; a < nH; a++) {
index[a] = (nai + a)->temp1;
}
}
}
if(ok)
cs->enumIndices();
if (ok){
cs->TmpLinkBond = VLACalloc(BondType, nH);
CHECKOK(ok, cs->TmpLinkBond);
if (ok){
for(a = 0; a < nH; a++) {
cs->TmpLinkBond[a].index[0] = (nai + a)->temp1;
cs->TmpLinkBond[a].index[1] = a;
cs->TmpLinkBond[a].order = 1;
cs->TmpLinkBond[a].stereo = 0;
cs->TmpLinkBond[a].id = -1;
#ifdef _PYMOL_IP_EXTRAS
cs->TmpLinkBond[a].oldid = -1;
#endif
}
cs->NTmpLinkBond = nH;
}
}
AtomInfoUniquefyNames(I->Obj.G, I->AtomInfo, I->NAtom, nai, NULL, nH);
if (ok)
ok &= ObjectMoleculeMerge(I, nai, cs, false, cAIC_AllMask, true); /
* will free nai and cs->TmpLinkBond */
if (ok)
ok &= ObjectMoleculeExtendIndices(I, state);
if (ok)
ok &= ObjectMoleculeUpdateNeighbors(I);
// copy of the idx -> atm mapping
std::vector<int> mergedIdxToAtm(cs->IdxToAtm, cs->IdxToAtm + cs->NInde
x);
for(b = 0; ok && b < I->NCSet; b++) { /* add coordinate into the
coordinate set */
tcs = I->CSet[b];
if(tcs) {
int idx = 0;
for(a = 0; ok && a < nH; a++) {
if(!ObjectMoleculeGetAtomVertex(I, b, index[a], v0)) {
continue;
}
ObjectMoleculeFindOpenValenceVector(I, b, index[a], v, NULL, -1)
;
d = AtomInfoGetBondLength(I->Obj.G, I->AtomInfo + index[a], &fak
eH);
scale3f(v, d, v);
add3f(v0, v, cs->Coord + 3 * idx);
cs->IdxToAtm[idx] = mergedIdxToAtm[a];
++idx;
}
cs->NIndex = idx;
if (ok)
ok &= CoordSetMerge(I, tcs, cs);
}
}
FreeP(index);
cs->fFree();
if (ok)
ok &= ObjectMoleculeSort(I);
ObjectMoleculeUpdateIDNumbers(I);
} else {
VLAFreeP(nai);
}
}
}
}
return ok;
}
static int AddCoordinateIntoCoordSet(ObjectMolecule * I, int a, CoordSet *tcs, static int AddCoordinateIntoCoordSet(ObjectMolecule * I, int a, CoordSet *tcs,
int *AtmToIdx, CoordSet *cs, float *backup, int mode, int at0, int *AtmToIdx, CoordSet *cs, float *backup, int mode, int at0,
int index0, int move_flag, float *va1, float *vh1, int index0, int move_flag, float *va1, float *vh1,
float *x1, float *y1, float *z1, float d, int ca0) { float *x1, float *y1, float *z1, float d, int ca0) {
float *f0, *f1; float *f0, *f1;
int b; int b;
int ch0; int ch0;
float vh0[3]; float vh0[3];
float va0[3] = { 0.0F, 0.0F, 0.0F }; float va0[3] = { 0.0F, 0.0F, 0.0F };
float x0[3], y0[3], z0[3]; float x0[3], y0[3], z0[3];
skipping to change at line 3481 skipping to change at line 3313
} }
return ok; return ok;
} }
/*========================================================================*/ /*========================================================================*/
int ObjectMoleculeFuse(ObjectMolecule * I, int index0, ObjectMolecule * src, int ObjectMoleculeFuse(ObjectMolecule * I, int index0, ObjectMolecule * src,
int index1, int mode, int move_flag) int index1, int mode, int move_flag)
{ {
PyMOLGlobals *G = I->Obj.G; PyMOLGlobals *G = I->Obj.G;
int a; int a;
AtomInfoType *ai0, *ai1, *nai; AtomInfoType *ai0, *ai1;
int n, nn; int n, nn;
int at0 = -1; int at0 = -1;
int at1 = -1; int at1 = -1;
int a0, a1; int a0, a1;
int hydr1 = -1; int hydr1 = -1;
int anch1 = -1; int anch1 = -1;
BondType *b0, *b1; BondType *b0, *b1;
float *backup = NULL; float *backup = NULL;
// float d; // float d;
CoordSet *cs = NULL, *scs = NULL; CoordSet *cs = NULL, *scs = NULL;
skipping to change at line 3547 skipping to change at line 3379
if(src->NCSet) { if(src->NCSet) {
scs = src->CSet[state1]; scs = src->CSet[state1];
anch1 = scs->AtmToIdx[at1]; anch1 = scs->AtmToIdx[at1];
} }
break; break;
} }
if((at0 >= 0) && (at1 >= 0) && scs && (anch1 >= 0)) { /* have anchors and sour ce coordinate set */ if((at0 >= 0) && (at1 >= 0) && scs && (anch1 >= 0)) { /* have anchors and sour ce coordinate set */
nai = (AtomInfoType *) VLAMalloc(src->NAtom, sizeof(AtomInfoType), 1, true); auto nai = pymol::vla<AtomInfoType>(src->NAtom);
CHECKOK(ok, nai);
/* copy atoms and atom info into a 1:1 direct mapping */ /* copy atoms and atom info into a 1:1 direct mapping */
if (ok) if (ok)
cs = CoordSetNew(I->Obj.G); cs = CoordSetNew(I->Obj.G);
CHECKOK(ok, cs); CHECKOK(ok, cs);
if (ok) if (ok)
cs->Coord = VLAlloc(float, scs->NIndex * 3); cs->Coord = VLAlloc(float, scs->NIndex * 3);
CHECKOK(ok, cs->Coord); CHECKOK(ok, cs->Coord);
if (ok) if (ok)
cs->NIndex = scs->NIndex; cs->NIndex = scs->NIndex;
if (ok){ if (ok){
skipping to change at line 3656 skipping to change at line 3487
/* set up tags which will enable use to continue editing bond */ /* set up tags which will enable use to continue editing bond */
if(ok && edit) { if(ok && edit) {
for(a = 0; a < I->NAtom; a++) { for(a = 0; a < I->NAtom; a++) {
I->AtomInfo[a].temp1 = 0; I->AtomInfo[a].temp1 = 0;
} }
I->AtomInfo[at0].temp1 = 1; I->AtomInfo[at0].temp1 = 1;
} }
if (ok) if (ok)
ok &= ObjectMoleculeMerge(I, nai, cs, false, cAIC_AllMask, true); ok &= ObjectMoleculeMerge(I, std::move(nai), cs, false, cAIC_AllMask, true );
/* will free nai, cs->TmpBond and cs->TmpLinkBond */ /* will free nai, cs->TmpBond and cs->TmpLinkBond */
if (ok){ if (ok){
if (I->DiscreteFlag){ if (I->DiscreteFlag){
for(a = 0; a < I->NCSet; a++) { for(a = 0; a < I->NCSet; a++) {
CoordSet *qcs = I->CSet[a]; CoordSet *qcs = I->CSet[a];
if(qcs) { if(qcs) {
qcs->tmp_index = a; qcs->tmp_index = a;
} }
} }
if (ok) if (ok)
skipping to change at line 3772 skipping to change at line 3603
} }
ai++; ai++;
} }
} }
if(flag) if(flag)
result = true; result = true;
return (result); return (result);
} }
/*========================================================================*/ /*========================================================================*/
int ObjectMoleculeAttach(ObjectMolecule * I, int index, AtomInfoType * nai) int ObjectMoleculeAttach(ObjectMolecule * I, int index,
pymol::vla<AtomInfoType>&& nai)
{ {
int a; int a;
AtomInfoType *ai; AtomInfoType *ai;
float v[3], v0[3], d; float v[3], v0[3], d;
CoordSet *cs = NULL; CoordSet *cs = NULL;
int ok = false; int ok = false;
ok_assert(1, ObjectMoleculeUpdateNeighbors(I)); ok_assert(1, ObjectMoleculeUpdateNeighbors(I));
ai = I->AtomInfo + index; ai = I->AtomInfo + index;
skipping to change at line 3803 skipping to change at line 3635
cs->TmpLinkBond->index[1] = 0; cs->TmpLinkBond->index[1] = 0;
cs->TmpLinkBond->order = 1; cs->TmpLinkBond->order = 1;
cs->TmpLinkBond->stereo = 0; cs->TmpLinkBond->stereo = 0;
cs->TmpLinkBond->id = -1; cs->TmpLinkBond->id = -1;
cs->enumIndices(); cs->enumIndices();
ok_assert(1, ObjectMoleculePrepareAtom(I, index, nai)); ok_assert(1, ObjectMoleculePrepareAtom(I, index, nai));
d = AtomInfoGetBondLength(I->Obj.G, ai, nai); d = AtomInfoGetBondLength(I->Obj.G, ai, nai);
ok_assert(1, ObjectMoleculeMerge(I, nai, cs, false, cAIC_AllMask, true)); // w ok_assert(1, ObjectMoleculeMerge(I, std::move(nai),
ill free nai and cs->TmpLinkBond cs, false, cAIC_AllMask, true)); // will free nai and cs->TmpLinkBond
ok_assert(1, ObjectMoleculeExtendIndices(I, -1)); ok_assert(1, ObjectMoleculeExtendIndices(I, -1));
ok_assert(1, ObjectMoleculeUpdateNeighbors(I)); ok_assert(1, ObjectMoleculeUpdateNeighbors(I));
for(a = 0; a < I->NCSet; a++) { /* add atom to each coordinate set */ for(a = 0; a < I->NCSet; a++) { /* add atom to each coordinate set */
if(I->CSet[a]) { if(I->CSet[a]) {
ObjectMoleculeGetAtomVertex(I, a, index, v0); ObjectMoleculeGetAtomVertex(I, a, index, v0);
ObjectMoleculeFindOpenValenceVector(I, a, index, v, NULL, -1); ObjectMoleculeFindOpenValenceVector(I, a, index, v, NULL, -1);
scale3f(v, d, v); scale3f(v, d, v);
add3f(v0, v, cs->Coord); add3f(v0, v, cs->Coord);
ok_assert(1, CoordSetMerge(I, I->CSet[a], cs)); ok_assert(1, CoordSetMerge(I, I->CSet[a], cs));
skipping to change at line 3830 skipping to change at line 3663
ok = true; ok = true;
ok_except1: ok_except1:
cs->fFree(); cs->fFree();
return ok; return ok;
} }
/*========================================================================*/ /*========================================================================*/
int ObjectMoleculeFillOpenValences(ObjectMolecule * I, int index) int ObjectMoleculeFillOpenValences(ObjectMolecule * I, int index)
{ {
int a; int a;
AtomInfoType *ai, *nai; AtomInfoType *ai;
int n, nn; int n, nn;
int result = 0; int result = 0;
int flag = true; int flag = true;
float v[3], v0[3], d; float v[3], v0[3], d;
CoordSet *cs = NULL; CoordSet *cs = NULL;
int ok = true; int ok = true;
if((index >= 0) && (index <= I->NAtom)) { if((index >= 0) && (index <= I->NAtom)) {
while(ok) { while(ok) {
if (ok) if (ok)
skipping to change at line 3875 skipping to change at line 3708
cs->TmpLinkBond->index[1] = 0; cs->TmpLinkBond->index[1] = 0;
cs->TmpLinkBond->order = 1; cs->TmpLinkBond->order = 1;
cs->TmpLinkBond->stereo = 0; cs->TmpLinkBond->stereo = 0;
cs->TmpLinkBond->id = -1; cs->TmpLinkBond->id = -1;
} }
} }
if(ok) if(ok)
cs->enumIndices(); cs->enumIndices();
if (ok) auto atInfo = pymol::vla<AtomInfoType>(1);
nai = (AtomInfoType *) VLAMalloc(1, sizeof(AtomInfoType), 1, true); AtomInfoType* nai = atInfo.data();
CHECKOK(ok, nai);
if (ok){ if (ok){
UtilNCopy(nai->elem, "H", 2); UtilNCopy(nai->elem, "H", 2);
nai->geom = cAtomInfoSingle; nai->geom = cAtomInfoSingle;
nai->valence = 1; nai->valence = 1;
ok &= ObjectMoleculePrepareAtom(I, index, nai); ok &= ObjectMoleculePrepareAtom(I, index, nai);
d = AtomInfoGetBondLength(I->Obj.G, ai, nai); d = AtomInfoGetBondLength(I->Obj.G, ai, nai);
if (ok) if (ok)
ok &= ObjectMoleculeMerge(I, nai, cs, false, cAIC_AllMask, true); ok &= ObjectMoleculeMerge(I, std::move(atInfo),
/* will free nai and cs->TmpLinkBond */ cs, false, cAIC_AllMask, true); /* will free nai and cs->Tmp
LinkBond */
} }
if (ok) if (ok)
ok &= ObjectMoleculeExtendIndices(I, -1); ok &= ObjectMoleculeExtendIndices(I, -1);
if (ok) if (ok)
ok &= ObjectMoleculeUpdateNeighbors(I); ok &= ObjectMoleculeUpdateNeighbors(I);
for(a = 0; ok && a < I->NCSet; a++) { /* add atom to each coordinate se t */ for(a = 0; ok && a < I->NCSet; a++) { /* add atom to each coordinate se t */
if(I->CSet[a]) { if(I->CSet[a]) {
ObjectMoleculeGetAtomVertex(I, a, index, v0); ObjectMoleculeGetAtomVertex(I, a, index, v0);
ObjectMoleculeFindOpenValenceVector(I, a, index, v, NULL, -1); ObjectMoleculeFindOpenValenceVector(I, a, index, v, NULL, -1);
scale3f(v, d, v); scale3f(v, d, v);
skipping to change at line 4408 skipping to change at line 4241
I->NCSet = n_state; I->NCSet = n_state;
FreeP(center); FreeP(center);
FreeP(count); FreeP(count);
FreeP(fsum); FreeP(fsum);
FreeP(max_sq); FreeP(max_sq);
ObjectMoleculeInvalidate(I, cRepSphere, cRepInvProp, -1); ObjectMoleculeInvalidate(I, cRepSphere, cRepInvProp, -1);
} }
/*========================================================================*/ /*========================================================================*/
void ObjectMoleculeReplaceAtom(ObjectMolecule * I, int index, AtomInfoType * ai) void ObjectMoleculeReplaceAtom(ObjectMolecule * I, int index, AtomInfoType&& ai)
{ {
if((index >= 0) && (index <= I->NAtom)) { if((index >= 0) && (index <= I->NAtom)) {
memcpy(I->AtomInfo + index, ai, sizeof(AtomInfoType)); I->AtomInfo[index] = std::move(ai);
ObjectMoleculeInvalidate(I, cRepAll, cRepInvAtoms, -1); ObjectMoleculeInvalidate(I, cRepAll, cRepInvAtoms, -1);
/* could we put in a refinement step here? */ /* could we put in a refinement step here? */
} }
} }
/*========================================================================*/ /*========================================================================*/
int ObjectMoleculePrepareAtom(ObjectMolecule * I, int index, AtomInfoType * ai, int ObjectMoleculePrepareAtom(ObjectMolecule * I, int index, AtomInfoType * ai,
bool uniquefy) bool uniquefy)
{ {
/* match existing properties of the old atom */ /* match existing properties of the old atom */
skipping to change at line 7176 skipping to change at line 7009
tmp = PyObject_GetAttrString(atom, "resn"); tmp = PyObject_GetAttrString(atom, "resn");
if(tmp) if(tmp)
ok = PConvPyObjectToStrMaxClean(tmp, buf, sizeof(buf) - 1); ok = PConvPyObjectToStrMaxClean(tmp, buf, sizeof(buf) - 1);
ai->resn = LexIdx(G, buf); ai->resn = LexIdx(G, buf);
if(!ok) if(!ok)
ErrMessage(G, "ObjectMoleculeChemPyModel2CoordSet", "can't read resn") ; ErrMessage(G, "ObjectMoleculeChemPyModel2CoordSet", "can't read resn") ;
Py_XDECREF(tmp); Py_XDECREF(tmp);
} }
if(ok) { if(ok) {
char resi[8];
tmp = PyObject_GetAttrString(atom, "resi");
if(tmp)
ok = PConvPyObjectToStrMaxClean(tmp, resi, sizeof(resi) - 1);
if(!ok)
ErrMessage(G, "ObjectMoleculeChemPyModel2CoordSet", "can't read resi")
;
else
ai->setResi(resi);
Py_XDECREF(tmp);
}
if(ok) {
tmp = PyObject_GetAttrString(atom, "ins_code"); tmp = PyObject_GetAttrString(atom, "ins_code");
if(tmp) { if(tmp) {
ResIdent tmp_ins_code; ResIdent tmp_ins_code;
ok = PConvPyObjectToStrMaxClean(tmp, tmp_ins_code, sizeof(ResIdent) - 1); ok = PConvPyObjectToStrMaxClean(tmp, tmp_ins_code, sizeof(ResIdent) - 1);
if(!ok) if(!ok)
ErrMessage(G, "ObjectMoleculeChemPyModel2CoordSet", "can't read ins_ code"); ErrMessage(G, "ObjectMoleculeChemPyModel2CoordSet", "can't read ins_ code");
else if(tmp_ins_code[0] != '?') { else if(tmp_ins_code[0] != '?') {
ai->setInscode(tmp_ins_code[0]); ai->setInscode(tmp_ins_code[0]);
} }
} }
skipping to change at line 7250 skipping to change at line 7071
Py_XDECREF(tmp); Py_XDECREF(tmp);
} }
if(ok) { if(ok) {
tmp = PyObject_GetAttrString(atom, "u_aniso"); tmp = PyObject_GetAttrString(atom, "u_aniso");
if(tmp) { if(tmp) {
float u[6]; float u[6];
if(PConvPyListToFloatArrayInPlace(tmp, u, 6)) { if(PConvPyListToFloatArrayInPlace(tmp, u, 6)) {
// only allocate if not all zero // only allocate if not all zero
if(u[0] || u[1] || u[2] || u[3] || u[4] || u[5]) if(u[0] || u[1] || u[2] || u[3] || u[4] || u[5])
memcpy(ai->get_anisou(), u, 6 * sizeof(float)); std::copy_n(u, 6, ai->get_anisou());
} }
Py_DECREF(tmp); Py_DECREF(tmp);
} }
} }
if(ok) { if(ok) {
tmp = PyObject_GetAttrString(atom, "q"); tmp = PyObject_GetAttrString(atom, "q");
if(tmp) if(tmp)
ok = PConvPyObjectToFloat(tmp, &ai->q); ok = PConvPyObjectToFloat(tmp, &ai->q);
if(!ok) if(!ok)
skipping to change at line 7353 skipping to change at line 7174
int color_index; int color_index;
ok = PConvPyObjectToInt(tmp, &color_index); ok = PConvPyObjectToInt(tmp, &color_index);
if(!ok) if(!ok)
ErrMessage(G, "ObjectMoleculeChemPyModel2CoordSet", "bad cartoon col or info"); ErrMessage(G, "ObjectMoleculeChemPyModel2CoordSet", "bad cartoon col or info");
else { else {
SettingSet(G, cSetting_cartoon_color, color_index, ai); SettingSet(G, cSetting_cartoon_color, color_index, ai);
} }
} }
Py_XDECREF(tmp); Py_XDECREF(tmp);
} }
if(ok && PyObject_HasAttrString(atom, "cartoon_transparency")) {
tmp = PyObject_GetAttrString(atom, "cartoon_transparency");
if(tmp) {
float alpha_val;
ok = PConvPyObjectToFloat(tmp, &alpha_val);
if(!ok)
ErrMessage(G, __FUNCTION__, "bad alpha value");
else {
SettingSet(G, cSetting_cartoon_transparency, alpha_val, ai);
}
}
Py_XDECREF(tmp);
}
if(ok && PyObject_HasAttrString(atom, "cartoon_trgb")) { if(ok && PyObject_HasAttrString(atom, "cartoon_trgb")) {
tmp = PyObject_GetAttrString(atom, "cartoon_trgb"); tmp = PyObject_GetAttrString(atom, "cartoon_trgb");
if(tmp) { if(tmp) {
unsigned int trgb; unsigned int trgb;
ok = PConvPyObjectToInt(tmp, (signed int *) &trgb); ok = PConvPyObjectToInt(tmp, (signed int *) &trgb);
if(!ok) if(!ok)
ErrMessage(G, "ObjectMoleculeChemPyModel2CoordSet", "bad cartoon col or info"); ErrMessage(G, "ObjectMoleculeChemPyModel2CoordSet", "bad cartoon col or info");
else { else {
char color_name[24]; char color_name[24];
sprintf(color_name, "0x%08x", trgb); sprintf(color_name, "0x%08x", trgb);
skipping to change at line 7589 skipping to change at line 7423
/*========================================================================*/ /*========================================================================*/
ObjectMolecule *ObjectMoleculeLoadChemPyModel(PyMOLGlobals * G, ObjectMolecule *ObjectMoleculeLoadChemPyModel(PyMOLGlobals * G,
ObjectMolecule * I, ObjectMolecule * I,
PyObject * model, int frame, int d iscrete) PyObject * model, int frame, int d iscrete)
{ {
#ifdef _PYMOL_NOPY #ifdef _PYMOL_NOPY
return NULL; return NULL;
#else #else
CoordSet *cset = NULL; CoordSet *cset = NULL;
AtomInfoType *atInfo; auto atInfo = pymol::vla<AtomInfoType>(10);
int ok = true; int ok = true;
int isNew = true; int isNew = true;
unsigned int nAtom = 0; unsigned int nAtom = 0;
int fractional = false; int fractional = false;
int connect_mode = -1; int connect_mode = -1;
int auto_bond = false; int auto_bond = false;
PyObject *tmp, *mol; PyObject *tmp, *mol;
if(!I) if(!I)
isNew = true; isNew = true;
else else
isNew = false; isNew = false;
if(ok) { if(ok) {
if(isNew) { if(isNew) {
I = (ObjectMolecule *) ObjectMoleculeNew(G, discrete); I = (ObjectMolecule *) ObjectMoleculeNew(G, discrete);
atInfo = I->AtomInfo; std::swap(atInfo, I->AtomInfo);
isNew = true; isNew = true;
} else { } else {
atInfo = (AtomInfoType*) VLAMalloc(10, sizeof(AtomInfoType), 2, true);
/* autozero here is important */
isNew = false;
if (discrete) if (discrete)
ObjectMoleculeSetDiscrete(G, I, true); ObjectMoleculeSetDiscrete(G, I, true);
} }
if(isNew) { if(isNew) {
I->Obj.Color = AtomInfoUpdateAutoColor(G); I->Obj.Color = AtomInfoUpdateAutoColor(G);
} }
cset = ObjectMoleculeChemPyModel2CoordSet(G, model, &atInfo); cset = ObjectMoleculeChemPyModel2CoordSet(G, model, &atInfo);
if(!cset) if(!cset)
skipping to change at line 7718 skipping to change at line 7550
AtomInfoType *ai = atInfo; AtomInfoType *ai = atInfo;
for(a = 0; a < nAtom; a++) { for(a = 0; a < nAtom; a++) {
(ai++)->discrete_state = fp1; (ai++)->discrete_state = fp1;
} }
} }
cset->Obj = I; cset->Obj = I;
cset->enumIndices(); cset->enumIndices();
cset->invalidateRep(cRepAll, cRepInvRep); cset->invalidateRep(cRepAll, cRepInvRep);
if(isNew) { if(isNew) {
I->AtomInfo = atInfo; /* IMPORTANT to reassign: this VLA may have move d! */ std::swap(I->AtomInfo, atInfo);
} else { } else {
ObjectMoleculeMerge(I, atInfo, cset, false, cAIC_AllMask, true); /* NOTE: will release atInfo */ ObjectMoleculeMerge(I, std::move(atInfo), cset, false, cAIC_AllMask, true) ;
} }
if(isNew) if(isNew)
I->NAtom = nAtom; I->NAtom = nAtom;
VLACheck(I->CSet, CoordSet *, frame); VLACheck(I->CSet, CoordSet *, frame);
if(I->NCSet <= frame) if(I->NCSet <= frame)
I->NCSet = frame + 1; I->NCSet = frame + 1;
if(I->CSet[frame]) if(I->CSet[frame])
I->CSet[frame]->fFree(); I->CSet[frame]->fFree();
I->CSet[frame] = cset; I->CSet[frame] = cset;
if(fractional && cset->Symmetry && cset->Symmetry->Crystal) { if(fractional && cset->Symmetry && cset->Symmetry->Crystal) {
skipping to change at line 7777 skipping to change at line 7609
int a; int a;
bool is_new = false; bool is_new = false;
if(frame < 0) { if(frame < 0) {
frame = I->NCSet; frame = I->NCSet;
} else if (frame < I->NCSet) { } else if (frame < I->NCSet) {
cset = I->CSet[frame]; cset = I->CSet[frame];
} }
if (!cset) { if (!cset) {
// template coordinate set, if available
cset = I->CSTmpl;
// find any coordinate set // find any coordinate set
for(a = 0; !cset && a < I->NCSet; ++a) for(a = 0; !cset && a < I->NCSet; ++a)
cset = I->CSet[a]; cset = I->CSet[a];
ok_assert(1, cset); ok_assert(1, cset);
cset = CoordSetCopy(cset); cset = CoordSetCopy(cset);
is_new = true; is_new = true;
} }
// check atom count // check atom count
if(coords_len != cset->NIndex * 3) { if(coords_len != cset->NIndex * 3) {
skipping to change at line 7864 skipping to change at line 7699
ok_raise(1); ok_raise(1);
} }
if(frame < 0) { if(frame < 0) {
frame = I->NCSet; frame = I->NCSet;
} else if (frame < I->NCSet) { } else if (frame < I->NCSet) {
cset = I->CSet[frame]; cset = I->CSet[frame];
} }
if (!cset) { if (!cset) {
// template coordinate set, if available
cset = I->CSTmpl;
// find any coordinate set // find any coordinate set
for(a = 0; !cset && a < I->NCSet; ++a) for(a = 0; !cset && a < I->NCSet; ++a)
cset = I->CSet[a]; cset = I->CSet[a];
ok_assert(1, cset); ok_assert(1, cset);
cset = CoordSetCopy(cset); cset = CoordSetCopy(cset);
is_new = true; is_new = true;
} }
// check atom count // check atom count
l = PySequence_Size(coords); l = PySequence_Size(coords);
skipping to change at line 8269 skipping to change at line 8107
// could eventually do PDB nomenclature charge assignment here... // could eventually do PDB nomenclature charge assignment here...
return; return;
} }
// Unfortunately, aromatic bonds (type 4) can't be used to determine // Unfortunately, aromatic bonds (type 4) can't be used to determine
// formal charges. The following uses a heuristic to guess bond orders // formal charges. The following uses a heuristic to guess bond orders
// for aromatic bonds. // for aromatic bonds.
auto valences = get_bond_order_sums(obj); auto valences = get_bond_order_sums(obj);
// (period currently incompatible with G->lex_const) // (period currently incompatible with G->lex_const)
lexidx_t lex_N_4 = LexBorrow(G, "N.4"); auto lex_N_4 = LexBorrow(G, "N.4");
for (int at = 0; at < obj->NAtom; ++at) { for (int at = 0; at < obj->NAtom; ++at) {
int fcharge = 0; int fcharge = 0;
auto ai = obj->AtomInfo + at; auto ai = obj->AtomInfo + at;
if (ai->protons == cAN_N) { if (ai->protons == cAN_N) {
if (ai->textType == lex_N_4) { if (ai->textType == lex_N_4) {
fcharge = 1; fcharge = 1;
} else if (valences[at] == 2) { } else if (valences[at] == 2) {
fcharge = -1; fcharge = -1;
skipping to change at line 8906 skipping to change at line 8744
/* /*
* Read one molecule in MOL2, MOL, SDF, MMD or XYZ format from the string pointe d * Read one molecule in MOL2, MOL, SDF, MMD or XYZ format from the string pointe d
* to by (*next_entry). All these formats (except MOL) support multiple * to by (*next_entry). All these formats (except MOL) support multiple
* concatenated entries in one file. If multiplex=1, then read only one * concatenated entries in one file. If multiplex=1, then read only one
* molecule (one state) and set the next_entry pointer to the beginning of the * molecule (one state) and set the next_entry pointer to the beginning of the
* next entry. Otherwise, read a multi-state molecule. * next entry. Otherwise, read a multi-state molecule.
*/ */
ObjectMolecule *ObjectMoleculeReadStr(PyMOLGlobals * G, ObjectMolecule * I, ObjectMolecule *ObjectMoleculeReadStr(PyMOLGlobals * G, ObjectMolecule * I,
const char **next_entry, const char **next_entry,
int content_format, int frame, cLoadType_t content_format, int frame,
int discrete, int quiet, int multiplex, int discrete, int quiet, int multiplex,
char *new_name, char *new_name,
short loadpropertiesall, OVLexicon *loadpro plex) short loadpropertiesall, OVLexicon *loadpro plex)
{ {
int ok = true; int ok = true;
CoordSet *cset = NULL; CoordSet *cset = NULL;
AtomInfoType *atInfo; pymol::vla<AtomInfoType> atInfo(nullptr);
int isNew; int isNew;
int nAtom; int nAtom;
const char *restart = NULL, *start = *next_entry; const char *restart = NULL, *start = *next_entry;
int repeatFlag = true; int repeatFlag = true;
int successCnt = 0; int successCnt = 0;
char tmpName[WordLength]; char tmpName[WordLength];
int deferred_tasks = false; int deferred_tasks = false;
int skip_out; int skip_out;
int connect = false; int connect = false;
int set_formal_charges = false; int set_formal_charges = false;
skipping to change at line 8938 skipping to change at line 8776
repeatFlag = false; repeatFlag = false;
skip_out = false; skip_out = false;
if(!I) if(!I)
isNew = true; isNew = true;
else else
isNew = false; isNew = false;
if(isNew) { if(isNew) {
I = (ObjectMolecule *) ObjectMoleculeNew(G, (discrete > 0)); I = (ObjectMolecule *) ObjectMoleculeNew(G, (discrete > 0));
atInfo = I->AtomInfo; std::swap(atInfo, I->AtomInfo);
} else { } else {
atInfo = (AtomInfoType*) VLAMalloc(10, sizeof(AtomInfoType), 2, true); /* autozero here is important */ atInfo = pymol::vla<AtomInfoType>(10);
} }
if(isNew) { if(isNew) {
I->Obj.Color = AtomInfoUpdateAutoColor(G); I->Obj.Color = AtomInfoUpdateAutoColor(G);
} }
restart = NULL; restart = NULL;
switch (content_format) { switch (content_format) {
case cLoadTypeMOL2: case cLoadTypeMOL2:
case cLoadTypeMOL2Str: case cLoadTypeMOL2Str:
skipping to change at line 8983 skipping to change at line 8821
cset = ObjectMoleculeMMDStr2CoordSet(G, start, &atInfo, &restart); cset = ObjectMoleculeMMDStr2CoordSet(G, start, &atInfo, &restart);
aic_mask = cAIC_MMDMask; aic_mask = cAIC_MMDMask;
break; break;
} }
if(!cset) { if(!cset) {
if(!isNew) if(!isNew)
VLAFreeP(atInfo); VLAFreeP(atInfo);
if(!successCnt) { if(!successCnt) {
if (isNew) if (isNew)
I->AtomInfo = atInfo; std::swap(I->AtomInfo, atInfo);
ObjectMoleculeFree(I); ObjectMoleculeFree(I);
I = NULL; I = NULL;
ok = false; ok = false;
} else { } else {
skip_out = true; skip_out = true;
} }
} }
if(ok && !skip_out) { if(ok && !skip_out) {
skipping to change at line 9027 skipping to change at line 8865
} }
} }
if(multiplex > 0) if(multiplex > 0)
UtilNCopy(tmpName, cset->Name, WordLength); UtilNCopy(tmpName, cset->Name, WordLength);
cset->Obj = I; cset->Obj = I;
cset->enumIndices(); cset->enumIndices();
cset->invalidateRep(cRepAll, cRepInvRep); cset->invalidateRep(cRepAll, cRepInvRep);
if(isNew) { if(isNew) {
I->AtomInfo = atInfo; /* IMPORTANT to reassign: this VLA may have move d! */ std::swap(I->AtomInfo, atInfo);
} else { } else {
ObjectMoleculeMerge(I, atInfo, cset, false, aic_mask, false); ObjectMoleculeMerge(I, std::move(atInfo), cset, false, aic_mask, false);
/* NOTE: will release atInfo */ /* NOTE: will release atInfo */
} }
if(isNew) if(isNew)
I->NAtom = nAtom; I->NAtom = nAtom;
if(frame < 0) if(frame < 0)
frame = I->NCSet; frame = I->NCSet;
VLACheck(I->CSet, CoordSet *, frame); VLACheck(I->CSet, CoordSet *, frame);
if(I->NCSet <= frame) if(I->NCSet <= frame)
I->NCSet = frame + 1; I->NCSet = frame + 1;
skipping to change at line 9092 skipping to change at line 8930
SceneCountFrames(G); SceneCountFrames(G);
ObjectMoleculeInvalidate(I, cRepAll, cRepInvAll, -1); ObjectMoleculeInvalidate(I, cRepAll, cRepInvAll, -1);
ObjectMoleculeUpdateIDNumbers(I); ObjectMoleculeUpdateIDNumbers(I);
ObjectMoleculeUpdateNonbonded(I); ObjectMoleculeUpdateNonbonded(I);
} }
return (I); return (I);
} }
/*========================================================================*/ /*========================================================================*/
typedef int CompareFn(PyMOLGlobals *, const AtomInfoType *, const AtomInfoType * ); typedef int CompareFn(PyMOLGlobals *, const AtomInfoType *, const AtomInfoType * );
int ObjectMoleculeMerge(ObjectMolecule * I, AtomInfoType * ai, int ObjectMoleculeMerge(ObjectMolecule * I, pymol::vla<AtomInfoType>&& ai,
CoordSet * cs, int bondSearchFlag, int aic_mask, int inva lidate) CoordSet * cs, int bondSearchFlag, int aic_mask, int inva lidate)
{ {
PyMOLGlobals *G = I->Obj.G; PyMOLGlobals *G = I->Obj.G;
int *index, *outdex, *a2i = NULL, *i2a = NULL; int *index, *outdex, *a2i = NULL, *i2a = NULL;
BondType *bond = NULL; BondType *bond = NULL;
int a, b, lb = 0, ac; int a, b, lb = 0, ac;
int c, nb, a1, a2; int c, nb, a1, a2;
int found; int found;
int nAt, nBd, nBond; int nAt, nBd, nBond;
int expansionFlag = false; int expansionFlag = false;
AtomInfoType *ai2;
int oldNAtom, oldNBond; int oldNAtom, oldNBond;
int ok = true; int ok = true;
oldNAtom = I->NAtom; oldNAtom = I->NAtom;
oldNBond = I->NBond; oldNBond = I->NBond;
/* first, sort the coodinate set */ /* first, sort the coodinate set */
index = AtomInfoGetSortedIndex(G, I, ai, cs->NIndex, &outdex); index = AtomInfoGetSortedIndex(G, I, ai, cs->NIndex, &outdex);
CHECKOK(ok, index); CHECKOK(ok, index);
if (!ok) if (!ok)
return false; return false;
for(b = 0; b < cs->NIndex; b++) for(b = 0; b < cs->NIndex; b++)
cs->IdxToAtm[b] = outdex[cs->IdxToAtm[b]]; cs->IdxToAtm[b] = outdex[cs->IdxToAtm[b]];
for(b = 0; b < cs->NIndex; b++) for(b = 0; b < cs->NIndex; b++)
cs->AtmToIdx[b] = -1; cs->AtmToIdx[b] = -1;
for(b = 0; b < cs->NIndex; b++) for(b = 0; b < cs->NIndex; b++)
cs->AtmToIdx[cs->IdxToAtm[b]] = b; cs->AtmToIdx[cs->IdxToAtm[b]] = b;
ai2 = (AtomInfoType *) VLAMalloc(cs->NIndex, sizeof(AtomInfoType), 5, true); auto ai2 = pymol::vla<AtomInfoType>(cs->NIndex);
/* autozero here is important */
CHECKOK(ok, ai2);
if (ok){ if (ok){
for(a = 0; a < cs->NIndex; a++) for(a = 0; a < cs->NIndex; a++)
ai2[a] = STD_MOVE(ai[index[a]]); /* creates a sorted list of atom inf o records */ ai2[a] = std::move(ai[index[a]]); /* creates a sorted list of atom in fo records */
} }
VLAFreeP(ai); ai = std::move(ai2);
ai = ai2;
/* now, match it up with the current object's atomic information */ /* now, match it up with the current object's atomic information */
if (ok){ if (ok){
for(a = 0; a < cs->NIndex; a++) { for(a = 0; a < cs->NIndex; a++) {
index[a] = -1; index[a] = -1;
outdex[a] = -1; outdex[a] = -1;
} }
} }
skipping to change at line 9247 skipping to change at line 9082
i2a = VLACalloc(int, cs->NIndex); i2a = VLACalloc(int, cs->NIndex);
CHECKOK(ok, i2a); CHECKOK(ok, i2a);
} }
if (ok){ if (ok){
for(a = 0; a < cs->NIndex; a++) { /* a is in original file space */ for(a = 0; a < cs->NIndex; a++) { /* a is in original file space */
a1 = cs->IdxToAtm[a]; /* a1 is in sorted atom info space */ a1 = cs->IdxToAtm[a]; /* a1 is in sorted atom info space */
a2 = index[a1]; a2 = index[a1];
i2a[a] = a2; /* a2 is in object space */ i2a[a] = a2; /* a2 is in object space */
if(a2 < oldNAtom) if(a2 < oldNAtom)
AtomInfoCombine(G, I->AtomInfo + a2, ai + a1, aic_mask); AtomInfoCombine(G, I->AtomInfo + a2, std::move(ai[a1]), aic_mask);
else else
*(I->AtomInfo + a2) = STD_MOVE(*(ai + a1)); I->AtomInfo[a2] = std::move(ai[a1]);
} }
} }
if(ok && I->DiscreteFlag) { if(ok && I->DiscreteFlag) {
ok = I->setNDiscrete(nAt); ok = I->setNDiscrete(nAt);
} }
cs->NAtIndex = nAt; cs->NAtIndex = nAt;
I->NAtom = nAt; I->NAtom = nAt;
skipping to change at line 9374 skipping to change at line 9209
} }
} else { } else {
ObjectMoleculeInvalidate(I, cRepAll, cRepInvAtoms, -1); ObjectMoleculeInvalidate(I, cRepAll, cRepInvAtoms, -1);
} }
} }
} }
return ok; return ok;
} }
/*========================================================================*/ /*========================================================================*/
void ObjectMoleculeAppendAtoms(ObjectMolecule * I, AtomInfoType * atInfo, CoordS
et * cs)
{
int a;
BondType *ii;
BondType *si;
AtomInfoType *src, *dest;
int nAtom, nBond;
if(I->NAtom) {
nAtom = I->NAtom + cs->NIndex;
VLACheck(I->AtomInfo, AtomInfoType, nAtom);
dest = I->AtomInfo + I->NAtom;
src = atInfo;
for(a = 0; a < cs->NIndex; a++)
*(dest++) = STD_MOVE(*(src++));
I->NAtom = nAtom;
VLAFreeP(atInfo);
} else {
if(I->AtomInfo)
VLAFreeP(I->AtomInfo);
I->AtomInfo = atInfo;
I->NAtom = cs->NIndex;
}
nBond = I->NBond + cs->NTmpBond;
if(!I->Bond)
I->Bond = VLACalloc(BondType, nBond);
VLACheck(I->Bond, BondType, nBond);
ii = I->Bond + I->NBond;
si = cs->TmpBond;
for(a = 0; a < cs->NTmpBond; a++) {
ii->index[0] = cs->IdxToAtm[si->index[0]];
ii->index[1] = cs->IdxToAtm[si->index[1]];
ii->order = si->order;
ii->stereo = si->stereo;
ii->id = -1;
ii++;
si++;
}
I->NBond = nBond;
}
/*========================================================================*/
CoordSet *ObjectMoleculeGetCoordSet(ObjectMolecule * I, int setIndex) CoordSet *ObjectMoleculeGetCoordSet(ObjectMolecule * I, int setIndex)
{ {
if((setIndex >= 0) && (setIndex < I->NCSet)) if((setIndex >= 0) && (setIndex < I->NCSet))
return (I->CSet[setIndex]); return (I->CSet[setIndex]);
else else
return (NULL); return (NULL);
} }
/*========================================================================*/ /*========================================================================*/
void ObjectMoleculeTransformTTTf(ObjectMolecule * I, float *ttt, int frame) void ObjectMoleculeTransformTTTf(ObjectMolecule * I, float *ttt, int frame)
skipping to change at line 9565 skipping to change at line 9358
} }
} }
if(inv_flag && cs) { if(inv_flag && cs) {
cs->invalidateRep(cRepAll, cRepInvRep); cs->invalidateRep(cRepAll, cRepInvRep);
} }
} }
} }
} }
break; break;
case OMOP_AddHydrogens: case OMOP_AddHydrogens:
if (ok) if (ok) {
if (!op->i2)
ok &= ObjectMoleculeAddSeleHydrogensRefactored(I, sele, op->i1); ok &= ObjectMoleculeAddSeleHydrogensRefactored(I, sele, op->i1);
else }
ok &= ObjectMoleculeAddSeleHydrogens(I, sele, -1); /* state? */
break; break;
case OMOP_FixHydrogens: case OMOP_FixHydrogens:
if (ok) if (ok)
ok &= ObjectMoleculeFixSeleHydrogens(I, sele, -1); /* state? */ ok &= ObjectMoleculeFixSeleHydrogens(I, sele, -1); /* state? */
break; break;
case OMOP_RevalenceFromSource: case OMOP_RevalenceFromSource:
case OMOP_RevalenceByGuessing: case OMOP_RevalenceByGuessing:
ai = I->AtomInfo; ai = I->AtomInfo;
for(a = 0; a < I->NAtom; a++) { for(a = 0; a < I->NAtom; a++) {
if(SelectorIsMember(G, ai->selEntry, sele)) { if(SelectorIsMember(G, ai->selEntry, sele)) {
skipping to change at line 10026 skipping to change at line 9817
} }
ai++; ai++;
} }
break; break;
case OMOP_GetChains: case OMOP_GetChains:
ai = I->AtomInfo; ai = I->AtomInfo;
for(a = 0; a < I->NAtom; a++) { for(a = 0; a < I->NAtom; a++) {
s = ai->selEntry; s = ai->selEntry;
if(SelectorIsMember(G, s, sele)) { if(SelectorIsMember(G, s, sele)) {
// pointer hack // pointer hack
((std::set<ov_word> *) (void*) op->ii1)->insert(ai->chain); ((std::set<lexidx_t> *) (void*) op->ii1)->insert(ai->chain);
op->i1++; op->i1++;
} }
ai++; ai++;
} }
break; break;
case OMOP_Spectrum: case OMOP_Spectrum:
ai = I->AtomInfo; ai = I->AtomInfo;
ai0 = NULL; ai0 = NULL;
for(a = 0; a < I->NAtom; a++) { for(a = 0; a < I->NAtom; a++) {
skipping to change at line 10426 skipping to change at line 10217
op->i2++; op->i2++;
break; break;
case OMOP_TTTF: case OMOP_TTTF:
hit_flag = true; hit_flag = true;
break; break;
case OMOP_LABL: case OMOP_LABL:
if(ok) { if(ok) {
if(!op->s1[0]) { if(!op->s1[0]) {
if(ai->label) { if(ai->label) {
op->i1--; /* negative if unlabelling */ op->i1--; /* negative if unlabelling */
OVLexicon_DecRef(I->Obj.G->Lexicon, ai->label); LexAssign(G, ai->label, 0);
ai->label = 0;
} }
ai->visRep &= ~cRepLabelBit; ai->visRep &= ~cRepLabelBit;
hit_flag = true; hit_flag = true;
} else { } else {
switch (op->i2) { switch (op->i2) {
case cExecutiveLabelEvalOn: case cExecutiveLabelEvalOn:
{ {
/* python label expression evaluation */ /* python label expression evaluation */
CoordSet *cs = NULL; CoordSet *cs = NULL;
if(I->DiscreteFlag && I->DiscreteCSet) { if(I->DiscreteFlag && I->DiscreteCSet) {
skipping to change at line 10822 skipping to change at line 10612
transformTTT44f3f(I->Obj.TTT, coord, v1); transformTTT44f3f(I->Obj.TTT, coord, v1);
coord = v1; coord = v1;
} }
} }
dist = (float) diff3f(coord, op->v1); dist = (float) diff3f(coord, op->v1);
if(dist > op->f1) if(dist > op->f1)
op->f1 = dist; op->f1 = dist;
op->i1++; op->i1++;
} }
break; break;
case OMOP_MDST:
if(I->DiscreteFlag) {
if(cs == I->DiscreteCSet[a])
a1 = I->DiscreteAtmToIdx[a];
else
a1 = -1;
} else
a1 = cs->AtmToIdx[a];
if(a1 >= 0) {
r = (float) diff3f(op->v1, cs->Coord + (3 * a1));
if(r > op->f1)
op->f1 = r;
}
break;
case OMOP_INVA: case OMOP_INVA:
if(!cs->objMolOpInvalidated) { if(!cs->objMolOpInvalidated) {
/* performance optimization: avoid repeatedly /* performance optimization: avoid repeatedly
calling invalidate on the same coord sets */ calling invalidate on the same coord sets */
if(I->DiscreteFlag) { if(I->DiscreteFlag) {
if(cs == I->DiscreteCSet[a]) if(cs == I->DiscreteCSet[a])
a1 = I->DiscreteAtmToIdx[a]; a1 = I->DiscreteAtmToIdx[a];
else else
a1 = -1; a1 = -1;
} else } else
skipping to change at line 11649 skipping to change at line 11425
result = CoordSetSetAtomVertex(I->CSet[state], index, v); result = CoordSetSetAtomVertex(I->CSet[state], index, v);
return (result); return (result);
} }
/*========================================================================*/ /*========================================================================*/
static void ObjectMoleculeRender(ObjectMolecule * I, RenderInfo * info) static void ObjectMoleculeRender(ObjectMolecule * I, RenderInfo * info)
{ {
PyMOLGlobals *G = I->Obj.G; PyMOLGlobals *G = I->Obj.G;
int state = info->state; int state = info->state;
CRay *ray = info->ray; CRay *ray = info->ray;
Picking **pick = info->pick; auto pick = info->pick;
int pass = info->pass; int pass = info->pass;
CoordSet *cs; CoordSet *cs;
int pop_matrix = false; int pop_matrix = false;
int use_matrices = SettingGet_i(I->Obj.G, I->Obj.Setting, NULL, cSetting_matri x_mode); int use_matrices = SettingGet_i(I->Obj.G, I->Obj.Setting, NULL, cSetting_matri x_mode);
if(use_matrices<0) use_matrices = 0; if(use_matrices<0) use_matrices = 0;
PRINTFD(I->Obj.G, FB_ObjectMolecule) PRINTFD(I->Obj.G, FB_ObjectMolecule)
" ObjectMolecule: rendering %s pass %d...\n", I->Obj.Name, pass ENDFD; " ObjectMolecule: rendering %s pass %d...\n", I->Obj.Name, pass ENDFD;
ObjectPrepareContext(&I->Obj, info); ObjectPrepareContext(&I->Obj, info);
skipping to change at line 11714 skipping to change at line 11490
} }
/*========================================================================*/ /*========================================================================*/
ObjectMolecule *ObjectMoleculeDummyNew(PyMOLGlobals * G, int type) ObjectMolecule *ObjectMoleculeDummyNew(PyMOLGlobals * G, int type)
{ {
ObjectMolecule *I = NULL; ObjectMolecule *I = NULL;
int nAtom; int nAtom;
float *coord = NULL; float *coord = NULL;
CoordSet *cset = NULL; CoordSet *cset = NULL;
AtomInfoType *atInfo = NULL;
int frame = -1; int frame = -1;
int ok = true; int ok = true;
I = ObjectMoleculeNew(G, false); I = ObjectMoleculeNew(G, false);
CHECKOK(ok, I); CHECKOK(ok, I);
if (!ok) if (!ok)
return NULL; return NULL;
nAtom = 1; nAtom = 1;
coord = VLAlloc(float, 3 * nAtom); coord = VLAlloc(float, 3 * nAtom);
CHECKOK(ok, coord); CHECKOK(ok, coord);
if (!ok){ if (!ok){
ObjectMoleculeFree(I); ObjectMoleculeFree(I);
return NULL; return NULL;
} }
zero3f(coord); zero3f(coord);
atInfo = (AtomInfoType*) VLAMalloc(10, sizeof(AtomInfoType), 2, true);
/* autozero here is important */
CHECKOK(ok, atInfo);
if (!ok){
VLAFreeP(coord);
ObjectMoleculeFree(I);
return NULL;
}
cset = CoordSetNew(G); cset = CoordSetNew(G);
CHECKOK(ok, cset); CHECKOK(ok, cset);
if (!ok){ if (!ok){
VLAFreeP(atInfo);
VLAFreeP(coord); VLAFreeP(coord);
ObjectMoleculeFree(I); ObjectMoleculeFree(I);
return NULL; return NULL;
} }
cset->NIndex = nAtom; cset->NIndex = nAtom;
cset->Coord = coord; cset->Coord = coord;
cset->TmpBond = NULL; cset->TmpBond = NULL;
cset->NTmpBond = 0; cset->NTmpBond = 0;
strcpy(cset->Name, "_origin"); strcpy(cset->Name, "_origin");
cset->Obj = I; cset->Obj = I;
cset->enumIndices(); cset->enumIndices();
ok &= ObjectMoleculeMerge(I, atInfo, cset, false, cAIC_IDMask, true); /* pymol::vla<AtomInfoType> atInfo(nAtom);
NOTE: will release atInfo */ ok &= ObjectMoleculeMerge(I, std::move(atInfo), cset, false, cAIC_IDMask, true
);
if (ok){ if (ok){
if(frame < 0) if(frame < 0)
frame = I->NCSet; frame = I->NCSet;
VLACheck(I->CSet, CoordSet *, frame); VLACheck(I->CSet, CoordSet *, frame);
CHECKOK(ok, I->CSet); CHECKOK(ok, I->CSet);
if (ok){ if (ok){
if(I->NCSet <= frame) if(I->NCSet <= frame)
I->NCSet = frame + 1; I->NCSet = frame + 1;
if(I->CSet[frame]) if(I->CSet[frame])
I->CSet[frame]->fFree(); I->CSet[frame]->fFree();
skipping to change at line 11839 skipping to change at line 11607
I->Obj.fInvalidate = (void (*)(CObject *, int rep, int level, int state)) I->Obj.fInvalidate = (void (*)(CObject *, int rep, int level, int state))
ObjectMoleculeInvalidate; ObjectMoleculeInvalidate;
I->Obj.fDescribeElement = (void (*)(CObject *, int index, char *buffer)) I->Obj.fDescribeElement = (void (*)(CObject *, int index, char *buffer))
ObjectMoleculeDescribeElement; ObjectMoleculeDescribeElement;
I->Obj.fGetSettingHandle = (CSetting ** (*)(CObject *, int state)) I->Obj.fGetSettingHandle = (CSetting ** (*)(CObject *, int state))
ObjectMoleculeGetSettingHandle; ObjectMoleculeGetSettingHandle;
I->Obj.fGetObjectState = (CObjectState * (*)(CObject *, int state)) I->Obj.fGetObjectState = (CObjectState * (*)(CObject *, int state))
ObjectMoleculeGetObjectState; ObjectMoleculeGetObjectState;
I->Obj.fGetCaption = (char *(*)(CObject *, char *, int)) ObjectMoleculeGetCapt ion; I->Obj.fGetCaption = (char *(*)(CObject *, char *, int)) ObjectMoleculeGetCapt ion;
I->AtomInfo = (AtomInfoType*) VLAMalloc(10, sizeof(AtomInfoType), 2, true); /* autozero here is important */ I->AtomInfo = pymol::vla<AtomInfoType>(10);
CHECKOK(ok, I->AtomInfo); CHECKOK(ok, I->AtomInfo);
if (!ok){ if (!ok){
ObjectMoleculeFree(I); ObjectMoleculeFree(I);
return NULL; return NULL;
} }
for(a = 0; a <= cUndoMask; a++) { for(a = 0; a <= cUndoMask; a++) {
I->UndoCoord[a] = NULL; I->UndoCoord[a] = NULL;
I->UndoState[a] = -1; I->UndoState[a] = -1;
} }
I->UndoIter = 0; I->UndoIter = 0;
/* ListInit(I->UndoData); */
return (I); return (I);
} }
/*========================================================================*/ /*========================================================================*/
ObjectMolecule *ObjectMoleculeCopy(const ObjectMolecule * obj) ObjectMolecule *ObjectMoleculeCopy(const ObjectMolecule * obj)
{ {
PyMOLGlobals * G = const_cast<PyMOLGlobals*>(obj->Obj.G); PyMOLGlobals * G = const_cast<PyMOLGlobals*>(obj->Obj.G);
int a; int a;
BondType *i0, *i1; BondType *i0, *i1;
AtomInfoType *a0, *a1;
OOCalloc(G, ObjectMolecule); OOCalloc(G, ObjectMolecule);
(*I) = (*obj); (*I) = (*obj);
I->Symmetry = SymmetryCopy(I->Symmetry); /* null-safe */ I->Symmetry = SymmetryCopy(I->Symmetry); /* null-safe */
I->UnitCellCGO = NULL; I->UnitCellCGO = NULL;
I->Neighbor = NULL; I->Neighbor = NULL;
I->Sculpt = NULL; I->Sculpt = NULL;
I->Obj.Setting = NULL; /* TODO - make a copy */ I->Obj.Setting = NULL; /* TODO - make a copy */
I->Obj.ViewElem = NULL; I->Obj.ViewElem = NULL;
I->Obj.gridSlotSelIndicatorsCGO = NULL; I->Obj.gridSlotSelIndicatorsCGO = NULL;
/* ListInit(I->UndoData); */
for(a = 0; a <= cUndoMask; a++) for(a = 0; a <= cUndoMask; a++)
I->UndoCoord[a] = NULL; I->UndoCoord[a] = NULL;
I->CSet = VLACalloc(CoordSet *, I->NCSet); /* auto-zero */ I->CSet = VLACalloc(CoordSet *, I->NCSet); /* auto-zero */
for(a = 0; a < I->NCSet; a++) { for(a = 0; a < I->NCSet; a++) {
I->CSet[a] = CoordSetCopy(obj->CSet[a]); I->CSet[a] = CoordSetCopy(obj->CSet[a]);
if (I->CSet[a]) if (I->CSet[a])
I->CSet[a]->Obj = I; I->CSet[a]->Obj = I;
} }
if(obj->CSTmpl) if(obj->CSTmpl)
skipping to change at line 11899 skipping to change at line 11664
I->DiscreteCSet = VLACalloc(CoordSet*, sz); I->DiscreteCSet = VLACalloc(CoordSet*, sz);
I->updateAtmToIdx(); I->updateAtmToIdx();
} }
I->Bond = VLACalloc(BondType, I->NBond); I->Bond = VLACalloc(BondType, I->NBond);
i0 = I->Bond; i0 = I->Bond;
i1 = obj->Bond; i1 = obj->Bond;
for(a = 0; a < I->NBond; a++) { for(a = 0; a < I->NBond; a++) {
AtomInfoBondCopy(G, i1++, i0++); AtomInfoBondCopy(G, i1++, i0++);
} }
I->AtomInfo = VLACalloc(AtomInfoType, I->NAtom); // unfortunately, the AtomInfoType is not copy-constructable yet
a0 = I->AtomInfo; // assert copy done correct
a1 = obj->AtomInfo; if (I->AtomInfo.size() != obj->AtomInfo.size()) {
throw "AtomInfo copy failed";
}
AtomInfoType *a0 = I->AtomInfo;
const AtomInfoType* a1 = obj->AtomInfo;
memset(a0, 0, sizeof(AtomInfoType) * I->NAtom);
for(a = 0; a < I->NAtom; a++) for(a = 0; a < I->NAtom; a++)
AtomInfoCopy(G, a1++, a0++); AtomInfoCopy(G, a1++, a0++);
return (I); return (I);
} }
/*========================================================================*/ /*========================================================================*/
/* /*
* Set the order of coordinate sets with an index array * Set the order of coordinate sets with an index array
skipping to change at line 11950 skipping to change at line 11720
void ObjectMoleculeFree(ObjectMolecule * I) void ObjectMoleculeFree(ObjectMolecule * I)
{ {
int a; int a;
SelectorPurgeObjectMembers(I->Obj.G, I); SelectorPurgeObjectMembers(I->Obj.G, I);
for(a = 0; a < I->NCSet; a++){ for(a = 0; a < I->NCSet; a++){
if(I->CSet[a]) { if(I->CSet[a]) {
I->CSet[a]->fFree(); I->CSet[a]->fFree();
I->CSet[a] = NULL; I->CSet[a] = NULL;
} }
} }
/* RemoveAllUndosForObjectMolecule(I); */
if(I->Symmetry) if(I->Symmetry)
SymmetryFree(I->Symmetry); SymmetryFree(I->Symmetry);
VLAFreeP(I->Neighbor); VLAFreeP(I->Neighbor);
VLAFreeP(I->DiscreteAtmToIdx); VLAFreeP(I->DiscreteAtmToIdx);
VLAFreeP(I->DiscreteCSet); VLAFreeP(I->DiscreteCSet);
VLAFreeP(I->CSet); VLAFreeP(I->CSet);
#ifndef _PYMOL_NO_CXX11
I->m_ciffile.reset(); // free data I->m_ciffile.reset(); // free data
#endif
{ {
int nAtom = I->NAtom; int nAtom = I->NAtom;
AtomInfoType *ai = I->AtomInfo; AtomInfoType *ai = I->AtomInfo;
for(a = 0; a < nAtom; a++) { for(a = 0; a < nAtom; a++) {
AtomInfoPurge(I->Obj.G, ai); AtomInfoPurge(I->Obj.G, ai);
ai++; ai++;
} }
VLAFreeP(I->AtomInfo); VLAFreeP(I->AtomInfo);
skipping to change at line 12000 skipping to change at line 11767
} }
/*========================================================================*/ /*========================================================================*/
ObjectMolecule *ObjectMoleculeReadPDBStr(PyMOLGlobals * G, ObjectMolecule * I, ObjectMolecule *ObjectMoleculeReadPDBStr(PyMOLGlobals * G, ObjectMolecule * I,
const char *PDBStr, int state, int disc rete, const char *PDBStr, int state, int disc rete,
M4XAnnoType * m4x, char *pdb_name, M4XAnnoType * m4x, char *pdb_name,
const char **next_pdb, PDBInfoRec * pdb _info, const char **next_pdb, PDBInfoRec * pdb _info,
int quiet, int *model_number) int quiet, int *model_number)
{ {
CoordSet *cset = NULL; CoordSet *cset = NULL;
AtomInfoType *atInfo; pymol::vla<AtomInfoType> atInfo(nullptr);
int ok = true; int ok = true;
int isNew = true; int isNew = true;
unsigned int nAtom = 0; unsigned int nAtom = 0;
const char *start, *restart = NULL; const char *start, *restart = NULL;
int repeatFlag = true; int repeatFlag = true;
int successCnt = 0; int successCnt = 0;
unsigned int aic_mask = cAIC_PDBMask; unsigned int aic_mask = cAIC_PDBMask;
SegIdent segi_override = ""; /* saved segi for corrupted NMR pdb files */ SegIdent segi_override = ""; /* saved segi for corrupted NMR pdb files */
skipping to change at line 12025 skipping to change at line 11792
if(!I) if(!I)
isNew = true; isNew = true;
else else
isNew = false; isNew = false;
if(ok) { if(ok) {
if(isNew) { if(isNew) {
I = (ObjectMolecule *) ObjectMoleculeNew(G, discrete); I = (ObjectMolecule *) ObjectMoleculeNew(G, discrete);
CHECKOK(ok, I); CHECKOK(ok, I);
if (ok) if (ok)
atInfo = I->AtomInfo; std::swap(atInfo, I->AtomInfo);
isNew = true; isNew = true;
} else { } else {
atInfo = (AtomInfoType*) VLAMalloc(10, sizeof(AtomInfoType), 2, true); /* autozero here is important */ atInfo = pymol::vla<AtomInfoType>(10);
CHECKOK(ok, atInfo); CHECKOK(ok, atInfo);
isNew = false; isNew = false;
} }
if(ok && isNew) { if(ok && isNew) {
I->Obj.Color = AtomInfoUpdateAutoColor(G); I->Obj.Color = AtomInfoUpdateAutoColor(G);
if (pdb_info->variant == PDB_VARIANT_VDB || if (pdb_info->variant == PDB_VARIANT_VDB ||
pdb_info->variant == PDB_VARIANT_PQR) { pdb_info->variant == PDB_VARIANT_PQR) {
// pqr files have no chain identifier by default // pqr files have no chain identifier by default
// vdb files have same chain identifiers in all symmetry copies // vdb files have same chain identifiers in all symmetry copies
SettingSet(cSetting_retain_order, 1, (CObject *) I); SettingSet(cSetting_retain_order, 1, (CObject *) I);
} }
} }
if (ok) if (ok)
cset = ObjectMoleculePDBStr2CoordSet(G, start, &atInfo, &restart, cset = ObjectMoleculePDBStr2CoordSet(G, start, &atInfo, &restart,
segi_override, m4x, pdb_name, segi_override, m4x, pdb_name,
next_pdb, pdb_info, quiet, model_num ber); next_pdb, pdb_info, quiet, model_num ber);
if (isNew && atInfo != I->AtomInfo){
I->AtomInfo = atInfo;
}
CHECKOK(ok, cset); CHECKOK(ok, cset);
if (ok){ if (ok){
if(m4x){ /* preserve original atom IDs for annotated Met aphorics files */ if(m4x){ /* preserve original atom IDs for annotated Met aphorics files */
if(m4x->annotated_flag){ if(m4x->annotated_flag){
aic_mask = (cAIC_b | cAIC_q); aic_mask = (cAIC_b | cAIC_q);
} }
} }
nAtom = cset->NIndex; nAtom = cset->NIndex;
} }
} }
skipping to change at line 12078 skipping to change at line 11842
AtomInfoType *ai = atInfo; AtomInfoType *ai = atInfo;
for(a = 0; a < nAtom; a++) { for(a = 0; a < nAtom; a++) {
(ai++)->discrete_state = fp1; (ai++)->discrete_state = fp1;
} }
} }
cset->Obj = I; cset->Obj = I;
cset->enumIndices(); cset->enumIndices();
cset->invalidateRep(cRepAll, cRepInvRep); cset->invalidateRep(cRepAll, cRepInvRep);
if(isNew) { if(isNew) {
I->AtomInfo = atInfo; /* IMPORTANT to reassign: this VLA may have move d! */ std::swap(I->AtomInfo, atInfo);
} else { } else {
ok &= ObjectMoleculeMerge(I, atInfo, cset, true, aic_mask, true); ok &= ObjectMoleculeMerge(I, std::move(atInfo), cset, true, aic_mask, tr ue);
/* NOTE: will release atInfo */ /* NOTE: will release atInfo */
} }
if(isNew) if(isNew)
I->NAtom = nAtom; I->NAtom = nAtom;
if(state < 0) if(state < 0)
state = I->NCSet; state = I->NCSet;
if(*model_number > 0) { if(*model_number > 0) {
if(SettingGetGlobal_b(G, cSetting_pdb_honor_model_number)) if(SettingGetGlobal_b(G, cSetting_pdb_honor_model_number))
state = *model_number - 1; state = *model_number - 1;
} }
 End of changes. 71 change blocks. 
333 lines changed or deleted 82 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)