// del a new geometry object from the list with the given index. Return success. // if n < 0, delete all markers int GeometryList::del_geometry(int glindex, int n) { // make sure the given GeometryMol object is OK if(glindex >= 0 && glindex < num_lists()) { // get the list of geometry objects for the given index GeomListPtr glist = geom_list(glindex); // make sure the geometry index is ok if(n >= 0 && n < glist->num()) { // delete and remove the geometry object delete (*glist)[n]; glist->remove(n); // indicate we were successful return TRUE; } else if(n < 0) { // delete and remove all geometry objects for(int j=(glist->num() - 1); j >= 0; j--) { delete (*glist)[j]; glist->remove(j); } // indicate we were successful return TRUE; } } // if here, something did not work return FALSE; }
// delete(category, labeldict) // XXX cut 'n paste from show... static PyObject *label_delete(PyObject *self, PyObject *args) { char *type; PyObject *labeldict; if (!PyArg_ParseTuple(args, (char *)"sO!:label.delete", &type, &PyDict_Type, &labeldict)) return NULL; VMDApp *app = get_vmdapp(); int cat = app->geometryList->geom_list_index(type); if (cat < 0) { PyErr_SetString(PyExc_ValueError, (char *)"Unknown label category"); return NULL; } GeomListPtr glist = app->geometryList->geom_list(cat); int gnum = glist->num(); for (int i=0; i<gnum; i++) { if (dict2geom(labeldict, (*glist)[i])) { app->label_delete(type, i); // XXX check return code Py_INCREF(Py_None); return Py_None; } } PyErr_SetString(PyExc_ValueError, "Invalid labeldict."); return NULL; }
const float *GeometryList::getTextOffset(const char *nm, int n) { GeomListPtr glist = geom_list(nm); if (!glist) return NULL; if (n < 0 || n >= glist->num()) return NULL; GeometryMol *g = (*glist)[n]; return g->text_offset(); }
int GeometryList::setTextFormat(const char *nm, int n, const char *format) { GeomListPtr glist = geom_list(nm); if (!glist) return FALSE; if (n < 0 || n >= glist->num()) return FALSE; GeometryMol *g = (*glist)[n]; g->set_text_format(format); return TRUE; }
const char *GeometryList::getTextFormat(const char *nm, int n) { // XXX get/set Text Offset/Format duplicate their first four lines... GeomListPtr glist = geom_list(nm); if (!glist) return NULL; if (n < 0 || n >= glist->num()) return NULL; GeometryMol *g = (*glist)[n]; return g->text_format(); }
int GeometryList::setTextOffset(const char *nm, int n, const float delta[2]) { GeomListPtr glist = geom_list(nm); if (!glist) return FALSE; if (n < 0 || n >= glist->num()) return FALSE; GeometryMol *g = (*glist)[n]; g->set_text_offset(delta); return TRUE; }
void GeometryList::do_color_changed(int clr) { if (clr == colorCat) { for (int i=0; i<num_lists(); i++) { GeomListPtr glist = geom_list(i); GeomListStruct *s = geomLists.data(i); int ind = scene->category_item_index(colorCat, geom_list_name(i)); int c = scene->category_item_value(colorCat, ind); s->curColor = c; for (int j=0; j<glist->num(); j++) (*glist)[j]->set_color(c); } } }
// prepare for drawing ... do any updates needed right before draw. // For now, this always recreates the display list void GeometryList::prepare() { // go through all the geometry objects, recalculate, and find out if // something is no longer 'ok'. If not, delete it. for(int i=(num_lists() - 1); i >= 0; i--) { GeomListPtr glist = geom_list(i); for(int j=(glist->num() - 1); j >= 0; j--) { GeometryMol *g = (*glist)[j]; if(!g->ok()) { del_geometry(i, j); } } } }
int GeometryList::setTextThickness(float newthick) { if (newthick <= 0) return FALSE; if (newthick == labelthickness) return TRUE; labelthickness = newthick; for(int i=(num_lists() - 1); i >= 0; i--) { GeomListPtr glist = geom_list(i); for(int j=(glist->num() - 1); j >= 0; j--) { GeometryMol *g = (*glist)[j]; g->set_text_thickness(newthick); } } return TRUE; }
int GeometryList::setTextSize(float newsize) { if (newsize <= 0) return FALSE; if (newsize == labelsize) return TRUE; labelsize = newsize; for(int i=(num_lists() - 1); i >= 0; i--) { GeomListPtr glist = geom_list(i); for(int j=(glist->num() - 1); j >= 0; j--) { GeometryMol *g = (*glist)[j]; g->set_text_size(newsize); } } return TRUE; }
// getvalues(category, labeldict) -> list // returns list containing value of label for every frame in the label // if the label contains atoms from more than one molecule, only the first // molecule is cycled (this the behavior of GeometryMol). // XXX Note: this command is bad: the GeometryMol::calculate_all method // twiddles the frame of the molecule, so this command isn't read only as // its semantics would imply. But it should be possible to fix this // in GeometryMol. static PyObject *label_getvalues(PyObject *self, PyObject *args) { char *type; PyObject *labeldict; if (!PyArg_ParseTuple(args, (char *)"sO!:label.getvalues", &type, &PyDict_Type, &labeldict)) return NULL; VMDApp *app = get_vmdapp(); int cat = app->geometryList->geom_list_index(type); if (cat < 0) { PyErr_SetString(PyExc_ValueError, (char *)"Unknown label category"); return NULL; } GeomListPtr glist = app->geometryList->geom_list(cat); int gnum = glist->num(); for (int i=0; i<gnum; i++) { if (dict2geom(labeldict, (*glist)[i])) return getvalues((*glist)[i]); } PyErr_SetString(PyExc_ValueError, (char *)"Invalid label"); return NULL; }
// delete the Nth category. Return success. int GeometryList::del_geom_list(int n) { GeomListStruct *oldlist = NULL; // make sure we do have a category with this name if(n >= 0 && n < num_lists()) { // get data for Nth list oldlist = geomLists.data(n); GeomListPtr glist = oldlist->geomList; // go through the list and delete all current GeometryMol objects for(int i=(glist->num() - 1); i >= 0; i--) { delete (*glist)[i]; } // delete the old list storage and structure delete glist; delete oldlist; geomLists.set_data(n, (GeomListStruct *) NULL); } // return whether we were successful return (oldlist != NULL); }
// toggle whether to show or hide a geometry monitor. If the monitor // specified is < 0, does so for all monitors in the given category int GeometryList::show_geometry(int glindex, int n, int s) { // make sure the given GeometryMol object is OK if(glindex >= 0 && glindex < num_lists()) { // get the list of geometry objects for the given index GeomListPtr glist = geom_list(glindex); // make sure the geometry index is ok if(n >= 0 && n < glist->num()) { // hide or show the specified object if (s) (*glist)[n] -> on(); else (*glist)[n] -> off(); // indicate we were successful return TRUE; } else if(n < 0) { // delete and remove all geometry objects for(int j=(glist->num() - 1); j >= 0; j--) { if (s) (*glist)[j] -> on(); else (*glist)[j] -> off(); } // indicate we were successful return TRUE; } } // if here, something did not work return FALSE; }
// listall(category) - return a list of labels for the given label category. // labels will be returned as dictionary objects with the following keys: // molid, atomid, value, on. molid and atomid will be tuples, value will // be either a float or PyNone, and on will be 1 or 0. static PyObject *listall(PyObject *self, PyObject *args) { char *type; if (!PyArg_ParseTuple(args, (char *)"s:label.listall", &type)) return NULL; VMDApp *app = get_vmdapp(); int cat = app->geometryList->geom_list_index(type); if (cat < 0) { PyErr_SetString(PyExc_ValueError, (char *)"Unknown label category"); return NULL; } GeomListPtr glist = app->geometryList->geom_list(cat); int gnum = glist->num(); PyObject *newlist = PyList_New(gnum); for (int i=0; i<gnum; i++) { PyObject *obj = geom2dict((*glist)[i]); if (obj == NULL) { Py_DECREF(newlist); return NULL; } PyList_SET_ITEM(newlist, i, geom2dict((*glist)[i])); } return newlist; }
int text_cmd_label(ClientData cd, Tcl_Interp *interp, int argc, const char *argv[]) { VMDApp *app = (VMDApp *)cd; if (argc < 2) { Tcl_SetResult(interp, (char *) "label add [Atoms|Bonds|Angles|Dihedrals] {atoms as <molid>/<atomid>}\n" "label addspring <molid> <atomid> <atomid> <k>\n" "label list -- return label categories\n" "label list <category> -- return id's of labels in given category\n" "label [show|hide|delete] <category> [index] -- \n\tControl specific label or all labels in category\n" "label graph <category> <index> -- Return a list of values for the given label\n\tfor all animation frames\n" "label textsize [<newsize>]\n" , TCL_STATIC); return TCL_ERROR; } if(!strupncmp(argv[1], "add", CMDLEN)) { if(argc > 3) { int n = argc-3; const char **items = argv+3; int *molid= new int[n]; int *atmid = new int[n]; int i; for(i=0; i < n; i++) { if (find_atom_from_name(interp, items[i], molid+i, atmid+i)) break; } int rc = -1; if(i == n) { // all successfully parsed rc = app->label_add(argv[2], argc-3, molid, atmid, NULL, 0.0f, 1); } delete [] molid; delete [] atmid; if (rc < 0) { Tcl_AppendResult(interp, "\nUnable to add label.", NULL); return TCL_ERROR; } } else return TCL_ERROR; } else if(!strupncmp(argv[1],"addspring",CMDLEN)) { /* add a spring */ if(argc != 6) { Tcl_AppendResult(interp, "usage: label addspring <molid> <atomid> <atomid> <k>", NULL); return TCL_ERROR; } int molid[2]; int atomid[2]; float k; sscanf(argv[2],"%d",molid); /* convert all of the args to numbers */ sscanf(argv[3],"%d",atomid); sscanf(argv[4],"%d",atomid+1); sscanf(argv[5],"%f",&k); molid[1]=molid[0]; if (app->label_add("Springs", 2, molid, atomid, NULL, k, 1) < 0) { Tcl_AppendResult(interp, "Unable to add spring.", NULL); return TCL_ERROR; } } else if(!strupncmp(argv[1], "list", CMDLEN)) { if(argc == 3) { int cat = app->geometryList->geom_list_index(argv[2]); if (cat < 0) { Tcl_AppendResult(interp, "graph list category '", argv[2], "' was not found", NULL); return TCL_ERROR; } // go through the list by hand GeomListPtr glist = app->geometryList->geom_list(cat); int gnum = glist->num(); char s[30]; GeometryMol *g; for (int i=0; i<gnum; i++) { g = (*glist)[i]; Tcl_AppendResult(interp, i==0 ? "" : " ", "{", NULL); for (int j=0; j<g->items(); j++) { // append the molecule id/atom index sprintf(s, "%d %d", g -> obj_index(j), g -> com_index(j)); Tcl_AppendElement(interp, s); } // and the value and the status sprintf(s, "%f", g->ok() ? g->calculate() : 0.0); Tcl_AppendElement(interp, s); Tcl_AppendElement(interp, g -> displayed() ? "show" : "hide"); Tcl_AppendResult(interp, "}", NULL); } return TCL_OK; } else if (argc == 2) { // return the main categories for (int i=0; i<app->geometryList -> num_lists(); i++) { Tcl_AppendElement(interp, app->geometryList -> geom_list_name(i)); } return TCL_OK; } else return TCL_ERROR; } else if(!strupncmp(argv[1], "show", CMDLEN) || !strupncmp(argv[1], "hide", CMDLEN)) { int item; if(argc == 3 || (argc == 4 && !strupncmp(argv[3], "all", CMDLEN))) item = (-1); else if(argc == 4) { if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) { Tcl_AppendResult(interp, " in label ", argv[1], NULL); return TCL_ERROR; } } else return TCL_ERROR; app->label_show(argv[2], item, !strupncmp(argv[1], "show", CMDLEN)); // XXX check return code } else if(!strupncmp(argv[1], "delete", CMDLEN)) { int item; if(argc == 3 || (argc == 4 && !strupncmp(argv[3], "all", CMDLEN))) { item = (-1); } else if(argc == 4) { if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) { Tcl_AppendResult(interp, " in label ", argv[1], NULL); return TCL_ERROR; } } else { return TCL_ERROR; } app->label_delete(argv[2], item); // XXX check return code } else if(!strupncmp(argv[1], "graph", CMDLEN) && argc > 3) { int item; if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) { return TCL_ERROR; }; // find the geometry int cat = app->geometryList->geom_list_index(argv[2]); if (cat < 0) { Tcl_AppendResult(interp, "Invalid geometry type: ", argv[2], NULL); return TCL_ERROR; } // get the correct geometry pointer GeomListPtr glist = app->geometryList -> geom_list(cat); int gnum = glist -> num(); if (item < 0 || item >= gnum) { sprintf(interp -> result, "label %s index %d out of range", argv[2], item); return TCL_ERROR; } // compute all the values GeometryMol *g = (*glist)[item]; if (!g->has_value()) { Tcl_AppendResult(interp, "Geometry type ", argv[2], " has no values to graph.", NULL); return TCL_ERROR; } ResizeArray<float> gValues(1024); if (!g->calculate_all(gValues)) { interp->result = (char *) "label has no value"; return TCL_ERROR; } if (argc > 4) { // save the values in the given filename const char *filename = argv[4]; FILE *outfile = fopen(filename, "w"); if (!outfile) { Tcl_AppendResult(interp, "Cannot write graph data to file ", filename, NULL); return TCL_ERROR; } for (int i=0; i<gValues.num(); i++) { fprintf(outfile, "%f %f\n", float(i), gValues[i]); } fclose(outfile); } else { char s[20]; for (int count = 0; count < gValues.num(); count++) { sprintf(s, "%f", gValues[count]); Tcl_AppendElement(interp, s); } } } else if (!strupncmp(argv[1], "textsize", CMDLEN)) { if (argc == 2) { // return the current size Tcl_SetObjResult(interp, Tcl_NewDoubleObj(app->label_get_textsize())); return TCL_OK; } else if (argc == 3) { // set new size double newsize = 1; if (Tcl_GetDouble(interp, argv[2], &newsize) != TCL_OK) return TCL_ERROR; if (!app->label_set_textsize((float) newsize)) { Tcl_AppendResult(interp, "label textsize: Unable to set size to ", argv[2], NULL); return TCL_ERROR; } } else { Tcl_SetResult(interp, "label textsize: wrong number of arguments", TCL_STATIC); return TCL_ERROR; } } else if (!strupncmp(argv[1], "textoffset", CMDLEN)) { if (argc == 4) { // return current offset; const char *geomtype = argv[2]; int geom; if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR; const float *offset = app->geometryList->getTextOffset(geomtype, geom); if (!offset) { Tcl_SetResult(interp, "label textoffset: Invalid geometry specified", TCL_STATIC); return TCL_ERROR; } Tcl_Obj *result = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(offset[0])); Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(offset[1])); Tcl_SetObjResult(interp, result); } else if (argc == 5) { const char *geomtype = argv[2]; int geom; if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR; float x, y; if (sscanf(argv[4], "%f %f", &x, &y) != 2) { Tcl_AppendResult(interp, "Could not understand argument to label textoffset:", argv[2], NULL); return TCL_ERROR; } if (!app->label_set_textoffset(geomtype, geom, x, y)) { Tcl_SetResult(interp, "label textoffset: Invalid geometry specified", TCL_STATIC); return TCL_ERROR; } } else { Tcl_SetResult(interp, "label textoffset: wrong number of arguments", TCL_STATIC); return TCL_ERROR; } } else if (!strupncmp(argv[1], "textformat", CMDLEN)) { if (argc == 4) { // return current format const char *geomtype = argv[2]; int geom; if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR; const char *format = app->geometryList->getTextFormat(geomtype, geom); if (!format) { Tcl_SetResult(interp, "label textformat: Invalid geometry specified", TCL_STATIC); return TCL_ERROR; } Tcl_SetResult(interp, (char *)format, TCL_VOLATILE); } else if (argc == 5) { const char *geomtype = argv[2]; int geom; if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR; if (!app->label_set_textformat(geomtype, geom, argv[4])) { Tcl_SetResult(interp, "label textformat failed.", TCL_STATIC); return TCL_ERROR; } } else { Tcl_SetResult(interp, "label textoffset: wrong number of arguments", TCL_STATIC); return TCL_ERROR; } } return TCL_OK; }
int GeometryList::add_geometry(const char *geomcatname, const int *molids, const int *atomids, const int *cells, float k, int toggle) { // check that geometry category name is valid int geomcat = geom_list_index(geomcatname); GeometryMol *g = NULL; MoleculeList *mlist = app->moleculeList; if (geomcat == geom_list_index("Atoms")) g = new GeometryAtom(*molids, *atomids, cells, mlist, app->commandQueue, this); else if (geomcat == geom_list_index("Bonds")) g = new GeometryBond((int *)molids, (int *)atomids, cells, mlist, app->commandQueue, this); else if (geomcat == geom_list_index("Angles")) g = new GeometryAngle((int *)molids, (int *)atomids, cells, mlist, app->commandQueue, this); else if (geomcat == geom_list_index("Dihedrals")) g = new GeometryDihedral((int *)molids, (int *)atomids, cells, mlist, app->commandQueue, this); else if (geomcat == geom_list_index("Springs")) g = new GeometrySpring((int *)molids, (int *)atomids, mlist, app->commandQueue, k, this); else { msgErr << "Unknown geometry category '" << geomcatname << "'." << sendmsg; return -1; } if(g && g->ok()) { GeomListPtr glist = geom_list(geomcat); // if there is already an identical label in the list, // do not add this one, instead toggle the displayed // status of the old one and return the index. for(int i=(glist->num() - 1); i >= 0; i--) { GeometryMol *g2 = (*glist)[i]; if(!strcmp(g2->unique_name(), g->unique_name())) { // name matches if (toggle) { if (g2->displayed()) g2->off(); else g2->on(); } delete g; return i; } } // spam the console msgInfo << "Added new " << geomcatname << " label " << g->name(); if (g->has_value()) msgInfo << " = " << g->calculate(); msgInfo << sendmsg; // add the geometry object glist->append(g); // calculate the value for the first time g->calculate(); // set the color, which also causes the display list to be generated g->set_color(geomLists.data(geomcat)->curColor); g->set_text_size(labelsize); g->set_text_thickness(labelthickness); // set the pick variables g->set_pick(); // indicate we were successful; return index of this object return glist->num() - 1; } // if here, something did not work return -1; }