00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include "VMDApp.h"
00025 #include "Molecule.h"
00026 #include "MoleculeList.h"
00027 #include "MaterialList.h"
00028 #include "tcl.h"
00029 #include "TclCommands.h"
00030 #include "Scene.h"
00031 #include "MoleculeGraphics.h"
00032
00033
00034 #define AT_LEAST(n, s) \
00035 { \
00036 if (argc < n) { \
00037 Tcl_SetResult(interp, \
00038 (char *) "graphics: " s ": not enough parameters", \
00039 TCL_STATIC); \
00040 return TCL_ERROR; \
00041 } \
00042 }
00043
00044
00045 #define MUST_HAVE(n, s) \
00046 { \
00047 if (argc != n) { \
00048 Tcl_SetResult(interp, \
00049 (char *) "graphics: " s ": incorrect number of parameters", \
00050 TCL_STATIC); \
00051 return TCL_ERROR; \
00052 } \
00053 }
00054
00055
00056 static int tcl_graphics_triangle(MoleculeGraphics *gmol,
00057 int argc, const char *argv[],
00058 Tcl_Interp *interp)
00059 {
00060
00061 MUST_HAVE(3, "triangle");
00062 float vals[9];
00063 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK ||
00064 tcl_get_vector(argv[1], vals+3, interp) != TCL_OK ||
00065 tcl_get_vector(argv[2], vals+6, interp) != TCL_OK ) {
00066 return TCL_ERROR;
00067 }
00068
00069
00070 char tmpstring[64];
00071 sprintf(tmpstring, "%d", gmol->add_triangle(vals+0, vals+3, vals+6));
00072 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00073 return TCL_OK;
00074 }
00075
00076
00077 static int tcl_graphics_trinorm(MoleculeGraphics *gmol,
00078 int argc, const char *argv[],
00079 Tcl_Interp *interp)
00080 {
00081
00082
00083 MUST_HAVE(6, "trinorm");
00084 float vals[19];
00085 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK ||
00086 tcl_get_vector(argv[1], vals+3, interp) != TCL_OK ||
00087 tcl_get_vector(argv[2], vals+6, interp) != TCL_OK ||
00088 tcl_get_vector(argv[3], vals+9, interp) != TCL_OK ||
00089 tcl_get_vector(argv[4], vals+12, interp) != TCL_OK ||
00090 tcl_get_vector(argv[5], vals+15, interp) != TCL_OK ) {
00091 return TCL_ERROR;
00092 }
00093
00094
00095 char tmpstring[64];
00096 sprintf(tmpstring, "%d",
00097 gmol->add_trinorm(vals+0, vals+3, vals+6,
00098 vals+9, vals+12, vals+15));
00099 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00100 return TCL_OK;
00101 }
00102
00103
00104 static int tcl_graphics_tricolor(MoleculeGraphics *gmol,
00105 int argc, const char *argv[],
00106 Tcl_Interp *interp)
00107 {
00108
00109
00110 MUST_HAVE(9, "tricolor");
00111 float vals[19];
00112 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK ||
00113 tcl_get_vector(argv[1], vals+3, interp) != TCL_OK ||
00114 tcl_get_vector(argv[2], vals+6, interp) != TCL_OK ||
00115 tcl_get_vector(argv[3], vals+9, interp) != TCL_OK ||
00116 tcl_get_vector(argv[4], vals+12, interp) != TCL_OK ||
00117 tcl_get_vector(argv[5], vals+15, interp) != TCL_OK ) {
00118 return TCL_ERROR;
00119 }
00120 int c1, c2, c3;
00121 if (Tcl_GetInt(interp, argv[6], &c1) != TCL_OK ||
00122 Tcl_GetInt(interp, argv[7], &c2) != TCL_OK ||
00123 Tcl_GetInt(interp, argv[8], &c3) != TCL_OK) {
00124 return TCL_ERROR;
00125 }
00126
00127
00128 char tmpstring[64];
00129 sprintf(tmpstring, "%d",
00130 gmol->add_tricolor(vals+0, vals+3, vals+6,
00131 vals+9, vals+12, vals+15, c1, c2, c3));
00132 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00133 return TCL_OK;
00134 }
00135
00136
00137 static int tcl_graphics_cylinder(MoleculeGraphics *gmol,
00138 int argc, const char *argv[],
00139 Tcl_Interp *interp)
00140 {
00141
00142 AT_LEAST(2, "cylinder");
00143 float vals[6];
00144 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK ||
00145 tcl_get_vector(argv[1], vals+3, interp) != TCL_OK) {
00146 return TCL_ERROR;
00147 }
00148
00149
00150 double radius = 1.0;
00151 int resolution = 6;
00152 int filled = 0;
00153 argc -= 2;
00154 argv += 2;
00155 if (argc %2) {
00156 Tcl_SetResult(interp, (char *) "graphics: cylinder has wrong number of options", TCL_STATIC);
00157 return TCL_ERROR;
00158 }
00159 while (argc) {
00160 if (!strcmp(argv[0], "radius")) {
00161 if (Tcl_GetDouble(interp, argv[1], &radius) != TCL_OK) {
00162 return TCL_ERROR;
00163 }
00164 if (radius <0) radius = 0;
00165 argc -= 2;
00166 argv += 2;
00167 continue;
00168 }
00169 if (!strcmp(argv[0], "resolution")) {
00170 if (Tcl_GetInt(interp, argv[1], &resolution) != TCL_OK) {
00171 return TCL_ERROR;
00172 }
00173 if (resolution < 0) resolution = 0;
00174 if (resolution > 30) resolution = 30;
00175 argc -= 2;
00176 argv += 2;
00177 continue;
00178 }
00179 if (!strcmp(argv[0], "filled")) {
00180 if (Tcl_GetBoolean(interp, argv[1], &filled) != TCL_OK) {
00181 return TCL_ERROR;
00182 }
00183 argc -= 2;
00184 argv += 2;
00185 continue;
00186 }
00187
00188 Tcl_AppendResult(interp, "graphics: unknown option for cylinder: ",
00189 argv[0], NULL);
00190 return TCL_ERROR;
00191 }
00192
00193
00194 char tmpstring[64];
00195 sprintf(tmpstring, "%d",
00196 gmol->add_cylinder(vals+0, vals+3, (float) radius, resolution, filled));
00197 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00198 return TCL_OK;
00199 }
00200
00201
00202 static int tcl_graphics_point(MoleculeGraphics *gmol,
00203 int argc, const char *argv[],
00204 Tcl_Interp *interp)
00205 {
00206 MUST_HAVE(1, "point");
00207 float vals[3];
00208 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK) {
00209 return TCL_ERROR;
00210 }
00211
00212
00213 char tmpstring[64];
00214 sprintf(tmpstring, "%d", gmol->add_point(vals+0));
00215 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00216 return TCL_OK;
00217 }
00218
00219
00220 static int tcl_graphics_pickpoint(MoleculeGraphics *gmol,
00221 int argc, const char *argv[],
00222 Tcl_Interp *interp)
00223 {
00224 MUST_HAVE(1, "pickpoint");
00225 float vals[3];
00226 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK) {
00227 return TCL_ERROR;
00228 }
00229
00230
00231 char tmpstring[64];
00232 sprintf(tmpstring, "%d", gmol->add_pickpoint(vals+0));
00233 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00234 return TCL_OK;
00235 }
00236
00237
00238
00239 static int tcl_graphics_line(MoleculeGraphics *gmol,
00240 int argc, const char *argv[],
00241 Tcl_Interp *interp)
00242 {
00243
00244 AT_LEAST(2, "line");
00245 float vals[6];
00246 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK ||
00247 tcl_get_vector(argv[1], vals+3, interp) != TCL_OK) {
00248 return TCL_ERROR;
00249 }
00250
00251
00252
00253 int line_style = ::SOLIDLINE;
00254 int width = 1;
00255 argc -= 2;
00256 argv += 2;
00257 if (argc %2) {
00258 Tcl_SetResult(interp, (char *) "graphics: line has wrong number of options", TCL_STATIC);
00259 return TCL_ERROR;
00260 }
00261 while (argc) {
00262 if (!strcmp(argv[0], "style")) {
00263 if (!strcmp(argv[1], "solid")) {
00264 line_style = ::SOLIDLINE;
00265 } else if (!strcmp(argv[1], "dashed")) {
00266 line_style = ::DASHEDLINE;
00267 } else {
00268 Tcl_AppendResult(interp, "graphics: don't understand the line style ",
00269 argv[1], NULL);
00270 return TCL_ERROR;
00271 }
00272 } else if (!strcmp(argv[0], "width")) {
00273 if (Tcl_GetInt(interp, argv[1], &width) != TCL_OK) {
00274 return TCL_ERROR;
00275 }
00276 if (width > 255) width = 255;
00277 if (width < 0) width = 0;
00278 } else {
00279 Tcl_AppendResult(interp, "graphics: don't understand the line option ",
00280 argv[0], NULL);
00281 return TCL_ERROR;
00282 }
00283 argc -= 2;
00284 argv += 2;
00285 }
00286
00287
00288 char tmpstring[64];
00289 sprintf(tmpstring, "%d", gmol->add_line(vals+0, vals+3, line_style, width));
00290 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00291 return TCL_OK;
00292 }
00293
00294
00295 static int tcl_graphics_materials(MoleculeGraphics *gmol,
00296 int argc, const char *argv[],
00297 Tcl_Interp *interp)
00298 {
00299 MUST_HAVE(1, "materials");
00300 int val;
00301 if (Tcl_GetBoolean(interp, argv[0], &val) != TCL_OK) {
00302 return TCL_ERROR;
00303 }
00304
00305
00306 char tmpstring[64];
00307 sprintf(tmpstring, "%d", gmol->use_materials(val));
00308 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00309 return TCL_OK;
00310 }
00311
00312
00313 static int tcl_graphics_material(MoleculeGraphics *gmol,
00314 int argc, const char *argv[],
00315 Tcl_Interp *interp, MaterialList *mlist)
00316 {
00317 MUST_HAVE(1, "material");
00318 int val = mlist->material_index(argv[0]);
00319 if (val < 0) {
00320 char tmpstring[1024];
00321 sprintf(tmpstring, "graphics: invalid material: %s", argv[0]);
00322 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00323 return TCL_ERROR;
00324 }
00325 const Material *mat = mlist->material(val);
00326 char tmpstring[64];
00327 sprintf(tmpstring, "%d", gmol->use_material(mat));
00328 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00329 return TCL_OK;
00330 }
00331
00332
00333
00334
00335 static int tcl_graphics_color(VMDApp *app, MoleculeGraphics *gmol,
00336 int argc, const char *argv[],
00337 Tcl_Interp *interp)
00338 {
00339 MUST_HAVE(1, "color");
00340
00341 int id;
00342 Tcl_ResetResult(interp);
00343 if (Tcl_GetInt(interp, argv[0], &id) == TCL_OK) {
00344
00345 if (id >=0 && id < MAXCOLORS) {
00346 char tmpstring[64];
00347 sprintf(tmpstring, "%d", gmol->use_color(id));
00348 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00349 return TCL_OK;
00350 } else {
00351 char tmpstring[64];
00352 sprintf(tmpstring, "graphics: color index value '%d' out of range", id);
00353 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00354 return TCL_ERROR;
00355 }
00356 }
00357
00358 Tcl_ResetResult(interp);
00359 id = app->color_index(argv[0]);
00360 if (id >= 0) {
00361 char tmpstring[64];
00362 sprintf(tmpstring, "%d", gmol->use_color(id));
00363 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00364 return TCL_OK;
00365 }
00366
00367 Tcl_AppendResult(interp, "graphics: unknown color: ", argv[0], NULL);
00368 return TCL_ERROR;
00369 }
00370
00371
00372 static int tcl_graphics_cone(MoleculeGraphics *gmol,
00373 int argc, const char *argv[],
00374 Tcl_Interp *interp)
00375 {
00376
00377 AT_LEAST(2, "cone");
00378 float vals[6];
00379 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK ||
00380 tcl_get_vector(argv[1], vals+3, interp) != TCL_OK) {
00381 return TCL_ERROR;
00382 }
00383
00384
00385 double radius = 1.0;
00386 double radius2 = 0.0;
00387 int resolution = 6;
00388 argc -= 2;
00389 argv += 2;
00390 if (argc %2) {
00391 Tcl_SetResult(interp, (char *) "graphics: cone has wrong number of options", TCL_STATIC);
00392 return TCL_ERROR;
00393 }
00394 while (argc) {
00395 if (!strcmp(argv[0], "radius2")) {
00396 if (Tcl_GetDouble(interp, argv[1], &radius2) != TCL_OK) {
00397 return TCL_ERROR;
00398 }
00399 if (radius2 <0) radius2 = 0;
00400 argc -= 2;
00401 argv += 2;
00402 continue;
00403 }
00404 if (!strcmp(argv[0], "radius")) {
00405 if (Tcl_GetDouble(interp, argv[1], &radius) != TCL_OK) {
00406 return TCL_ERROR;
00407 }
00408 if (radius <0) radius = 0;
00409 argc -= 2;
00410 argv += 2;
00411 continue;
00412 }
00413 if (!strcmp(argv[0], "resolution")) {
00414 if (Tcl_GetInt(interp, argv[1], &resolution) != TCL_OK) {
00415 return TCL_ERROR;
00416 }
00417 if (resolution < 0) resolution = 0;
00418 if (resolution > 300) resolution = 300;
00419 argc -= 2;
00420 argv += 2;
00421 continue;
00422 }
00423
00424
00425 Tcl_AppendResult(interp, "graphics: unknown option for cone: ",
00426 argv[0], NULL);
00427 return TCL_ERROR;
00428 }
00429
00430
00431 char tmpstring[64];
00432 sprintf(tmpstring, "%d",
00433 gmol->add_cone(vals+0, vals+3, (float) radius, (float) radius2, resolution));
00434 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00435 return TCL_OK;
00436 }
00437
00438
00439
00440 static int tcl_graphics_sphere(MoleculeGraphics *gmol,
00441 int argc, const char *argv[],
00442 Tcl_Interp *interp)
00443 {
00444
00445 AT_LEAST(1, "sphere");
00446 float vals[3];
00447 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK) {
00448 return TCL_ERROR;
00449 }
00450
00451
00452 double radius = 1.0;
00453 int resolution = 6;
00454 argc -= 1;
00455 argv += 1;
00456 if (argc %2) {
00457 Tcl_SetResult(interp, (char *) "graphics: sphere has wrong number of options", TCL_STATIC);
00458 return TCL_ERROR;
00459 }
00460 while (argc) {
00461 if (!strcmp(argv[0], "radius")) {
00462 if (Tcl_GetDouble(interp, argv[1], &radius) != TCL_OK) {
00463 return TCL_ERROR;
00464 }
00465 if (radius <0) radius = 0;
00466 argc -= 2;
00467 argv += 2;
00468 continue;
00469 }
00470 if (!strcmp(argv[0], "resolution")) {
00471 if (Tcl_GetInt(interp, argv[1], &resolution) != TCL_OK) {
00472 return TCL_ERROR;
00473 }
00474 if (resolution < 0) resolution = 0;
00475 if (resolution > 30) resolution = 30;
00476 argc -= 2;
00477 argv += 2;
00478 continue;
00479 }
00480
00481 Tcl_AppendResult(interp, "graphics: unknown option for sphere: ",
00482 argv[0], NULL);
00483 return TCL_ERROR;
00484 }
00485
00486
00487 char tmpstring[64];
00488 sprintf(tmpstring, "%d",
00489 gmol->add_sphere(vals+0, (float) radius, resolution));
00490 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00491 return TCL_OK;
00492 }
00493
00494
00495
00496 static int tcl_graphics_text(MoleculeGraphics *gmol, int argc, const char *argv[],
00497 Tcl_Interp *interp) {
00498
00499 AT_LEAST(2, "text");
00500 float vals[3];
00501 if (tcl_get_vector(argv[0], vals+0, interp) != TCL_OK) {
00502 return TCL_ERROR;
00503 }
00504
00505
00506 const char* string = argv[1];
00507 double size = 1.0;
00508 double thickness = 1.0;
00509 argc -= 2;
00510 argv += 2;
00511
00512 if (argc % 2) {
00513 Tcl_SetResult(interp, (char *) "graphics: text has wrong number of options", TCL_STATIC);
00514 return TCL_ERROR;
00515 }
00516
00517 while (argc) {
00518 if (!strcmp(argv[0], "size")) {
00519 if (Tcl_GetDouble(interp, argv[1], &size) != TCL_OK) {
00520 return TCL_ERROR;
00521 }
00522 if (size <0) size = 0;
00523 argc -= 2;
00524 argv += 2;
00525 continue;
00526 }
00527
00528 if (!strcmp(argv[0], "thickness")) {
00529 if (Tcl_GetDouble(interp, argv[1], &thickness) != TCL_OK) {
00530 return TCL_ERROR;
00531 }
00532 if (thickness <0) thickness = 0;
00533 argc -= 2;
00534 argv += 2;
00535 continue;
00536 }
00537
00538
00539 Tcl_AppendResult(interp, "graphics: unknown option for text: ",
00540 argv[0], NULL);
00541 return TCL_ERROR;
00542 }
00543
00544
00545 char tmpstring[64];
00546 sprintf(tmpstring, "%d", gmol->add_text(vals+0, string, (float) size, (float) thickness));
00547 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00548 return TCL_OK;
00549 }
00550
00551
00552 static int tcl_graphics_spheretube(MoleculeGraphics *gmol, int argc, const char *argv[], Tcl_Interp *interp) {
00553
00554 AT_LEAST(2, "spheretube");
00555 float *coords = NULL;
00556 float *radii = NULL;
00557 float radius = 0.0f;
00558 float *rgb3fv = NULL;
00559 int *colorids = NULL;
00560 int numcoords = 0, numcolors = 0, numcolorids = 0;
00561 int radset = 0, numradii = 0;
00562 int drawtubes = 0;
00563 int res = 8;
00564
00565 if (tcl_get_vecarray(argv[0], numcoords, coords, interp) != TCL_OK) {
00566 delete [] coords;
00567 return TCL_ERROR;
00568 }
00569
00570
00571 argc -= 1;
00572 argv += 1;
00573
00574 while (argc) {
00575 if (!strcmp(argv[0], "colors")) {
00576 if (tcl_get_vecarray(argv[1], numcolors, rgb3fv, interp) != TCL_OK) {
00577 delete [] coords;
00578 delete [] rgb3fv;
00579 delete [] colorids;
00580 delete [] radii;
00581 return TCL_ERROR;
00582 }
00583
00584 argc -= 2;
00585 argv += 2;
00586 continue;
00587 }
00588
00589 if (!strcmp(argv[0], "colorids")) {
00590 if (tcl_get_intarray(argv[1], numcolorids, colorids, interp) != TCL_OK) {
00591 delete [] coords;
00592 delete [] rgb3fv;
00593 delete [] colorids;
00594 delete [] radii;
00595 return TCL_ERROR;
00596 }
00597
00598 rgb3fv = new float[numcolorids * 3];
00599 for (int idx=0; idx<numcolorids; idx++) {
00600 int id = colorids[idx];
00601
00602 if (id <0 && id >= MAXCOLORS) {
00603 char tmpstring[64];
00604 sprintf(tmpstring, "graphics spheretubes: color index value '%d' out of range", id);
00605 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00606 return TCL_ERROR;
00607 }
00608 }
00609
00610 argc -= 2;
00611 argv += 2;
00612 continue;
00613 }
00614
00615 if (!strcmp(argv[0], "radii")) {
00616 if (tcl_get_array(argv[1], numradii, radii, interp) != TCL_OK) {
00617 delete [] coords;
00618 delete [] rgb3fv;
00619 delete [] colorids;
00620 delete [] radii;
00621 return TCL_ERROR;
00622 }
00623 radset = 1;
00624 radius = float(radii[0]);
00625
00626 argc -= 2;
00627 argv += 2;
00628 continue;
00629 }
00630
00631 if (!strcmp(argv[0], "radius")) {
00632 double trad = 0.0;
00633 if (Tcl_GetDouble(interp, argv[1], &trad) != TCL_OK) {
00634 delete [] coords;
00635 delete [] rgb3fv;
00636 delete [] colorids;
00637 delete [] radii;
00638 return TCL_ERROR;
00639 }
00640 if (trad < 0) trad = 0;
00641 numradii = 1;
00642 radset = 1;
00643 radius = float(trad);
00644
00645 argc -= 2;
00646 argv += 2;
00647 continue;
00648 }
00649
00650 if (!strcmp(argv[0], "drawtubes")) {
00651 if (Tcl_GetInt(interp, argv[1], &drawtubes) != TCL_OK) {
00652 delete [] coords;
00653 delete [] rgb3fv;
00654 delete [] colorids;
00655 delete [] radii;
00656 return TCL_ERROR;
00657 }
00658 argc -= 2;
00659 argv += 2;
00660 continue;
00661 }
00662
00663 if (!strcmp(argv[0], "resolution")) {
00664 if (Tcl_GetInt(interp, argv[1], &res) != TCL_OK) {
00665 delete [] coords;
00666 delete [] rgb3fv;
00667 delete [] colorids;
00668 delete [] radii;
00669 return TCL_ERROR;
00670 }
00671 if (res < 8) res = 8;
00672 argc -= 2;
00673 argv += 2;
00674 continue;
00675 }
00676
00677
00678 Tcl_AppendResult(interp, "graphics: unknown option for spheretube: ",
00679 argv[0], NULL);
00680
00681 delete [] coords;
00682 delete [] rgb3fv;
00683 delete [] colorids;
00684 delete [] radii;
00685 return TCL_ERROR;
00686 }
00687
00688 #if 0
00689 printf("***spheretube: coords %d radii %d drawtubes: %d res %d\n",
00690 numcoords/3, numradii, drawtubes, res);
00691 #endif
00692
00693 if ((numcoords % 3)) {
00694 Tcl_SetResult(interp, (char *) "graphics: illegal spheretube coordinate vector length", TCL_STATIC);
00695 printf("total coordinate components not divible by 3!\n");
00696 delete [] coords;
00697 delete [] rgb3fv;
00698 delete [] colorids;
00699 delete [] radii;
00700 return TCL_ERROR;
00701 }
00702 if ((numradii > 1) && (numradii != (numcoords/3))) {
00703 Tcl_SetResult(interp, (char *) "graphics: spheretube requires matching count of coords and radii", TCL_STATIC);
00704 delete [] coords;
00705 delete [] rgb3fv;
00706 delete [] colorids;
00707 delete [] radii;
00708 return TCL_ERROR;
00709 }
00710 if ((numcolors > 0 || numcolorids > 0) &&
00711 (((numcolors != 0) && (numcolors != numcoords)) ||
00712 ((numcolorids != 0) && ((3*numcolorids) != numcoords)))) {
00713 Tcl_SetResult(interp, (char *) "graphics: spheretube requires matching count of coords and colors", TCL_STATIC);
00714 delete [] coords;
00715 delete [] rgb3fv;
00716 delete [] colorids;
00717 delete [] radii;
00718 return TCL_ERROR;
00719 }
00720 if ((!radset)) {
00721 Tcl_SetResult(interp, (char *) "graphics: spheretube requires either radius or radii parameter be set", TCL_STATIC);
00722 delete [] coords;
00723 delete [] rgb3fv;
00724 delete [] colorids;
00725 delete [] radii;
00726 return TCL_ERROR;
00727 }
00728
00729 int colorcnt = 0;
00730 if (numcolors > 0)
00731 colorcnt = numcolors / 3;
00732 if (numcolorids > 0)
00733 colorcnt = numcolorids;
00734
00735 char tmpstring[64];
00736 int gid = gmol->add_spheretube(numcoords/3, coords, numradii,
00737 (numradii > 1) ? radii : &radius,
00738 colorcnt, rgb3fv, colorids,
00739 drawtubes, res);
00740 sprintf(tmpstring, "%d", gid);
00741 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00742 return TCL_OK;
00743 }
00744
00745
00747
00748 static int tcl_graphics_delete(MoleculeGraphics *gmol, int argc, const char *argv[],
00749 Tcl_Interp *interp) {
00750 if (argc != 1) {
00751 Tcl_SetResult(interp, (char *) "graphics: delete takes one parameter (either an index or 'all')", TCL_STATIC);
00752 return TCL_ERROR;
00753 }
00754 if (!strcmp(argv[0], "all")) {
00755 gmol->delete_all();
00756 return TCL_OK;
00757 }
00758 int id;
00759 if (Tcl_GetInt(interp, argv[0], &id) != TCL_OK) {
00760 return TCL_ERROR;
00761 }
00762 gmol->delete_id(id);
00763 return TCL_OK;
00764 }
00765
00766
00767 static int tcl_graphics_replace(MoleculeGraphics *gmol, int argc, const char *argv[],
00768 Tcl_Interp *interp) {
00769 if (argc != 1) {
00770 Tcl_SetResult(interp, (char *) "graphics: replace takes one parameter, the index", TCL_STATIC);
00771 return TCL_ERROR;
00772 }
00773 int id;
00774 if (Tcl_GetInt(interp, argv[0], &id) != TCL_OK) {
00775 return TCL_ERROR;
00776 }
00777 gmol->replace_id(id);
00778 return TCL_OK;
00779 }
00780
00781
00782 static int tcl_graphics_exists(MoleculeGraphics *gmol, int argc, const char *argv[],
00783 Tcl_Interp *interp) {
00784 if (argc != 1) {
00785 Tcl_SetResult(interp, (char *) "graphics: exists takes one parameter, the index", TCL_STATIC);
00786 return TCL_ERROR;
00787 }
00788 int id;
00789 if (Tcl_GetInt(interp, argv[0], &id) != TCL_OK) {
00790 return TCL_ERROR;
00791 }
00792
00793 char tmpstring[64];
00794 sprintf(tmpstring, "%d", gmol->index_id(id) != -1);
00795 Tcl_SetResult(interp, tmpstring, TCL_VOLATILE);
00796 return TCL_OK;
00797 }
00798
00799
00800 static int tcl_graphics_info(MoleculeGraphics *gmol,
00801 int argc, const char *argv[],
00802 Tcl_Interp *interp)
00803 {
00804 if (argc != 1) {
00805 Tcl_SetResult(interp, (char *) "graphics: info takes one parameter, the index", TCL_STATIC);
00806 return TCL_ERROR;
00807 }
00808 int id;
00809 if (Tcl_GetInt(interp, argv[0], &id) != TCL_OK) {
00810 return TCL_ERROR;
00811 }
00812
00813 Tcl_AppendResult(interp, gmol->info_id(id), NULL);
00814 return TCL_OK;
00815 }
00816
00817
00818
00819
00820 static int tcl_graphics(VMDApp *app, int molid, int argc, const char *argv[],
00821 Tcl_Interp *interp)
00822 {
00823
00824 Molecule *mol = app->moleculeList->mol_from_id(molid);
00825 if (mol == NULL) {
00826 Tcl_SetResult(interp, (char *) "graphics: invalid graphics molecule", TCL_STATIC);
00827 return TCL_ERROR;
00828 }
00829 if (argc < 1) {
00830 Tcl_SetResult(interp, (char *) "graphics: not enough parameters", TCL_STATIC);
00831 return TCL_ERROR;
00832 }
00833 MoleculeGraphics *gmol = mol->moleculeGraphics();
00834
00835 if (!strcmp(argv[0], "list")) {
00836 if (argc != 1) {
00837 Tcl_SetResult(interp, (char *) "graphics: list takes no parameters", TCL_STATIC);
00838 return TCL_ERROR;
00839 }
00840 int num = gmol->num_elements();
00841 for (int i=0; i<num; i++) {
00842 int id = gmol->element_id(i);
00843 if (id >=0) {
00844 char s[16];
00845 sprintf(s, "%d", id);
00846 Tcl_AppendElement(interp, s);
00847 }
00848 }
00849 return TCL_OK;
00850 }
00851
00852 if (argc < 2) {
00853 Tcl_SetResult(interp, (char *) "graphics: not enough parameters", TCL_STATIC);
00854 return TCL_ERROR;
00855 }
00856 if (!strcmp(argv[0], "triangle")) {
00857 return tcl_graphics_triangle(gmol, argc-1, argv+1, interp);
00858 }
00859 if (!strcmp(argv[0], "trinorm")) {
00860 return tcl_graphics_trinorm(gmol, argc-1, argv+1, interp);
00861 }
00862 if (!strcmp(argv[0], "tricolor")) {
00863 return tcl_graphics_tricolor(gmol, argc-1, argv+1, interp);
00864 }
00865 if (!strcmp(argv[0], "point")) {
00866 return tcl_graphics_point(gmol, argc-1, argv+1, interp);
00867 }
00868 if (!strcmp(argv[0], "pickpoint")) {
00869 return tcl_graphics_pickpoint(gmol, argc-1, argv+1, interp);
00870 }
00871 if (!strcmp(argv[0], "line")) {
00872 return tcl_graphics_line(gmol, argc-1, argv+1, interp);
00873 }
00874 if (!strcmp(argv[0], "cylinder")) {
00875 return tcl_graphics_cylinder(gmol, argc-1, argv+1, interp);
00876 }
00877 if (!strcmp(argv[0], "cone")) {
00878 return tcl_graphics_cone(gmol, argc-1, argv+1, interp);
00879 }
00880 if (!strcmp(argv[0], "sphere")) {
00881 return tcl_graphics_sphere(gmol, argc-1, argv+1, interp);
00882 }
00883 if (!strcmp(argv[0], "text")) {
00884 return tcl_graphics_text(gmol, argc-1, argv+1, interp);
00885 }
00886 if (!strcmp(argv[0], "spheretube")) {
00887 return tcl_graphics_spheretube(gmol, argc-1, argv+1, interp);
00888 }
00889 if (!strcmp(argv[0], "materials")) {
00890 return tcl_graphics_materials(gmol, argc-1, argv+1, interp);
00891 }
00892 if (!strcmp(argv[0], "material")) {
00893 return tcl_graphics_material(gmol, argc-1, argv+1, interp,
00894 app->materialList);
00895 }
00896 if (!strcmp(argv[0], "color") || !strcmp(argv[1], "colour")) {
00897 return tcl_graphics_color(app, gmol, argc-1, argv+1, interp);
00898 }
00899 if (!strcmp(argv[0], "delete")) {
00900 return tcl_graphics_delete(gmol, argc-1, argv+1, interp);
00901 }
00902 if (!strcmp(argv[0], "exists")) {
00903 return tcl_graphics_exists(gmol, argc-1, argv+1, interp);
00904 }
00905 if (!strcmp(argv[0], "replace")) {
00906 return tcl_graphics_replace(gmol, argc-1, argv+1, interp);
00907 }
00908 if (!strcmp(argv[0], "info")) {
00909 return tcl_graphics_info(gmol, argc-1, argv+1, interp);
00910 }
00911 Tcl_AppendResult(interp, "graphics: don't understand the command: ",
00912 argv[0], NULL);
00913 return TCL_ERROR;
00914 }
00915
00916
00917
00918 int graphics_tcl(ClientData cd, Tcl_Interp *interp, int argc, const char *argv[]) {
00919
00920 if (argc < 2) {
00921 Tcl_SetResult(interp, (char *) "graphics: not enough parameters", TCL_STATIC);
00922 return TCL_ERROR;
00923 }
00924
00925 VMDApp *app = (VMDApp *)cd;
00926
00927 int mol = -1;
00928 if (!strcmp(argv[1], "top")) {
00929 if (app->moleculeList->top()) {
00930 mol = app->moleculeList->top()->id();
00931 }
00932 } else {
00933 if (Tcl_GetInt(interp, argv[1], &mol) != TCL_OK) {
00934 return TCL_ERROR;
00935 }
00936 }
00937
00938 return tcl_graphics(app, mol, argc-2, argv+2, interp);
00939 }
00940
00941