00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 00004 *cr University of Illinois 00005 *cr All Rights Reserved 00006 *cr 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * RCS INFORMATION: 00011 * 00012 * $RCSfile: GeometryList.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.66 $ $Date: 2019年01月17日 21:20:59 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * 00019 * This maintains a set of lists of geometry monitors, and draws them to 00020 * the scene. This is a Displayable which keeps the graphical representations 00021 * of the geometry monitors; this is also a Pickable, and creates and controls 00022 * the PickMode objects which create new geometry monitors via the pointers. 00023 * This object keeps a set of ResizeArray, each of which is a 'category' for 00024 * geometry monitors (i.e Atoms, Bonds, etc.) which contain GeometryMol objects. 00025 * 00026 ***************************************************************************/ 00027 00028 #include "GeometryList.h" 00029 #include "GeometryAtom.h" 00030 #include "GeometryBond.h" 00031 #include "GeometryAngle.h" 00032 #include "GeometryDihedral.h" 00033 #include "GeometrySpring.h" 00034 #include "DisplayDevice.h" 00035 #include "DispCmds.h" 00036 #include "MoleculeList.h" 00037 #include "utilities.h" 00038 #include "VMDApp.h" 00039 #include "Scene.h" 00040 #include "Inform.h" 00041 00042 // default colors to use 00043 #define ATOMGEOMCOL REGGREEN 00044 #define BONDGEOMCOL REGWHITE 00045 #define ANGLEGEOMCOL REGYELLOW 00046 #define DIHEGEOMCOL REGCYAN 00047 #define TUGGEOMCOL REGWHITE 00048 #define SPRINGGEOMCOL REGORANGE 00049 00050 00052 GeometryList::GeometryList(VMDApp *vmdapp, Displayable *disp) 00053 : Displayable(disp) { 00054 00055 // indicate we don't yet have a color object to use 00056 colorCat = (-1); 00057 00058 // save the list of molecules to use for data 00059 app = vmdapp; 00060 00061 // default size of text labels is 1.0 (no scaling) 00062 labelsize = 1.0f; 00063 labelthickness = 1.0f; 00064 00065 // create default lists for atom, bond, angle, and dihedral measurements 00066 add_geom_list("Atoms", ATOMGEOMCOL); 00067 add_geom_list("Bonds", BONDGEOMCOL); 00068 add_geom_list("Angles", ANGLEGEOMCOL); 00069 add_geom_list("Dihedrals", DIHEGEOMCOL); 00070 add_geom_list("Springs", SPRINGGEOMCOL); 00071 00072 colorCat = scene->add_color_category("Labels"); 00073 for (int i=0; i<num_lists(); i++) { 00074 scene->add_color_item(colorCat, geomLists.name(i), 00075 geomLists.data(i)->defaultColor); 00076 } 00077 00078 // Displayable characteristics 00079 rot_off(); 00080 scale_off(); 00081 glob_trans_off(); 00082 cent_trans_off(); 00083 } 00084 00085 00087 GeometryList::~GeometryList(void) { 00088 00089 // for all the lists, delete all geometry monitors 00090 for(int i=(num_lists() - 1); i >= 0; i--) 00091 del_geom_list(i); 00092 } 00093 00094 00096 00097 void GeometryList::do_color_changed(int clr) { 00098 if (clr == colorCat) { 00099 for (int i=0; i<num_lists(); i++) { 00100 GeomListPtr glist = geom_list(i); 00101 GeomListStruct *s = geomLists.data(i); 00102 int ind = scene->category_item_index(colorCat, geom_list_name(i)); 00103 int c = scene->category_item_value(colorCat, ind); 00104 s->curColor = c; 00105 for (int j=0; j<glist->num(); j++) 00106 (*glist)[j]->set_color(c); 00107 } 00108 } 00109 } 00110 00112 00113 // add a new category: specify the name, and default color. Return index of 00114 // new list. 00115 int GeometryList::add_geom_list(const char *nm, int clr) { 00116 00117 // make sure we do not already have a category with this name 00118 int oldlist = geom_list_index(nm); 00119 if(oldlist >= 0) 00120 return oldlist; 00121 00122 // create a new struct 00123 GeomListStruct *newlist = new GeomListStruct; 00124 newlist->geomList = new ResizeArray<GeometryMol *>(8); 00125 newlist->defaultColor = clr; 00126 newlist->curColor = clr; 00127 00128 // add the new category to the big list 00129 return geomLists.add_name(nm, newlist); 00130 } 00131 00132 00133 // delete the Nth category. Return success. 00134 int GeometryList::del_geom_list(int n) { 00135 GeomListStruct *oldlist = NULL; 00136 00137 // make sure we do have a category with this name 00138 if(n >= 0 && n < num_lists()) { 00139 // get data for Nth list 00140 oldlist = geomLists.data(n); 00141 GeomListPtr glist = oldlist->geomList; 00142 00143 // go through the list and delete all current GeometryMol objects 00144 for(int i=(glist->num() - 1); i >= 0; i--) { 00145 delete (*glist)[i]; 00146 } 00147 00148 // delete the old list storage and structure 00149 delete glist; 00150 delete oldlist; 00151 geomLists.set_data(n, (GeomListStruct *) NULL); 00152 } 00153 00154 // return whether we were successful 00155 return (oldlist != NULL); 00156 } 00157 00158 int GeometryList::add_geometry(const char *geomcatname, const int *molids, 00159 const int *atomids, const int *cells, float k, int toggle) { 00160 00161 // check that geometry category name is valid 00162 int geomcat = geom_list_index(geomcatname); 00163 GeometryMol *g = NULL; 00164 MoleculeList *mlist = app->moleculeList; 00165 if (geomcat == geom_list_index("Atoms")) 00166 g = new GeometryAtom(*molids, *atomids, cells, mlist, app->commandQueue, this); 00167 else if (geomcat == geom_list_index("Bonds")) 00168 g = new GeometryBond((int *)molids, (int *)atomids, cells, mlist, app->commandQueue, this); 00169 else if (geomcat == geom_list_index("Angles")) 00170 g = new GeometryAngle((int *)molids, (int *)atomids, cells, mlist, app->commandQueue, this); 00171 else if (geomcat == geom_list_index("Dihedrals")) 00172 g = new GeometryDihedral((int *)molids, (int *)atomids, cells, mlist, app->commandQueue, this); 00173 else if (geomcat == geom_list_index("Springs")) 00174 g = new GeometrySpring((int *)molids, (int *)atomids, mlist, app->commandQueue, k, this); 00175 else { 00176 msgErr << "Unknown geometry category '" << geomcatname << "'." << sendmsg; 00177 return -1; 00178 } 00179 if(g && g->ok()) { 00180 GeomListPtr glist = geom_list(geomcat); 00181 00182 // if there is already an identical label in the list, 00183 // do not add this one, instead toggle the displayed 00184 // status of the old one and return the index. 00185 for(int i=(glist->num() - 1); i >= 0; i--) { 00186 GeometryMol *g2 = (*glist)[i]; 00187 if(!strcmp(g2->unique_name(), g->unique_name())) { 00188 // name matches 00189 if (toggle) { 00190 if (g2->displayed()) 00191 g2->off(); 00192 else 00193 g2->on(); 00194 } 00195 00196 delete g; 00197 return i; 00198 } 00199 } 00200 00201 // spam the console 00202 msgInfo << "Added new " << geomcatname << " label " << g->name(); 00203 if (g->has_value()) 00204 msgInfo << " = " << g->calculate(); 00205 msgInfo << sendmsg; 00206 00207 // add the geometry object 00208 glist->append(g); 00209 00210 // calculate the value for the first time 00211 g->calculate(); 00212 00213 // set the color, which also causes the display list to be generated 00214 g->set_color(geomLists.data(geomcat)->curColor); 00215 g->set_text_size(labelsize); 00216 g->set_text_thickness(labelthickness); 00217 00218 // set the pick variables 00219 g->set_pick(); 00220 00221 // indicate we were successful; return index of this object 00222 return glist->num() - 1; 00223 } 00224 00225 // if here, something did not work 00226 return -1; 00227 } 00228 00229 00230 // del a new geometry object from the list with the given index. Return success. 00231 // if n < 0, delete all markers 00232 int GeometryList::del_geometry(int glindex, int n) { 00233 00234 // make sure the given GeometryMol object is OK 00235 if(glindex >= 0 && glindex < num_lists()) { 00236 00237 // get the list of geometry objects for the given index 00238 GeomListPtr glist = geom_list(glindex); 00239 00240 // make sure the geometry index is ok 00241 if(n >= 0 && n < glist->num()) { 00242 // delete and remove the geometry object 00243 delete (*glist)[n]; 00244 glist->remove(n); 00245 00246 // indicate we were successful 00247 return TRUE; 00248 } else if(n < 0) { 00249 // delete and remove all geometry objects 00250 for(int j=(glist->num() - 1); j >= 0; j--) { 00251 delete (*glist)[j]; 00252 glist->remove(j); 00253 } 00254 00255 // indicate we were successful 00256 return TRUE; 00257 } 00258 } 00259 00260 // if here, something did not work 00261 return FALSE; 00262 } 00263 00264 // toggle whether to show or hide a geometry monitor. If the monitor 00265 // specified is < 0, does so for all monitors in the given category 00266 int GeometryList::show_geometry(int glindex, int n, int s) { 00267 00268 // make sure the given GeometryMol object is OK 00269 if(glindex >= 0 && glindex < num_lists()) { 00270 00271 // get the list of geometry objects for the given index 00272 GeomListPtr glist = geom_list(glindex); 00273 00274 // make sure the geometry index is ok 00275 if(n >= 0 && n < glist->num()) { 00276 // hide or show the specified object 00277 if (s) 00278 (*glist)[n] -> on(); 00279 else 00280 (*glist)[n] -> off(); 00281 00282 00283 // indicate we were successful 00284 return TRUE; 00285 } else if(n < 0) { 00286 // delete and remove all geometry objects 00287 for(int j=(glist->num() - 1); j >= 0; j--) { 00288 if (s) 00289 (*glist)[j] -> on(); 00290 else 00291 (*glist)[j] -> off(); 00292 } 00293 00294 00295 // indicate we were successful 00296 return TRUE; 00297 } 00298 } 00299 00300 // if here, something did not work 00301 return FALSE; 00302 } 00303 00304 int GeometryList::setTextSize(float newsize) { 00305 if (newsize <= 0) 00306 return FALSE; 00307 00308 if (newsize == labelsize) return TRUE; 00309 00310 labelsize = newsize; 00311 for(int i=(num_lists() - 1); i >= 0; i--) { 00312 GeomListPtr glist = geom_list(i); 00313 for(int j=(glist->num() - 1); j >= 0; j--) { 00314 GeometryMol *g = (*glist)[j]; 00315 g->set_text_size(newsize); 00316 } 00317 } 00318 00319 return TRUE; 00320 } 00321 00322 int GeometryList::setTextThickness(float newthick) { 00323 if (newthick <= 0) 00324 return FALSE; 00325 00326 if (newthick == labelthickness) return TRUE; 00327 00328 labelthickness = newthick; 00329 for(int i=(num_lists() - 1); i >= 0; i--) { 00330 GeomListPtr glist = geom_list(i); 00331 for(int j=(glist->num() - 1); j >= 0; j--) { 00332 GeometryMol *g = (*glist)[j]; 00333 g->set_text_thickness(newthick); 00334 } 00335 } 00336 00337 return TRUE; 00338 } 00339 00340 const float *GeometryList::getTextOffset(const char *nm, int n) { 00341 GeomListPtr glist = geom_list(nm); 00342 if (!glist) return NULL; 00343 if (n < 0 || n >= glist->num()) return NULL; 00344 GeometryMol *g = (*glist)[n]; 00345 return g->text_offset(); 00346 } 00347 00348 int GeometryList::setTextOffset(const char *nm, int n, const float delta[2]) { 00349 00350 GeomListPtr glist = geom_list(nm); 00351 if (!glist) return FALSE; 00352 if (n < 0 || n >= glist->num()) return FALSE; 00353 GeometryMol *g = (*glist)[n]; 00354 g->set_text_offset(delta); 00355 return TRUE; 00356 } 00357 00358 const char *GeometryList::getTextFormat(const char *nm, int n) { 00359 // XXX get/set Text Offset/Format duplicate their first four lines... 00360 GeomListPtr glist = geom_list(nm); 00361 if (!glist) return NULL; 00362 if (n < 0 || n >= glist->num()) return NULL; 00363 GeometryMol *g = (*glist)[n]; 00364 return g->text_format(); 00365 } 00366 00367 int GeometryList::setTextFormat(const char *nm, int n, const char *format) { 00368 GeomListPtr glist = geom_list(nm); 00369 if (!glist) return FALSE; 00370 if (n < 0 || n >= glist->num()) return FALSE; 00371 GeometryMol *g = (*glist)[n]; 00372 g->set_text_format(format); 00373 return TRUE; 00374 } 00375 00377 00378 // prepare for drawing ... do any updates needed right before draw. 00379 // For now, this always recreates the display list 00380 void GeometryList::prepare() { 00381 00382 // go through all the geometry objects, recalculate, and find out if 00383 // something is no longer 'ok'. If not, delete it. 00384 for(int i=(num_lists() - 1); i >= 0; i--) { 00385 GeomListPtr glist = geom_list(i); 00386 for(int j=(glist->num() - 1); j >= 0; j--) { 00387 GeometryMol *g = (*glist)[j]; 00388 if(!g->ok()) { 00389 del_geometry(i, j); 00390 } 00391 } 00392 } 00393 } 00394