00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <string.h>
00010 #include <ctype.h>
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <tcl.h>
00014 #include "config.h"
00015 #include "GeometryList.h"
00016 #include "GeometryMol.h"
00017 #include "utilities.h"
00018 #include "VMDApp.h"
00019
00020 static int find_atom_from_name(Tcl_Interp *interp, const char *str, int *molid,
00021 int *atomid) {
00022
00023
00024
00025 const char *slash = strchr(str, '/');
00026 if (!slash) {
00027 Tcl_AppendResult(interp, "Illegal format: ", str, NULL);
00028 return -1;
00029 }
00030
00031
00032 if (slash == str) {
00033 Tcl_AppendResult(interp, "Missing molecule specification: ", str, NULL);
00034 return -1;
00035 }
00036 if (strlen(slash+1) == 0) {
00037 Tcl_AppendResult(interp, "Missing atom specification: ", str, NULL);
00038 return -1;
00039 }
00040 const char *s;
00041 for (s = str; s < slash; s++) {
00042 if (!isdigit(*s)) {
00043 Tcl_AppendResult(interp, "Illegal molecule specification: ", str, NULL);
00044 return -1;
00045 }
00046 }
00047 for (s = slash+1; *s; s++) {
00048 if (!isdigit(*s)) {
00049 Tcl_AppendResult(interp, "Illegal atom specification: ", str, NULL);
00050 return -1;
00051 }
00052 }
00053
00054
00055 char *buf = new char[slash-str + 1];
00056 strncpy(buf, str, slash-str);
00057 buf[slash-str] = '\0';
00058 *molid = atoi(buf);
00059 *atomid = atoi(slash+1);
00060 return 0;
00061 }
00062
00063
00064 int text_cmd_label(ClientData cd, Tcl_Interp *interp, int argc,
00065 const char *argv[]) {
00066
00067 VMDApp *app = (VMDApp *)cd;
00068
00069 if (argc < 2) {
00070 Tcl_SetResult(interp,
00071 (char *)
00072 "label add [Atoms|Bonds|Angles|Dihedrals] {atoms as <molid>/<atomid>}\n"
00073 "label addspring <molid> <atomid> <atomid> <k>\n"
00074 "label list -- return label categories\n"
00075 "label list <category> -- return id's of labels in given category\n"
00076 "label [show|hide|delete] <category> [index] -- \n\tControl specific label or all labels in category\n"
00077 "label graph <category> <index> -- Return a list of values for the given label\n\tfor all animation frames\n"
00078 "label textsize [<newsize>]\n" ,
00079 TCL_STATIC);
00080 return TCL_ERROR;
00081 }
00082 if(!strupncmp(argv[1], "add", CMDLEN)) {
00083 if(argc > 3) {
00084 int n = argc-3;
00085 const char **items = argv+3;
00086 int *molid= new int[n];
00087 int *atmid = new int[n];
00088 int i;
00089 for(i=0; i < n; i++) {
00090 if (find_atom_from_name(interp, items[i], molid+i, atmid+i))
00091 break;
00092 }
00093 int rc = -1;
00094 if(i == n) {
00095 rc = app->label_add(argv[2], argc-3, molid, atmid, NULL, 0.0f, 1);
00096 }
00097 delete [] molid;
00098 delete [] atmid;
00099 if (rc < 0) {
00100 Tcl_AppendResult(interp, "\nUnable to add label.", NULL);
00101 return TCL_ERROR;
00102 }
00103 }
00104 else
00105 return TCL_ERROR;
00106
00107 }
00108 else if(!strupncmp(argv[1],"addspring",CMDLEN)) {
00109 if(argc != 6) {
00110 Tcl_AppendResult(interp, "usage: label addspring <molid> <atomid> <atomid> <k>", NULL);
00111 return TCL_ERROR;
00112 }
00113 int molid[2];
00114 int atomid[2];
00115 float k;
00116 sscanf(argv[2],"%d",molid);
00117 sscanf(argv[3],"%d",atomid);
00118 sscanf(argv[4],"%d",atomid+1);
00119 sscanf(argv[5],"%f",&k);
00120 molid[1]=molid[0];
00121 if (app->label_add("Springs", 2, molid, atomid, NULL, k, 1) < 0) {
00122 Tcl_AppendResult(interp, "Unable to add spring.", NULL);
00123 return TCL_ERROR;
00124 }
00125 }
00126 else if(!strupncmp(argv[1], "list", CMDLEN)) {
00127 if(argc == 3) {
00128 int cat = app->geometryList->geom_list_index(argv[2]);
00129 if (cat < 0) {
00130 Tcl_AppendResult(interp, "graph list category '", argv[2],
00131 "' was not found", NULL);
00132 return TCL_ERROR;
00133 }
00134
00135 GeomListPtr glist = app->geometryList->geom_list(cat);
00136 int gnum = glist->num();
00137 char s[30];
00138 GeometryMol *g;
00139 for (int i=0; i<gnum; i++) {
00140 g = (*glist)[i];
00141 Tcl_AppendResult(interp, i==0 ? "" : " ", "{", NULL);
00142 for (int j=0; j<g->items(); j++) {
00143
00144 sprintf(s, "%d %d", g -> obj_index(j), g -> com_index(j));
00145 Tcl_AppendElement(interp, s);
00146 }
00147
00148 sprintf(s, "%f", g->ok() ? g->calculate() : 0.0);
00149 Tcl_AppendElement(interp, s);
00150 Tcl_AppendElement(interp, g -> displayed() ? "show" : "hide");
00151 Tcl_AppendResult(interp, "}", NULL);
00152 }
00153 return TCL_OK;
00154 }
00155 else if (argc == 2) {
00156
00157 for (int i=0; i<app->geometryList -> num_lists(); i++) {
00158 Tcl_AppendElement(interp, app->geometryList -> geom_list_name(i));
00159 }
00160 return TCL_OK;
00161 } else
00162 return TCL_ERROR;
00163
00164 } else if(!strupncmp(argv[1], "show", CMDLEN) ||
00165 !strupncmp(argv[1], "hide", CMDLEN)) {
00166 int item;
00167 if(argc == 3 || (argc == 4 && !strupncmp(argv[3], "all", CMDLEN)))
00168 item = (-1);
00169 else if(argc == 4) {
00170 if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) {
00171 Tcl_AppendResult(interp, " in label ", argv[1], NULL);
00172 return TCL_ERROR;
00173 }
00174 } else
00175 return TCL_ERROR;
00176
00177 app->label_show(argv[2], item, !strupncmp(argv[1], "show", CMDLEN));
00178
00179
00180 } else if(!strupncmp(argv[1], "delete", CMDLEN)) {
00181 int item;
00182 if(argc == 3 || (argc == 4 && !strupncmp(argv[3], "all", CMDLEN))) {
00183 item = (-1);
00184 } else if(argc == 4) {
00185 if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) {
00186 Tcl_AppendResult(interp, " in label ", argv[1], NULL);
00187 return TCL_ERROR;
00188 }
00189 } else {
00190 return TCL_ERROR;
00191 }
00192
00193 app->label_delete(argv[2], item);
00194
00195
00196 } else if(!strupncmp(argv[1], "graph", CMDLEN) && argc > 3) {
00197 int item;
00198 if (Tcl_GetInt(interp, argv[3], &item) != TCL_OK) {
00199 return TCL_ERROR;
00200 };
00201
00202 int cat = app->geometryList->geom_list_index(argv[2]);
00203 if (cat < 0) {
00204 Tcl_AppendResult(interp, "Invalid geometry type: ", argv[2], NULL);
00205 return TCL_ERROR;
00206 }
00207
00208 GeomListPtr glist = app->geometryList -> geom_list(cat);
00209 int gnum = glist -> num();
00210 if (item < 0 || item >= gnum) {
00211 sprintf(interp -> result, "label %s index %d out of range",
00212 argv[2], item);
00213 return TCL_ERROR;
00214 }
00215
00216 GeometryMol *g = (*glist)[item];
00217 if (!g->has_value()) {
00218 Tcl_AppendResult(interp, "Geometry type ", argv[2], " has no values to graph.", NULL);
00219 return TCL_ERROR;
00220 }
00221 ResizeArray<float> gValues(1024);
00222 if (!g->calculate_all(gValues)) {
00223 interp->result = (char *) "label has no value";
00224 return TCL_ERROR;
00225 }
00226 if (argc > 4) {
00227
00228 const char *filename = argv[4];
00229 FILE *outfile = fopen(filename, "w");
00230 if (!outfile) {
00231 Tcl_AppendResult(interp, "Cannot write graph data to file ",
00232 filename, NULL);
00233 return TCL_ERROR;
00234 }
00235 for (int i=0; i<gValues.num(); i++) {
00236 fprintf(outfile, "%f %f\n", float(i), gValues[i]);
00237 }
00238 fclose(outfile);
00239 } else {
00240 char s[20];
00241 for (int count = 0; count < gValues.num(); count++) {
00242 sprintf(s, "%f", gValues[count]);
00243 Tcl_AppendElement(interp, s);
00244 }
00245 }
00246 } else if (!strupncmp(argv[1], "textsize", CMDLEN)) {
00247 if (argc == 2) {
00248
00249 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(app->label_get_textsize()));
00250 return TCL_OK;
00251 } else if (argc == 3) {
00252
00253 double newsize = 1;
00254 if (Tcl_GetDouble(interp, argv[2], &newsize) != TCL_OK)
00255 return TCL_ERROR;
00256 if (!app->label_set_textsize((float) newsize)) {
00257 Tcl_AppendResult(interp, "label textsize: Unable to set size to ",
00258 argv[2], NULL);
00259 return TCL_ERROR;
00260 }
00261 } else {
00262 Tcl_SetResult(interp, "label textsize: wrong number of arguments",
00263 TCL_STATIC);
00264 return TCL_ERROR;
00265 }
00266 } else if (!strupncmp(argv[1], "textoffset", CMDLEN)) {
00267 if (argc == 4) {
00268
00269 const char *geomtype = argv[2];
00270 int geom;
00271 if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00272 const float *offset = app->geometryList->getTextOffset(geomtype, geom);
00273 if (!offset) {
00274 Tcl_SetResult(interp, "label textoffset: Invalid geometry specified", TCL_STATIC);
00275 return TCL_ERROR;
00276 }
00277 Tcl_Obj *result = Tcl_NewListObj(0, NULL);
00278 Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(offset[0]));
00279 Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj(offset[1]));
00280 Tcl_SetObjResult(interp, result);
00281 } else if (argc == 5) {
00282 const char *geomtype = argv[2];
00283 int geom;
00284 if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00285 float x, y;
00286 if (sscanf(argv[4], "%f %f", &x, &y) != 2) {
00287 Tcl_AppendResult(interp, "Could not understand argument to label textoffset:", argv[2], NULL);
00288 return TCL_ERROR;
00289 }
00290 if (!app->label_set_textoffset(geomtype, geom, x, y)) {
00291 Tcl_SetResult(interp, "label textoffset: Invalid geometry specified", TCL_STATIC);
00292 return TCL_ERROR;
00293 }
00294 } else {
00295 Tcl_SetResult(interp, "label textoffset: wrong number of arguments",
00296 TCL_STATIC);
00297 return TCL_ERROR;
00298 }
00299 } else if (!strupncmp(argv[1], "textformat", CMDLEN)) {
00300 if (argc == 4) {
00301
00302 const char *geomtype = argv[2];
00303 int geom;
00304 if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00305 const char *format = app->geometryList->getTextFormat(geomtype, geom);
00306 if (!format) {
00307 Tcl_SetResult(interp, "label textformat: Invalid geometry specified", TCL_STATIC);
00308 return TCL_ERROR;
00309 }
00310 Tcl_SetResult(interp, (char *)format, TCL_VOLATILE);
00311 } else if (argc == 5) {
00312 const char *geomtype = argv[2];
00313 int geom;
00314 if (Tcl_GetInt(interp, argv[3], &geom) != TCL_OK) return TCL_ERROR;
00315 if (!app->label_set_textformat(geomtype, geom, argv[4])) {
00316 Tcl_SetResult(interp, "label textformat failed.", TCL_STATIC);
00317 return TCL_ERROR;
00318 }
00319 } else {
00320 Tcl_SetResult(interp, "label textoffset: wrong number of arguments",
00321 TCL_STATIC);
00322 return TCL_ERROR;
00323 }
00324 }
00325 return TCL_OK;
00326 }