From 2cc6adceb69a7c4f55c743d4ec675991b2c4391b Mon Sep 17 00:00:00 2001 From: toshinagata1964 Date: Tue, 24 Jul 2012 09:17:35 +0000 Subject: [PATCH] Copy/paste of molecules was broken when it had atoms with more than ATOMS_CONNECTS_LIMIT bonds. Fixed. git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@264 a2be9bc6-48de-4e38-9406-05402d4bc13c --- MolLib/Molecule.c | 40 ++++++++++++++++++++++++++++++++++++++-- MolLib/Molecule.h | 6 +++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/MolLib/Molecule.c b/MolLib/Molecule.c index 77b36f6..9cc47b3 100755 --- a/MolLib/Molecule.c +++ b/MolLib/Molecule.c @@ -4936,6 +4936,18 @@ MoleculeDeserialize(const char *data, Int length, Int *timep) memmove(ap->frames, ptr, sizeof(Vector) * ap->nframes); ptr += sizeof(Vector) * ap->nframes; } + } else if (strcmp(data, "EXTCON") == 0) { + Atom *ap; + for (i = 0, ap = mp->atoms; i < mp->natoms; i++, ap = ATOM_NEXT(ap)) { + if (ap->nconnects <= ATOM_CONNECTS_LIMIT) + continue; + n = ap->nconnects; + ap->nconnects = 0; + ap->connects.ptr = NULL; + NewArray(&(ap->connects.ptr), &(ap->nconnects), sizeof(Int), n); + memmove(ap->connects.ptr, ptr, sizeof(Int) * n); + ptr += sizeof(Int) * n; + } } else if (strcmp(data, "BOND") == 0) { n = len / (sizeof(Int) * 2); NewArray(&mp->bonds, &mp->nbonds, sizeof(Int) * 2, n); @@ -5036,7 +5048,7 @@ char * MoleculeSerialize(Molecule *mp, Int *outLength, Int *timep) { char *ptr, *p; - int len, len_all, i, naniso, nframes; + int len, len_all, i, naniso, nframes, nconnects; /* Array of atoms */ len = 8 + sizeof(Int) + gSizeOfAtomRecord * mp->natoms; @@ -5047,7 +5059,7 @@ MoleculeSerialize(Molecule *mp, Int *outLength, Int *timep) *((Int *)(ptr + 8)) = gSizeOfAtomRecord * mp->natoms; p = ptr + 8 + sizeof(Int); memmove(p, mp->atoms, gSizeOfAtomRecord * mp->natoms); - naniso = nframes = 0; + naniso = nframes = nconnects = 0; for (i = 0; i < mp->natoms; i++) { Atom *ap = ATOM_AT_INDEX(p, i); if (ap->aniso != NULL) { @@ -5058,6 +5070,10 @@ MoleculeSerialize(Molecule *mp, Int *outLength, Int *timep) nframes += ap->nframes; ap->frames = NULL; } + if (ap->nconnects > ATOM_CONNECTS_LIMIT) { + nconnects += ap->nconnects; + ap->connects.ptr = NULL; + } } len_all = len; @@ -5102,6 +5118,26 @@ MoleculeSerialize(Molecule *mp, Int *outLength, Int *timep) len_all += len; } + /* Array of connects */ + if (nconnects > 0) { + len = 8 + sizeof(Int) + sizeof(Int) * nconnects; + ptr = (char *)realloc(ptr, len_all + len); + if (ptr == NULL) + goto out_of_memory; + p = ptr + len_all; + memmove(p, "EXTCON\0\0", 8); + *((Int *)(p + 8)) = sizeof(Int) * nconnects; + p += 8 + sizeof(Int); + for (i = 0; i < mp->natoms; i++) { + Atom *ap = ATOM_AT_INDEX(mp->atoms, i); + if (ap->nconnects > ATOM_CONNECTS_LIMIT) { + memmove(p, ap->connects.ptr, sizeof(Int) * ap->nconnects); + p += sizeof(Int) * ap->nconnects; + } + } + len_all += len; + } + /* Bonds, angles, dihedrals, impropers */ if (mp->nbonds > 0) { len = 8 + sizeof(Int) + sizeof(Int) * 2 * mp->nbonds; diff --git a/MolLib/Molecule.h b/MolLib/Molecule.h index d0618c8..db750f4 100755 --- a/MolLib/Molecule.h +++ b/MolLib/Molecule.h @@ -79,7 +79,7 @@ typedef struct Atom { union { Int *ptr; Int data[ATOM_CONNECTS_LIMIT]; - } connects; /* If nconnects >= ATOM_CONNECTS_LIMIT, memory is malloc()'ed; otherwise, data[] is used. */ + } connects; /* If nconnects > ATOM_CONNECTS_LIMIT, memory is malloc()'ed; otherwise, data[] is used. */ /* Int connects[ATOMS_MAX_CONNECTS]; */ Vector r; /* position */ Vector v; /* velocity */ @@ -111,8 +111,8 @@ extern Int gSizeOfAtomRecord; #define SYMOP_ALIVE(s) ((s.dx || s.dy || s.dz || s.sym) != 0) #define SYMOP_EQUAL(s1, s2) (s1.dx == s2.dx && s1.dy == s2.dy && s1.dz == s2.dz && s1.sym == s2.sym) -/* atom.connects is a union entry, including direct data for nconnects < ATOM_CONNECTS_LIMIT - and malloc()'ed entry for nconnects >= ATOM_CONNECTS_LIMIT. The following functions +/* atom.connects is a union entry, including direct data for nconnects <= ATOM_CONNECTS_LIMIT + and malloc()'ed entry for nconnects > ATOM_CONNECTS_LIMIT. The following functions automatically take care of the memory allocation/deallocation. */ Int *AtomConnects(Atom *ap); void AtomResizeConnects(Atom *ap, Int nconnects); -- 2.11.0