1 
2 /*
3 A* -------------------------------------------------------------------
4 B* This file contains source code for the PyMOL computer program
5 C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
6 D* -------------------------------------------------------------------
7 E* It is unlawful to modify or remove this copyright notice.
8 F* -------------------------------------------------------------------
9 G* Please see the accompanying LICENSE file for further information.
10 H* -------------------------------------------------------------------
11 I* Additional authors of this source file include:
12 -*
13 -*
14 -*
15 Z* -------------------------------------------------------------------
16 */
17 #ifndef _H_CoordSet
18 #define _H_CoordSet
19 
20 #include"os_python.h"
21 #include"Rep.h"
22 #include"Symmetry.h"
23 #include"Word.h"
24 #include"Setting.h"
25 #include"ObjectMolecule.h"
26 #include"vla.h"
27 
28 #define COORD_SET_HAS_ANISOU 0x01
29 
30 enum mmpymolx_prop_state_t {
31   MMPYMOLX_PROP_STATE_NULL = 0, // invalidated
32   MMPYMOLX_PROP_STATE_AUTO,     // auto-assigned (libmmpymolx)
33   MMPYMOLX_PROP_STATE_USER,     // user-assigned (cmd.alter)
34 };
35 
36 struct CoordSet : CObjectState {
37   enum {
38     NoPeriodicity = 0,
39     Orthogonal = 1,
40     Octahedral = 2,
41   };
42 
43   // methods (not fully refactored yet)
44   void fFree();
45 
46   // methods
47   void update(int state);
48   void render(RenderInfo * info);
49   void enumIndices();
50   void appendIndices(int offset);
51   int extendIndices(int nAtom);
52   void invalidateRep(int type, int level);
53   int atmToIdx(int atm) const;
54 
55   // read/write pointer to coordinate
coordPtrCoordSet56   float * coordPtr(int idx) {
57     return Coord + idx * 3;
58   }
59 
60   // read pointer to coordinate
coordPtrCoordSet61   const float * coordPtr(int idx) const {
62     return Coord + idx * 3;
63   }
64 
getAtomInfoCoordSet65   AtomInfoType * getAtomInfo(int idx) {
66     return Obj->AtomInfo + IdxToAtm[idx];
67   }
68 
69   // true if any atom in this coord set has any of the reps in "bitmask" shown
hasRepCoordSet70   bool hasRep(int bitmask) {
71     if (Obj->RepVisCache & bitmask)
72       for (int idx = 0; idx < NIndex; idx++)
73         if (getAtomInfo(idx)->visRep & bitmask)
74           return true;
75     return false;
76   }
77 
78   ObjectMolecule *Obj = nullptr;
79   pymol::vla<float> Coord;
80   pymol::vla<int> IdxToAtm;
81   pymol::vla<int> AtmToIdx;
82   int NIndex = 0, NAtIndex = 0, prevNIndex = 0, prevNAtIndex = 0;
83   ::Rep *Rep[cRepCnt] = {0};            /* an array of pointers to representations */
84   int Active[cRepCnt] = {0};          /* active flags */
85   int NTmpBond = 0;                 /* optional, temporary (for coord set transfers) */
86   pymol::vla<BondType> TmpBond;            /* actual bond info is stored in ObjectMolecule */
87   int NTmpLinkBond = 0;             /* optional, temporary storage of linkage  info. */
88   pymol::vla<BondType> TmpLinkBond;        /* first atom is in obj, second is in cset */
89   std::unique_ptr<CSymmetry> Symmetry;
90   WordType Name = {0};
91   std::vector<float> Spheroid;
92   std::vector<float> SpheroidNormal;
93   CSetting *Setting = nullptr;
94   /* for periodic MD boxes -- may be merge into symmetry lattice later... */
95   std::unique_ptr<CCrystal> PeriodicBox;
96   int PeriodicBoxType = NoPeriodicity;
97   int tmp_index = 0;                /* for saving */
98 
99   pymol::vla<LabPosType> LabPos;
100 
101   /* not saved in state */
102 
103   pymol::vla<RefPosType> RefPos;
104 
105   /* idea:
106      int start_atix, stop_atix <-- for discrete objects, we need
107      something like this that would enable pymol to skip atoms not in the
108      discrete state...question is: are these atoms sorted together right
109      now or not? probably not, and if not then we need to change sorting
110      for discrete objects to be state-dependent, but this could screw up
111      byres/bychain actions which assume such atoms to be adjancent...
112    */
113 
114   CGO *SculptCGO = nullptr;
115   CGO *SculptShaderCGO = nullptr;
116   MapType *Coord2Idx = nullptr;
117   float Coord2IdxReq = 0, Coord2IdxDiv = 0;
118 
119   /* temporary / optimization */
120 
121   int objMolOpInvalidated = 0;
122 #ifdef _PYMOL_IP_EXTRAS
123   mmpymolx_prop_state_t validMMStereo = MMPYMOLX_PROP_STATE_NULL;
124   mmpymolx_prop_state_t validTextType = MMPYMOLX_PROP_STATE_NULL;
125 #endif
126 
127 #ifdef _PYMOL_IP_PROPERTIES
128 #endif
129 
130   /* Atom-state Settings */
131   pymol::vla<int> atom_state_setting_id;
132   pymol::vla<char> has_atom_state_settings;
133 
134   // special member functions
135   CoordSet(PyMOLGlobals * G);
136   CoordSet(const CoordSet &cs);
137   ~CoordSet();
138 };
139 
140 typedef void (*fUpdateFn) (CoordSet *, int);
141 
142 int BondInOrder(BondType * a, int b1, int b2);
143 int BondCompare(BondType * a, BondType * b);
144 
145 PyObject *CoordSetAsNumPyArray(CoordSet * cs, short copy);
146 PyObject *CoordSetAsPyList(CoordSet * I);
147 int CoordSetFromPyList(PyMOLGlobals * G, PyObject * list, CoordSet ** cs);
148 
149 void CoordSetAtomToPDBStrVLA(PyMOLGlobals * G, char **charVLA, int *c,
150                              const AtomInfoType * ai,
151                              const float *v, int cnt,
152                              const PDBInfoRec * pdb_info,
153                              const double *matrix);
154 #define CoordSetNew(G) new CoordSet(G)
155 CoordSet* CoordSetCopy(const CoordSet* src);
156 
157 void CoordSetTransform44f(CoordSet * I, const float *mat);
158 void CoordSetTransform33f(CoordSet * I, const float *mat);
159 void CoordSetRealToFrac(CoordSet * I, const CCrystal * cryst);
160 void CoordSetFracToReal(CoordSet * I, const CCrystal * cryst);
161 
162 bool CoordSetInsureOrthogonal(PyMOLGlobals * G,
163     CoordSet * cset,
164     const float * sca,
165     const CCrystal *cryst=NULL,
166     bool quiet=true);
167 
168 void CoordSetGetAverage(const CoordSet * I, float *v0);
169 PyObject *CoordSetAtomToChemPyAtom(PyMOLGlobals * G, AtomInfoType * ai, const float *v,
170                                    const float *ref, int index, const double *matrix);
171 int CoordSetGetAtomVertex(const CoordSet * I, int at, float *v);
172 int CoordSetGetAtomTxfVertex(const CoordSet * I, int at, float *v);
173 int CoordSetSetAtomVertex(CoordSet * I, int at, const float *v);
174 int CoordSetMoveAtom(CoordSet * I, int at, const float *v, int mode);
175 int CoordSetMoveAtomLabel(CoordSet * I, int at, const float *v, const float *diff);
176 
177 int CoordSetTransformAtomTTTf(CoordSet * I, int at, const float *TTT);
178 int CoordSetTransformAtomR44f(CoordSet * I, int at, const float *matrix);
179 
180 int CoordSetValidateRefPos(CoordSet * I);
181 
182 void CoordSetPurge(CoordSet * I);
183 void CoordSetAdjustAtmIdx(CoordSet * I, int *lookup, int nAtom);
184 int CoordSetMerge(ObjectMolecule *OM, CoordSet * I, CoordSet * cs);        /* must be non-overlapping */
185 void CoordSetRecordTxfApplied(CoordSet * I, const float *TTT, int homogenous);
186 void CoordSetUpdateCoord2IdxMap(CoordSet * I, float cutoff);
187 
188 typedef struct _CCoordSetUpdateThreadInfo CCoordSetUpdateThreadInfo;
189 
190 void CoordSetUpdateThread(CCoordSetUpdateThreadInfo * T);
191 
192 void LabPosTypeCopy(const LabPosType * src, LabPosType * dst);
193 void RefPosTypeCopy(const RefPosType * src, RefPosType * dst);
194 
195 
196 #ifndef _PYMOL_NOPY
197 int CoordSetSetSettingFromPyObject(PyMOLGlobals * G, CoordSet *cs, int at, int setting_id, PyObject *val);
198 #endif
199 int CoordSetCheckSetting(PyMOLGlobals * G, CoordSet *cs, int at, int setting_id);
200 PyObject *SettingGetIfDefinedPyObject(PyMOLGlobals * G, CoordSet *cs, int at, int setting_id);
201 int CoordSetCheckUniqueID(PyMOLGlobals * G, CoordSet *cs, int at);
202 
203 #define AtomStateGetSetting_b     AtomStateGetSetting
204 #define AtomStateGetSetting_i     AtomStateGetSetting
205 #define AtomStateGetSetting_f     AtomStateGetSetting
206 #define AtomStateGetSetting_s     AtomStateGetSetting
207 #define AtomStateGetSetting_color AtomStateGetSetting
208 
209 #define ATOMSTATEGETSETTINGARGS PyMOLGlobals * G, \
210   const ObjectMolecule * obj, \
211   const CoordSet * cs, int idx, \
212   const AtomInfoType * ai, \
213   int setting_id
214 
215 template <typename V> void AtomStateGetSetting(ATOMSTATEGETSETTINGARGS, V * out);
216 
217 // atom-state level setting
SettingSet(int index,V value,CoordSet * cs,int idx)218 template <typename V> void SettingSet(int index, V value, CoordSet *cs, int idx) {
219   auto& G = cs->G;
220   CoordSetCheckUniqueID(G, cs, idx);
221   cs->has_atom_state_settings[idx] = true;
222   SettingUniqueSet(G, cs->atom_state_setting_id[idx], index, value);
223 }
224 
225 // object-state level setting
SettingSet(int index,V value,CoordSet * cs)226 template <typename V> void SettingSet(int index, V value, CoordSet *cs) {
227   SettingSet(cs->G, &cs->Setting, index, value);
228 }
229 
230 // Rotates the ANISOU vector
231 bool RotateU(const double *matrix, float *anisou);
232 
233 #endif
234