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 |