00001 #include <iostream>
00002 #include <fstream>
00003 #include <math.h>
00004 #include <string.h>
00005 #include <libxml/xmlmemory.h>
00006
00007 #include <GL/glut.h>
00008 #include <GL/glx.h>
00009 #include <GL/glu.h>
00010 #include <X11/keysym.h>
00011 #include "def.h"
00012 #include "run.h"
00013 #include "io.h"
00014 using namespace std;
00015 #include "list.h"
00016 #include "collection.h"
00017 #include "model.h"
00018 #include "species.h"
00019 using namespace Species;
00020 #include "domain.h"
00021 #include "gui.h"
00022
00023 namespace Gui {
00024 Domain *domain;
00025 ElementDisp disp[maxelements];
00026 char *configfile=(char*)"gui.cfg",
00027 windowname[MAXLINLEN];
00028 int
00029 showpar[maxshowpars],
00030 finished,
00031 animation,
00032 nwdump,iwdump,
00033 attributeList[] =
00034 { GLX_RGBA,
00035 GLX_RED_SIZE, 1,
00036 GLX_GREEN_SIZE, 1,
00037 GLX_BLUE_SIZE, 1,
00038 GLX_DOUBLEBUFFER,
00039 GLX_DEPTH_SIZE, 1,
00040 None
00041 };
00042 REAL
00043 step,
00044 vecval[maxlineprm],
00045 axes[maxaxesprm],
00046 rgbcolor[maxcolor][3],
00047 wdtime,
00048 xo[3],
00049 dx,dy,dz,
00050 lastx, lasty, lastz;
00051
00052
00053 int mouseButtons[3];
00054 REAL zoom;
00055 REAL rotx;
00056 REAL roty;
00057 REAL tx;
00058 REAL ty;
00059
00060 REAL
00061 xmin[DIM],xmax[DIM],
00062 lx,ly,lz,lmin,lmax;
00063
00064 enum Movement movement;
00065
00066 struct ColorScale colorscale;
00067 struct Scene scene;
00068 struct WindowGeom window;
00069
00070 struct BFaceList *bface_root;
00071
00072 Display *dpy;
00073 Window win;
00074
00075 int firstR = 1;
00076 int *vars, *coms;
00077
00078 int query_extension(char* extName)
00079 {
00080 char *p = (char *) glGetString(GL_EXTENSIONS);
00081 char *end = p + strlen(p);
00082 while (p < end)
00083 {
00084 int n = strcspn(p, " ");
00085 if ((strlen(extName) == n) && (strncmp(extName, p, n) == 0))
00086 return GL_TRUE;
00087 p += (n + 1);
00088 }
00089 return GL_FALSE;
00090 }
00091 void init(int argc, char* argv[], Domain *newdomain) {
00092
00093 domain=newdomain;
00094
00095 scene.color.scheme=colorByMass;
00096 glutInit(&argc, argv);
00097 mouseButtons[0] = 0;
00098 mouseButtons[1] = 0;
00099 mouseButtons[2] = 0;
00100 zoom = 15.0f;
00101 rotx = 0.0f;
00102 roty = 0.001f;
00103 tx = 0.0f;
00104 ty = 0.0f;
00105 lastx = 0.0;
00106 lasty = 0.0;
00107 showpar[dumpWindow] = 0;
00108 showpar[showRun] = 1;
00109 showpar[showAxes] = 1;
00110 showpar[showSpheres] = 0;
00111 showpar[showNodes] = 1;
00112 showpar[showVariables] = 0;
00113 showpar[showBoundaryVertexes] = 0;
00114 showpar[showBoundaryVectors] = 0;
00115 showpar[showToolVertexes] = 0;
00116 showpar[showFrame] = 0;
00117 showpar[showBoundaryFaceCenters] = 0;
00118 showpar[showBoundaryFaces] = 0;
00119 showpar[showBoundaryGrid] = 0;
00120 showpar[showToolGrid] = 0;
00121 showpar[showCellCenters] = 0;
00122 showpar[showFaceCenters] = 0;
00123 showpar[showBonds] = 0;
00124 showpar[showGrid] = 0;
00125 finished=0;
00126 animation=0;
00127 lastz=1.0;
00128
00129 wdtime=-1.0;
00130 XVisualInfo *vi;
00131 XSetWindowAttributes swa;
00132 GLXContext cx;
00133 sprintf(windowname,"%s",argv[0]);
00134 initdisp();
00135 dpy = XOpenDisplay(0);
00136 if (!dpy) ERROR("CAN'T OPEN DISPLAY");
00137 vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList);
00138 if (!vi) ERROR("NO SUITABLE VISUAL");
00139 cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
00140 swa.colormap = XCreateColormap
00141 ( dpy,
00142 RootWindow(dpy, vi->screen),
00143 vi->visual, AllocNone
00144 );
00145 swa.border_pixel = 0;
00146 swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask |
00147 ButtonPressMask | ButtonMotionMask;
00148 if(Run::option.debug)
00149 printf
00150 ( "Open window: width=%d, height=%d\n",
00151 window.width,window.height
00152 );
00153 if(Run::option.debug)
00154 printf("Window: width=%d, height=%d\n",window.width, window.height);
00155 win=XCreateWindow
00156 ( dpy,
00157 RootWindow(dpy, vi->screen),
00158 0, 0, window.width, window.height,
00159 0, vi->depth, InputOutput, vi->visual,
00160 CWBorderPixel|CWColormap|CWEventMask, &swa
00161 );
00162 XStoreName(dpy, win, windowname);
00163 XMapWindow(dpy, win);
00164 glXMakeCurrent(dpy, win, cx);
00165
00166 #ifndef GL_VERSION_1_1
00167 if (!query_extension("GL_EXT_polygon_offset"))
00168 error(argv[0], "polygon_offset extension is not available");
00169 #else
00170 (void) query_extension;
00171 #endif
00172 Materials(argc, argv);
00173 helpDisplay();
00174 }
00175 void helpDisplay() {
00176 printf("MOUSE CONTROL:\n");
00177 printf("left button & drag - rotate\n");
00178 printf("right button & drag - translate\n");
00179 printf("KEYSTROKE COMMANDS:\n");
00180 printf("? - show help\n");
00181 printf("a - show/hide axes\n");
00182 printf("c - switch color scheme\n");
00183 printf("f - show/hide frame\n");
00184 printf("G(g) - show/hide (boundary) grid\n");
00185 printf("i - initialize domains\n");
00186 printf("l - load configuration from %s\n",configfile);
00187 printf("n - show/hide nodes\n");
00188 printf("o - toggle output\n");
00189 printf("q - quit without saving\n");
00190 printf("r - run\n");
00191 printf("s - advance one iteration step\n");
00192 printf("t(T) - toggle pores nodes\n");
00193 printf("w - write data at this time step into %s-<number>.dat.gz\n",Run::outputname);
00194 printf("+ - move forward along the arrow-axis\n");
00195 printf("- - move backward along the arrow-axis\n");
00196 printf(": - command mode\n esc: exit\n");
00197 }
00198 int readparam(
00199 char *s,
00200 char *param[],
00201 int maxparam,
00202 char *filename,
00203 int val[]
00204 )
00205 { int i;
00206 for (i=0; i<maxparam; i++)
00207 { int lparam;
00208 if(param[i]==NULL) continue;
00209 lparam=strlen(param[i]);
00210 if
00211 ( lparam>0 &&
00212 (*(s+lparam)==' ' || *(s+lparam)=='=')
00213 && memcmp(s,param[i],lparam)==0
00214 ) break;
00215 }
00216 if (i<maxparam)
00217 { if ((s=strchr(s,'='))==NULL)
00218 { fprintf
00219 ( stderr,
00220 "WARNING: wrong format at '%s' in file %s\n\t-> IGNORED\n",
00221 s,filename
00222 );
00223 return -1;
00224 }
00225 while(isspace(*++s));
00226 sscanf(s,"%d",&val[i]);
00227 }
00228 return i;
00229 }
00230 int readparam(
00231 char *s,
00232 char *param[],
00233 int maxparam,
00234 char *filename,
00235 REAL val[]
00236 )
00237 { int i;
00238 for (i=0; i<maxparam; i++)
00239 { int lparam=strlen(param[i]);
00240 if
00241 ( (*(s+lparam)==' ' || *(s+lparam)=='=')
00242 && memcmp(s,param[i],lparam)==0
00243 ) break;
00244 }
00245 if (i<maxparam)
00246 { if ((s=strchr(s,'='))==NULL)
00247 { fprintf
00248 ( stderr,
00249 "WARNING: wrong format at '%s' in file %s\n\t-> IGNORED\n",
00250 s,filename
00251 );
00252 return -1;
00253 }
00254 while(isspace(*++s));
00255 sscanf(s,"%g",&val[i]);
00256 }
00257 return i;
00258 }
00259 void readconf() {
00260 using namespace IO;
00261 int i;
00262 char
00263 *colorname[maxcolor],
00264 *showparnam[maxshowpars],
00265 *pointparam[maxpointprm],
00266 *lineparam[maxlineprm],
00267 *axesprmnam[maxaxesprm],
00268
00269 *filename=configfile,
00270 buf[MAXLINLEN],*s;
00271 REAL a;
00272 FILE *file;
00273 colorname [red ]=strdup("color.red");
00274 colorname [green ]=strdup("color.green");
00275 colorname [blue ]=strdup("color.blue");
00276 colorname [skyblue ]=strdup("color.skyblue");
00277 colorname [brown ]=strdup("color.brown");
00278 colorname [magenta ]=strdup("color.magenta");
00279 for (int i=magenta+1;i<maxcolor;i++)
00280 { char name[MAXLINLEN];
00281 sprintf(name,"color%d",i);
00282 colorname[i]=strdup(name);
00283 }
00284
00285 for (int i=0;i<maxshowpars;i++)
00286 showparnam[i]=NULL;
00287 showparnam[showSpheres]=strdup("spheres" );
00288 pointparam[variable ]=strdup("variable" );
00289 pointparam[size ]=strdup("size" );
00290 pointparam[sizevar ]=strdup("sizevar" );
00291 pointparam[massvar ]=strdup("massvar" );
00292 pointparam[vmin ]=strdup("value.min" );
00293 pointparam[vmax ]=strdup("value.max" );
00294 lineparam [thickness]=strdup("thickness" );
00295 lineparam [length ]=strdup("length" );
00296 axesprmnam[axeswidth]=strdup("width" );
00297 axesprmnam[xaxislength]=strdup("length.x" );
00298 axesprmnam[yaxislength]=strdup("length.y" );
00299 axesprmnam[zaxislength]=strdup("length.z" );
00300 axesprmnam[arrowidth ]=strdup("arrow.width");
00301 axesprmnam[arrowheight]=strdup("arrow.length");
00302 for (i=0; i<maxcolor; i++)
00303 { pointparam[i]=strdup(colorname[i]);
00304 lineparam [i]=strdup(colorname[i]);
00305
00306 }
00307
00308
00309
00310
00311
00312
00313
00314 step=1.0;
00315 int colorscheme=0;
00316 scene.mesh.node[size]=1.0;
00317 scene.mesh.node[vmin]=0.0;
00318 scene.mesh.node[vmax]=1.0;
00319 scene.mesh.node[red]=0.0;
00320 scene.mesh.node[green]=1.0;
00321 scene.mesh.node[blue]=0.0;
00322 scene.mesh.line[thickness]=1.0;
00323 scene.mesh.line[red]=1.0;
00324 scene.mesh.line[green]=0.0;
00325 scene.mesh.line[blue]=0.0;
00326 scene.frame.line[thickness]=1.0;
00327 scene.frame.line[red]=1.0;
00328 scene.frame.line[green]=1.0;
00329 scene.frame.line[blue]=0.0;
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 for(int i=0;i<DIM;i++) {
00381 xmin[i]=domain->minBound(i);
00382 xmax[i]=domain->maxBound(i);
00383 }
00384
00385 char *doctype=(char*)DOCTYPE;
00386 char *inpfilename=Run::configfile;
00387
00388
00389 char *p,word[MAXLINLEN];
00390 FILE *inp;
00391 if(Run::option.verbose)printf("Domain::inpfilename=%s\n",inpfilename);
00392 xmlDocPtr doc;
00393 xmlNodePtr root;
00394
00395 if (Run::option.verbose|Run::option.debug)
00396 { printf
00397 ( "Reading geometry from %s\n",
00398 inpfilename
00399 );fflush(stdout);
00400 }
00401 doc = xmlParseFile(inpfilename);
00402 if (doc == NULL )
00403 { fprintf(stderr,"XML parser failed in %s\n",inpfilename);
00404 exit(1);
00405 }
00406 root = xmlDocGetRootElement(doc);
00407 if (root == NULL)
00408 { fprintf(stderr,"Empty document: %s\n",inpfilename);
00409 xmlFreeDoc(doc);
00410 return;
00411 }
00412 if (xmlStrcmp(root->name, (const xmlChar *) doctype))
00413 { fprintf
00414 ( stderr,
00415 "document of the wrong type, root node != %s in %s\n",
00416 doctype,inpfilename
00417 );
00418 xmlFreeDoc(doc);
00419 return;
00420 }
00421 for
00422 ( xmlNodePtr cur = root->xmlChildrenNode;
00423 cur != NULL; cur = cur->next
00424 )
00425 {
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 if ((!xmlStrcmp(cur->name, (const xmlChar *)"gui"))) {
00487 for(xmlNodePtr gui = cur->xmlChildrenNode; gui != NULL; gui = gui->next) {
00488
00489 if((!xmlStrcmp(gui->name, (const xmlChar *)"translation"))) {
00490 if( parseWord(doc, gui, (char*)"step", word) != 0 ) {
00491 REAL step = (REAL)atof(word);
00492 if(Run::option.verbose) cout << "Translation step = " << step << endl;
00493 }
00494 }
00495
00496 if((!xmlStrcmp(gui->name, (const xmlChar *)"vector"))) {
00497 if(Run::option.verbose) cout<<"Vector parameters:\n";
00498 if( parseWord(doc, gui, (char*)"length", word) != 0 ) {
00499 REAL veclength = (REAL)atof(word);
00500 if(Run::option.verbose) cout << "\tlength = " << veclength << endl;
00501 vecval[length]=veclength;
00502 }
00503
00504 if( parseWord(doc, gui, (char*)"thickness", word) != 0 ) {
00505 REAL vecthickness = (REAL)atof(word);
00506 if(Run::option.verbose) cout << "\tthickness = " << vecthickness << endl;
00507 vecval[thickness]=vecthickness;
00508 }
00509 for(xmlNodePtr color = gui->xmlChildrenNode; color != NULL; color = color->next) {
00510 if ((!xmlStrcmp(color->name, (const xmlChar *)"color"))) {
00511 if( parseWord(doc, color, (char*)"red", word) != 0 ) {
00512 REAL vectorRed = (REAL)atof(word);
00513 if(Run::option.verbose)
00514 cout << "\tColor Red = " << vectorRed << endl;
00515 vecval[red]=vectorRed;
00516 }
00517
00518 if( parseWord(doc, color, (char*)"green", word) != 0 ) {
00519 REAL vectorGreen = (REAL)atof(word);
00520 if(Run::option.verbose)
00521 cout << "\tColor Green = " << vectorGreen << endl;
00522 vecval[green]=vectorGreen;
00523 }
00524
00525 if( parseWord(doc, color, (char*)"blue", word) != 0 )
00526 {
00527 REAL vectorBlue = (REAL)atof(word);
00528 if(Run::option.verbose)
00529 cout << "\tColor Blue = " << vectorBlue << endl;
00530 vecval[blue]=vectorBlue;
00531 }
00532 }
00533 }
00534 }
00535 if((!xmlStrcmp(gui->name, (const xmlChar *)"frame"))) {
00536 if(Run::option.verbose)cout<<"Frame parameters\n";
00537 for( xmlNodePtr fr = gui->xmlChildrenNode;
00538 fr != NULL; fr = fr->next
00539 ) {
00540 if ((!xmlStrcmp(fr->name, (const xmlChar *)"line"))) {
00541 if(Run::option.verbose)cout<<"\tLine\n";
00542 if( parseWord(doc, fr, (char*)"thickness", word) != 0 ) {
00543 REAL lineThickness = (REAL)atof(word);
00544 if(Run::option.verbose) cout << "\t\tThickness = " << lineThickness << endl;
00545 scene.frame.line[thickness]=lineThickness;
00546 }
00547 for(xmlNodePtr color = fr->xmlChildrenNode;
00548 color != NULL; color = color->next) {
00549 if ((!xmlStrcmp(color->name, (const xmlChar *)"color"))) {
00550 if(Run::option.verbose)cout<<"\t\tColor\n";
00551 if( parseWord(doc, color, (char*)"red", word) != 0 ) {
00552 REAL lineRed = (REAL)atof(word);
00553 if(Run::option.verbose) cout << "\t\t\tRed = " << lineRed << endl;
00554 scene.frame.line[red]=lineRed;
00555 }
00556 if( parseWord(doc, color, (char*)"green", word) != 0 ) {
00557 REAL lineGreen = (REAL)atof(word);
00558 if(Run::option.verbose) cout << "\t\t\tGreen = " << lineGreen << endl;
00559 scene.frame.line[green]=lineGreen;
00560 }
00561 if( parseWord(doc, color, (char*)"blue", word) != 0 ) {
00562 REAL lineBlue = (REAL)atof(word);
00563 if(Run::option.verbose) cout << "\t\t\tBlue = " << lineBlue << endl;
00564 scene.frame.line[blue]=lineBlue;
00565 }
00566 REAL rgbcolor[3];
00567 rgbcolor[0]=scene.frame.line[red];
00568 rgbcolor[1]=scene.frame.line[green];
00569 rgbcolor[2]=scene.frame.line[blue];
00570 setElementColor(frame,rgbcolor);
00571 }
00572 }
00573 }
00574 }
00575 }
00576 if((!xmlStrcmp(gui->name, (const xmlChar *)"mesh"))) {
00577 if(Run::option.verbose)cout<<"Mesh parameters\n";
00578 for( xmlNodePtr fr = gui->xmlChildrenNode;
00579 fr != NULL; fr = fr->next
00580 ) {
00581 if ((!xmlStrcmp(fr->name, (const xmlChar *)"node"))) {
00582 if(Run::option.verbose)cout<<"\tNode\n";
00583 if( parseWord(doc, fr, (char*)"type", word) != 0 ) {
00584 if(Run::option.verbose) cout << "\t\tType = " << word << endl;
00585 showpar[showSpheres] = 0;
00586 if(strncmp(word,"sphere",6)==0) showpar[showSpheres]=1;
00587 }
00588 for(xmlNodePtr colors = fr->xmlChildrenNode;
00589 colors != NULL; colors = colors->next) {
00590 if ((!xmlStrcmp(colors->name, (const xmlChar *)"colorscheme"))) {
00591 if(Run::option.verbose)cout<<"\t\tColor Scheme\n";
00592 if( parseWord(doc, colors, (char*)"variable", word) != 0 ) {
00593 if(Run::option.verbose) cout << "\t\tVariable = " << word << endl;
00594 colorscheme=0;
00595 if(strcmp(word,"type")==0) colorscheme=(int)colorByType;
00596 else if(strcmp(word,"mass")==0) colorscheme=(int)colorByMass;
00597 }
00598 scene.color.minvalue=0.0;
00599 if( parseWord(doc, colors, (char*)"minvalue", word) != 0 ) {
00600 if(Run::option.verbose) cout << "\t\tMin Value = " << word << endl;
00601 REAL minvalue=(REAL)atof(word);
00602 scene.color.minvalue=minvalue;
00603 }
00604 scene.color.maxvalue=1.0;
00605 if( parseWord(doc, colors, (char*)"maxvalue", word) != 0 ) {
00606 if(Run::option.verbose) cout << "\t\tMax Value = " << word << endl;
00607 REAL maxvalue=(REAL)atof(word);
00608 scene.color.maxvalue=maxvalue;
00609 }
00610 }
00611 }
00612 if( parseWord(doc, fr, (char*)"size", word) != 0 ) {
00613 REAL nodeSize = (REAL)atof(word);
00614 if(Run::option.verbose) cout << "\t\tSize = " << nodeSize << endl;
00615 scene.mesh.node[size]=nodeSize;
00616 }
00617 for(xmlNodePtr color = fr->xmlChildrenNode; color != NULL; color = color->next) {
00618 if ((!xmlStrcmp(color->name, (const xmlChar *)"color"))) {
00619 if(Run::option.verbose)cout<<"\t\tColor\n";
00620 if( parseWord(doc, color, (char*)"red", word) != 0 ) {
00621 REAL lineRed = (REAL)atof(word);
00622 if(Run::option.verbose) cout << "\t\t\tRed = " << lineRed << endl;
00623 scene.mesh.node[red]=lineRed;
00624 }
00625 if( parseWord(doc, color, (char*)"green", word) != 0 ) {
00626 REAL lineGreen = (REAL)atof(word);
00627 if(Run::option.verbose) cout << "\t\t\tGreen = " << lineGreen << endl;
00628 scene.mesh.node[green]=lineGreen;
00629 }
00630 if( parseWord(doc, color, (char*)"blue", word) != 0 ) {
00631 REAL lineBlue = (REAL)atof(word);
00632 if(Run::option.verbose) cout << "\t\t\tBlue = " << lineBlue << endl;
00633 scene.mesh.node[blue]=lineBlue;
00634 }
00635 REAL rgbcolor[3];
00636 rgbcolor[0]=scene.mesh.node[red];
00637 rgbcolor[1]=scene.mesh.node[green];
00638 rgbcolor[2]=scene.mesh.node[blue];
00639 setElementColor(nodes,rgbcolor);
00640 }
00641 }
00642 }
00643 if ((!xmlStrcmp(fr->name, (const xmlChar *)"line"))) {
00644 if(Run::option.verbose)cout<<"\tLine\n";
00645 if( parseWord(doc, fr, (char*)"thickness", word) != 0 ) {
00646 REAL lineThickness = (REAL)atof(word);
00647 if(Run::option.verbose) cout << "\t\tThickness = " << lineThickness << endl;
00648 scene.mesh.line[thickness]=lineThickness;
00649 }
00650 for(xmlNodePtr color = fr->xmlChildrenNode;
00651 color != NULL; color = color->next) {
00652 if ((!xmlStrcmp(color->name, (const xmlChar *)"color"))) {
00653 if(Run::option.verbose)cout<<"\t\tColor\n";
00654 if( parseWord(doc, color, (char*)"red", word) != 0 ) {
00655 REAL lineRed = (REAL)atof(word);
00656 if(Run::option.verbose) cout << "\t\t\tRed = " << lineRed << endl;
00657 scene.mesh.line[red]=lineRed;
00658 }
00659 if( parseWord(doc, color, (char*)"green", word) != 0 ) {
00660 REAL lineGreen = (REAL)atof(word);
00661 if(Run::option.verbose) cout << "\t\t\tGreen = " << lineGreen << endl;
00662 scene.mesh.line[green]=lineGreen;
00663 }
00664 if( parseWord(doc, color, (char*)"blue", word) != 0 ) {
00665 REAL lineBlue = (REAL)atof(word);
00666 if(Run::option.verbose) cout << "\t\t\tBlue = " << lineBlue << endl;
00667 scene.mesh.line[blue]=lineBlue;
00668 }
00669 REAL rgbcolor[3];
00670 rgbcolor[0]=scene.mesh.line[red];
00671 rgbcolor[1]=scene.mesh.line[green];
00672 rgbcolor[2]=scene.mesh.line[blue];
00673 setElementColor(mesh,rgbcolor);
00674 }
00675 }
00676 }
00677 }
00678 }
00679 }
00680 }
00681 }
00682 xmlFreeDoc(doc);
00683 dx=step*lx;
00684 dy=step*ly;
00685 dz=step*lz;
00686 scene.color.scheme=(ColorSchemes) colorscheme;
00687 if(Run::option.verbose){printf("File %s parsed\n",inpfilename);fflush(stdout);}
00688 }
00689 void refresh() {
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 }
00701 void initdisp() {
00702 if(Run::option.debug){printf("Initializing display\n");fflush(stdout);}
00703 rgbcolor[red ][red ]=1.0;
00704 rgbcolor[red ][green ]=0.0;
00705 rgbcolor[red ][blue ]=0.0;
00706 rgbcolor[green ][red ]=0.0;
00707 rgbcolor[green ][green ]=1.0;
00708 rgbcolor[green ][blue ]=0.0;
00709 rgbcolor[blue ][red ]=0.0;
00710 rgbcolor[blue ][green ]=0.0;
00711 rgbcolor[blue ][blue ]=1.0;
00712 rgbcolor[skyblue][red ]=0.0;
00713 rgbcolor[skyblue][green ]=1.0;
00714 rgbcolor[skyblue][blue ]=1.0;
00715 rgbcolor[brown ][red ]=1.0;
00716 rgbcolor[brown ][green ]=1.0;
00717 rgbcolor[brown ][blue ]=0.0;
00718 rgbcolor[magenta][red ]=1.0;
00719 rgbcolor[magenta][green ]=0.0;
00720 rgbcolor[magenta][blue ]=1.0;
00721 rgbcolor[yellow][red ]=1.0;
00722 rgbcolor[yellow][green ]=1.0;
00723 rgbcolor[yellow][blue ]=0.0;
00724 colorscale.relative=0;
00725 if (maxcolor>6)
00726 { int
00727 ncolor=(int)pow((double)maxcolor,1./3.),
00728 icolor=5;
00729 for (int ired =1; ired <ncolor; ired++ )
00730 for (int igreen=1; igreen<ncolor; igreen++ )
00731 for (int iblue =1; iblue <ncolor; iblue++ )
00732 { if (++icolor>=maxcolor) break;
00733 rgbcolor[icolor][ired ]=(REAL)ired /(REAL)ncolor;
00734 rgbcolor[icolor][igreen]=(REAL)igreen/(REAL)ncolor;
00735 rgbcolor[icolor][iblue ]=(REAL)iblue /(REAL)ncolor;
00736 }
00737 }
00738 vecval[length ]=.2;
00739 vecval[thickness]=1.5;
00740 vecval[red ]=0.5;
00741 vecval[green ]=1.0;
00742 vecval[blue ]=1.0;
00743 axes[axeswidth ]=5.0;
00744 axes[xaxislength]=0.1;
00745 axes[yaxislength]=0.1;
00746 axes[zaxislength]=0.1;
00747 axes[arrowheight]=0.1;
00748 axes[arrowidth ]=0.03;
00749
00750 scene.frame.line[thickness]=1.0;
00751 scene.frame.line[red ]=1.0;
00752 scene.frame.line[green ]=0.0;
00753 scene.frame.line[blue ]=0.0;
00754 scene.mesh.node[size ]=1.0;
00755 scene.mesh.node[red ]=1.;
00756 scene.mesh.node[green]=1.;
00757 scene.mesh.node[blue ]=0.;
00758 scene.mesh.line[thickness]=1.0;
00759 scene.mesh.line[red ]=1.0;
00760 scene.mesh.line[green ]=0.0;
00761 scene.mesh.line[blue ]=0.0;
00762 for (int eltype=0; eltype<maxelements; eltype++)
00763 setElementColor(eltype,rgbcolor[(eltype)%maxcolor]);
00764 setElementColor(nodes,rgbcolor[green]);
00765 setElementColor(edges,rgbcolor[red]);
00766 setElementColor(faces,rgbcolor[brown]);
00767 setElementColor(cells,rgbcolor[skyblue]);
00768 setElementColor(frame,rgbcolor[yellow]);
00769 setElementColor(mesh,rgbcolor[red]);
00770 readconf();
00771
00772 if(domain->Molecules()->number()==0) {
00773 for(int i=0;i<DIM;i++) {
00774 domain->setMinBound(i,xmin[i]);
00775 domain->setMaxBound(i,xmax[i]);
00776 }
00777 }
00778 if(Run::option.debug)
00779 { printf
00780 ( "Grid limits: xmin={%g,%g,%g}, xmax={%g,%g,%g}\n",
00781 xmin[0],xmin[1],xmin[2],xmax[0],xmax[1],xmax[2]
00782 ); fflush(stdout);
00783 }
00784
00785
00786 lmin= LARGE;
00787 lmax=-LARGE;
00788 lx=xmax[0]-xmin[0];
00789 ly=xmax[1]-xmin[1];
00790 lz=xmax[2]-xmin[2];
00791 if (lx>lmax) lmax=lx;
00792 if (ly>lmax) lmax=ly;
00793 if (lz>lmax) lmax=lz;
00794 if (lx<lmin) lmin=lx;
00795 if (ly<lmin) lmin=ly;
00796 if (lz<lmin) lmin=lz;
00797 xo[0]=xmin[0]+.5*lx;
00798 xo[1]=xmin[1]+.5*ly;
00799 xo[2]=xmin[2]+.5*lz;
00800 lx=ly=lz=lmax;
00801 dx=step*lx;
00802 dy=step*ly;
00803 dz=step*lz;
00804 zoom=1.4*lz;
00805 if (Run::option.debug|Run::option.verbose)
00806 printf("Origin of coordinate axes: %g\t%g\t%g\n",xo[0],xo[1],xo[2]);
00807 { REAL window_size;
00808 window_size=1.5*WINDOW_SIZE/sqrt(lx*lx+ly*ly);
00809 window.width=(int)(window_size*lx);
00810 if (window.width>MAX_WINDOW_WIDTH)window.width=MAX_WINDOW_WIDTH;
00811 window.height=(int)(window_size*ly);
00812 if (window.height>MAX_WINDOW_HEIGHT)window.height=MAX_WINDOW_HEIGHT;
00813 }
00814
00815 }
00816
00817
00818 void Materials(int argc, char *argv[]) {
00819 GLfloat mat[4] = { 0.8, 0.7, 0.5, 1.0 },
00820 shine=0.6;
00821 if(Run::option.debug)
00822 { printf("Materials: argc=%d",argc);fflush(stdout);
00823 for (int i=0; i<argc; i++)
00824 printf(" '%s'",argv[i]);
00825 printf("\n");fflush(stdout);
00826 }
00827
00828 GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
00829 GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
00830 GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 };
00831 GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
00832 GLfloat local_view[] = { 0.0 };
00833 glEnable(GL_DEPTH_TEST);
00834 glDepthFunc(GL_LESS);
00835 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
00836 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
00837 glLightfv(GL_LIGHT0, GL_POSITION, position);
00838 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
00839 glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
00840 glFrontFace (GL_CW);
00841 glEnable(GL_LIGHTING);
00842 glEnable(GL_LIGHT0);
00843 glEnable(GL_AUTO_NORMAL);
00844 glEnable(GL_NORMALIZE);
00845 glMatrixMode (GL_MODELVIEW);
00846 glLoadIdentity ();
00847 glClearColor(0.0, 0.0, 0.0, 0.0);
00848 glClearAccum(0.0, 0.0, 0.0, 0.0);
00849
00850 glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
00851 glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
00852 glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
00853 glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0);
00854 glTranslatef(-xo[0], -xo[1], -xo[2]-3*lz);
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873 void showVector
00874 (
00875 double *x,
00876 double *v
00877 )
00878 {
00879 if (vecval[length]*(fabs(v[0])+fabs(v[1])+fabs(v[2]))>1.e6)
00880 { fprintf
00881 ( stderr,
00882 "VALUE AT (%g,%g,%g) TOO LARGE (not displayed)\n",
00883 x[0],x[1],x[2]
00884 );
00885 return;
00886 }
00887 glBegin(GL_LINES);
00888 glVertex3f
00889 ( (GLfloat)x[0],
00890 (GLfloat)x[1],
00891 (GLfloat)x[2]
00892 );
00893 glVertex3f
00894 ( (GLfloat)(x[0]+vecval[length]*v[0]),
00895 (GLfloat)(x[1]+vecval[length]*v[1]),
00896 (GLfloat)(x[2]+vecval[length]*v[2])
00897 );
00898 glEnd();
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 void showParticle (
00953 double vmn,
00954 double vmx,
00955 double val,
00956 double *x
00957 ) {
00958 REAL r,g,b,
00959 vav=.5*(vmn+vmx),
00960 alow =PI/(2.*(vav-vmn)),
00961 ahigh=PI/(2.*(vmx-vav)),
00962 a;
00963 if (val<vmn)
00964 { r=g=0.0; b=1.0; }
00965 else
00966 if (val>vmx)
00967 { r=1.0; g=b=0.0; }
00968 else
00969 if (val<vav)
00970 { a=(REAL)(val-vmn)*alow;
00971 b=cos(a); g=sin(a);
00972 r=0.0;
00973 }
00974 else
00975 { a=(REAL)(val-vav)*ahigh;
00976 g=cos(a); r=sin(a);
00977 b=0.0;
00978 }
00979 glColor3f(r,g,b);
00980 glVertex3f((GLfloat)x[0],(GLfloat)x[1],(GLfloat)x[2]);
00981 }
00982 void showSphere (
00983 double vmn,
00984 double vmx,
00985 double val,
00986 double rad,
00987 double *x
00988 )
00989 {
00990 GLfloat mat[4],
00991 shine=0.6;
00992 REAL r,g,b,
00993 vav=.5*(vmn+vmx),
00994 alow =PI/(2.*(vav-vmn)),
00995 ahigh=PI/(2.*(vmx-vav)),
00996 a;
00997 if (val<vmn)
00998 { r=g=0.0; b=1.0; }
00999 else
01000 if (val>vmx)
01001 { r=1.0; g=b=0.0; }
01002 else
01003 if (val<vav)
01004 { a=(REAL)(val-vmn)*alow;
01005 b=cos(a); g=sin(a);
01006 if(g<0.0)g=0.0;
01007 if(b<0.0)b=0.0;
01008 r=0.0;
01009 }
01010 else
01011 { a=(REAL)(val-vav)*ahigh;
01012 g=cos(a); r=sin(a);
01013 if(g<0.0)g=0.0;
01014 if(r<0.0)r=0.0;
01015 b=0.0;
01016 }
01017
01018
01019 glPushMatrix();
01020
01021 mat[0]=r;mat[1]=g;mat[2]=b;mat[3]=1.0;
01022 glEnable(GL_LIGHTING);
01023 glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
01024 glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
01025 glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
01026 glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0);
01027 glTranslatef (x[0], x[1], x[2]);
01028 glutSolidSphere (rad, 15, 15);
01029
01030
01031 glPopMatrix();
01032 }
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181 void displayAxes() {
01182 GLfloat mat[4] = { 0.6, 0.8, 0.3, 1.0 },
01183 shine=0.6;
01184 mat[0]=.8;mat[1]=0.7;mat[2]=0.5;
01185 glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
01186 glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
01187 glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
01188 glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0);
01189 if (!showpar[showAxes]) return;
01190 glEnable(GL_LIGHTING);
01191 glLineWidth (axes[axeswidth]);
01192 glBegin (GL_LINES);
01193 glVertex3f(xo[0],xo[1],xo[2]);
01194 glVertex3f(xo[0]+axes[xaxislength]*lx,xo[1],xo[2]);
01195 glVertex3f(xo[0],xo[1],xo[2]);
01196 glVertex3f(xo[0],xo[1]+axes[yaxislength]*ly,xo[2]);
01197 glVertex3f(xo[0],xo[1],xo[2]);
01198 glVertex3f(xo[0],xo[1],xo[2]+axes[zaxislength]*lz);
01199 glEnd ();
01200
01201
01202 glPushMatrix();
01203
01204 glTranslatef (xo[0], xo[1], xo[2]+axes[zaxislength]*lz);
01205 glutSolidCone (axes[arrowidth]*lz, axes[arrowheight]*lz, 4, 4);
01206
01207
01208 glPopMatrix();
01209 }
01210
01211 void getScaling
01212 (
01213 double &l0,
01214 double &l1
01215 )
01216 {
01217 l0=lmin,l1=lmax;
01218 }
01219 void getXLimits
01220 ( double *x0,
01221 double *x1
01222 )
01223 {
01224 for (int i=0; i<3; i++)
01225 { x0[i]=xmin[i];
01226 x1[i]=xmax[i];
01227 }
01228 }
01229 void Exit()
01230 {
01231 char s[MAXLINLEN];
01232 if (animation) {
01233 animation=0;
01234 }
01235 printf("Exit (y/n)? ");fflush(stdout);
01236 fgets(s,MAXLINLEN,stdin);
01237 if (*s!='y') return;
01238
01239 exit(0);
01240 }
01241 void Quit()
01242 {
01243 char s[MAXLINLEN];
01244 if (animation) {
01245 animation=0;
01246 }
01247 printf("Quit (y/n)? ");fflush(stdout);
01248 fgets(s,MAXLINLEN,stdin);
01249 if (*s!='y') return;
01250
01251 exit(0);
01252 }
01253 void menu(int value) {
01254 printf("Menu %d: ",value);
01255 switch (value) {
01256 case 0:
01257 showpar[showBoundaryVertexes] = showpar[showBoundaryVertexes]==0?1:0;
01258 printf("Show Boundary Vertexes = %d\n",showpar[showBoundaryVertexes]);
01259 break;
01260 case 1:
01261 showpar[showBoundaryGrid] = showpar[showBoundaryGrid]==0?1:0;
01262 printf("Show Boundary Grid = %d\n",showpar[showBoundaryGrid]);
01263 break;
01264 case 2:
01265 showpar[showBoundaryFaceCenters] = showpar[showBoundaryFaceCenters]==0?1:0;
01266 printf("Show Boundary Faces = %d\n",showpar[showBoundaryFaceCenters]);
01267 break;
01268 case 3:
01269 showpar[showNodes] = showpar[showNodes]==0?1:0;
01270 printf("Show Grid Nodes = %d\n",showpar[showNodes]);
01271 break;
01272 case 4:
01273 showpar[showFaceCenters] = showpar[showFaceCenters]==0?1:0;
01274 printf("Show Face Centers = %d\n",showpar[showFaceCenters]);
01275 break;
01276 case 5:
01277 showpar[showCellCenters] = showpar[showCellCenters]==0?1:0;
01278 printf("Show Cell Centers = %d\n",showpar[showCellCenters]);
01279 break;
01280 case 6:
01281 showpar[showGrid] = showpar[showGrid]==0?1:0;
01282 printf("Show Grid = %d\n",showpar[showGrid]);
01283 break;
01284 case 7:
01285 printf("Option 7 Not implemented \n");
01286 break;
01287 case 8:
01288 showpar[showBonds] = showpar[showBonds]==0?1:0;
01289 printf("Show Bonds = %d\n",showpar[showBonds]);
01290 break;
01291 case 9:
01292 showpar[showVariables] = showpar[showVariables]==0?1:0;
01293 printf("Show Variables = %d\n",showpar[showVariables]);
01294 break;
01295 case 10:
01296 showpar[showAxes] = showpar[showAxes]==0?1:0;
01297 printf("Show Axes = %d\n",showpar[showAxes]);
01298 break;
01299 case 11:
01300 showpar[showBoundaryVectors] = showpar[showBoundaryVectors]==0?1:0;
01301 printf("Show Boundary Vectors = %d\n",showpar[showBoundaryVectors]);
01302 break;
01303 case 12:
01304
01305 break;
01306 case 13:
01307
01308 break;
01309 case 14:
01310 if (finished) break;
01311 animation=animation==0?1:0;
01312 if (animation)
01313 glutIdleFunc(animate);
01314 else
01315 { glutIdleFunc(NULL);
01316 printf("\n");fflush(stdout);
01317 }
01318 break;
01319 case 15:
01320 helpDisplay();
01321 break;
01322 case 16:
01323 printf(ABOUT);
01324 break;
01325 case 17:
01326 printf("\nSend your comments to andrei@smirnov.mae.wvu.edu\n");
01327
01328 exit(0);
01329 break;
01330 }
01331 fflush(stdout);
01332
01333 }
01334 void displayMenu()
01335 {
01336 printf("----------------- MENU -----------------\n");
01337 printf(" ACTION (key-shortcut)\n");
01338 printf(" 0. Quit menu (<Enter>)\n");
01339 printf("Toggle the display of \n");
01340 printf(" 1. Boundary vertexes \n");
01341 printf(" 2. Boundary grid (g)\n");
01342 printf(" 3. Boundary faces \n");
01343 printf(" 4. Nodes (n)\n");
01344 printf(" 5. Frame (f)\n");
01345
01346
01347
01348
01349 printf("10. Axes (a)\n");
01350 printf("11. Boundary Vectors (v)\n");
01351 printf("Actions:\n");
01352
01353
01354 printf("14. Initialize (r)\n");
01355 printf("15. Run/Stop (r)\n");
01356 printf("16. Help (?)\n");
01357 printf("17. About \n");
01358 printf("18. Quit program (q)\n");
01359 }
01360 void consoleMenu()
01361 { int selection=-1;
01362 do
01363 { char buf[MAXLINLEN];
01364 displayMenu();
01365 printf("Select: ");
01366 selection=0;
01367 fgets(buf,MAXLINLEN,stdin);
01368 sscanf(buf,"%d",&selection);
01369 if (selection==0) return;
01370 if (selection>0&&selection<=15)
01371 menu(selection-1);
01372 else printf("Wrong selection: %d\n",selection);
01373
01374 } while (selection!=0);
01375 }
01376 void setBackgroundRun()
01377 {
01378 showpar[showRun]=0;
01379 }
01380 void setForegroundRun()
01381 {
01382 showpar[showRun]=1;
01383 }
01384 void toggleSpheres() {
01385 showpar[showSpheres]=showpar[showSpheres]?0:1;
01386 printf("Show Spheres = %d\n",showpar[showSpheres]);
01387 }
01388 void switchColorScheme() {
01389 scene.color.scheme=(ColorSchemes)(((int)scene.color.scheme+1)%(int)maxColorSchemes);
01390 printf("Color Scheme = %d\n",(int)scene.color.scheme);
01391 }
01392 void runmany()
01393 { int n=0;
01394 printf("Enter number or iterations: ");fflush(stdout);
01395 scanf("%d",&n);
01396 printf("Executing %d iterations ...",n);fflush(stdout);
01397 domain->run(n);
01398 printf(" done\n");
01399 }
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448 void toggleWindowDump() {
01449 printf("Enter window dump time interval: ");fflush(stdout);
01450 scanf("%g",&wdtime);
01451 if(wdtime>0.0)
01452 { showpar[dumpWindow]=1;
01453 iwdump=0;nwdump=(int)(wdtime/Run::time.step+0.5);
01454 printf("Window dump = %d, dump time interval = %g\n",showpar[dumpWindow],wdtime);
01455 }
01456 else
01457 { showpar[dumpWindow]=0;
01458 printf("Window dump disabled\n",showpar[dumpWindow],wdtime);
01459 }
01460 }
01461 void dumpwindow()
01462 { using namespace IO;
01463 xwd(windowname);
01464 }
01465 void commandMode()
01466 {
01467 static struct Command
01468 {
01469 char *name;
01470 void (*f)();
01471 } command[] =
01472 {
01473
01474 {(char*)"m",consoleMenu},
01475
01476
01477
01478
01479 {(char*)"bg",setBackgroundRun},
01480 {(char*)"cs",switchColorScheme},
01481 {(char*)"fg",setForegroundRun},
01482 {(char*)"?",helpCommand},
01483 {(char*)"h",helpCommand},
01484 {(char*)"help",helpCommand},
01485 {(char*)"r",runmany},
01486 {(char*)"sp",toggleSpheres},
01487 {(char*)"wd",toggleWindowDump},
01488 {(char*)"dw",dumpwindow},
01489 {(char*)"e",Exit},
01490 {(char*)"q",Quit},
01491 {(char*)".",NULL},
01492 {(char*)"\0",NULL}
01493 }, *cmd;
01494 char buf[MAXLINLEN+1],*p,*s;
01495 printf("Command mode\n");
01496 while (1) {
01497 printf(":");fflush(stdout);
01498 #ifdef WITH_DOVE
01499 if(iproc==0)
01500 #endif
01501 { fgets(buf,MAXLINLEN,stdin);
01502 }
01503
01504
01505
01506
01507
01508 for (s=buf; isspace(*s); s++);
01509 if ((p=strchr(s,'\n'))!=NULL) *p='\0';
01510 for (cmd=command; *cmd->name!='\0'; cmd++)
01511 if (strcmp(s,cmd->name)==0) break;
01512 switch (*cmd->name)
01513 {
01514 case '\0':
01515 if (*s=='\0')
01516 { printf("Display-mode\n");fflush(stdout);
01517 return;
01518 }
01519 else
01520 printf("Unknown command\n");
01521 break;
01522 case '.':
01523 printf("\nDisplay-mode\n");fflush(stdout);
01524 return;
01525 default:
01526 (*cmd->f)();
01527 }
01528 }
01529 }
01530 void display() {
01531
01532 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01533 glPushMatrix();
01534
01535
01536 glTranslatef(0.0, 0.0, -zoom);
01537 glTranslatef(tx, ty, 0.0);
01538 glRotatef(rotx, 1.0, 0.0, 0.0);
01539 glRotatef(roty, 0.0, 1.0, 0.0);
01540
01541 displayAxes();
01542
01543 refresh();
01544 if (showpar[showGrid]) {
01545 cout << "showGrid disabled\n";
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583 }
01584 if (showpar[showBoundaryGrid]) {
01585 cout << "showBoundaryGrid disabled\n";
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694 }
01695 if(showpar[showFrame]) {
01696 REAL edgescolor[3];
01697 getElementColor(frame,edgescolor);
01698 glDisable(GL_LIGHTING);
01699 glLineWidth (scene.frame.line[thickness]);
01700 glColor3f(edgescolor[red], edgescolor[green], edgescolor[blue]);
01701 REAL v[2][2][2][3];
01702
01703 v[0][0][0][0]=xmin[0];
01704 v[0][0][0][1]=xmin[1];
01705 v[0][0][0][2]=xmin[2];
01706
01707 v[0][0][1][0]=xmin[0];
01708 v[0][0][1][1]=xmin[1];
01709 v[0][0][1][2]=xmax[2];
01710
01711 v[0][1][0][0]=xmin[0];
01712 v[0][1][0][1]=xmax[1];
01713 v[0][1][0][2]=xmin[2];
01714
01715 v[0][1][1][0]=xmin[0];
01716 v[0][1][1][1]=xmax[1];
01717 v[0][1][1][2]=xmax[2];
01718
01719 v[1][0][0][0]=xmax[0];
01720 v[1][0][0][1]=xmin[1];
01721 v[1][0][0][2]=xmin[2];
01722
01723 v[1][0][1][0]=xmax[0];
01724 v[1][0][1][1]=xmin[1];
01725 v[1][0][1][2]=xmax[2];
01726
01727 v[1][1][0][0]=xmax[0];
01728 v[1][1][0][1]=xmax[1];
01729 v[1][1][0][2]=xmin[2];
01730
01731 v[1][1][1][0]=xmax[0];
01732 v[1][1][1][1]=xmax[1];
01733 v[1][1][1][2]=xmax[2];
01734
01735 glBegin(GL_LINES);
01736 for(int i=0;i<2;i++)
01737 for(int j=0;j<2;j++) {
01738 glVertex3f((GLfloat)v[i][j][0][0],(GLfloat)v[i][j][0][1],(GLfloat)v[i][j][0][2]);
01739 glVertex3f((GLfloat)v[i][j][0][0],(GLfloat)v[i][j][0][1],(GLfloat)v[i][j][1][2]);
01740 glVertex3f((GLfloat)v[i][0][j][0],(GLfloat)v[i][0][j][1],(GLfloat)v[i][0][j][2]);
01741 glVertex3f((GLfloat)v[i][0][j][0],(GLfloat)v[i][1][j][1],(GLfloat)v[i][0][j][2]);
01742 glVertex3f((GLfloat)v[0][i][j][0],(GLfloat)v[0][i][j][1],(GLfloat)v[0][i][j][2]);
01743 glVertex3f((GLfloat)v[1][i][j][0],(GLfloat)v[0][i][j][1],(GLfloat)v[0][i][j][2]);
01744 }
01745 glEnd();
01746 }
01747 if(showpar[showNodes]) {
01748 REAL ncolor[3],bcolor[3];
01749 int showboundarynodes=showpar[showBoundaryVertexes];
01750 getElementColor(faces,bcolor);
01751 if(scene.color.scheme==colorByTime)Palette::init(Run::time.start,Run::time.end);
01752 if(scene.color.scheme==colorByType)Palette::init(scene.color.minvalue,scene.color.maxvalue);
01753 if(scene.color.scheme==colorByMass)Palette::init(scene.color.minvalue,scene.color.maxvalue);
01754 getElementColor(nodes,ncolor);
01755 if(showpar[showSpheres]) {
01756 if(Run::option.debug)printf("Show Nodes as Spheres\n");
01757 GLfloat radius=scene.mesh.node[size];
01758 if(radius<=0.0)radius=0.5*Potential::lengthscale();
01759 GLfloat mat[4],
01760 shine=0.6;
01761 mat[3]=1.0;
01762 glEnable(GL_LIGHTING);
01763 glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0);
01764 if (domain->Molecules()->number()>0) {
01765
01766 Collection<Molecule> *nodes=domain->Molecules();
01767 nodes->goFirst();
01768 do {
01769 Molecule *node=nodes->Current();
01770 REAL
01771 size=species[node->Type()].Size(),
01772 *x=node->Coordinates();
01773 if(size>0.0) radius=0.5*size;
01774 glTranslatef ((GLfloat)x[0], (GLfloat)x[1], (GLfloat)x[2]);
01775 switch(scene.color.scheme) {
01776 case colorByBoundary:
01777
01778
01779
01780 mat[0]=ncolor[red];mat[1]=ncolor[green];mat[2]=ncolor[blue];
01781
01782 break;
01783 case colorByType:
01784 Palette::pickcolor((REAL)node->Type(),ncolor);
01785 mat[0]=ncolor[red];mat[1]=ncolor[green];mat[2]=ncolor[blue];
01786 break;
01787 case colorByTime:
01788 Palette::pickcolor(Run::time.current,ncolor);
01789 mat[0]=ncolor[red];mat[1]=ncolor[green];mat[2]=ncolor[blue];
01790 break;
01791 case colorByMass:
01792 Palette::pickcolor(species[node->Type()].Mass(),ncolor);
01793 mat[0]=ncolor[red];mat[1]=ncolor[green];mat[2]=ncolor[blue];
01794 break;
01795 default:
01796 mat[0]=ncolor[red];mat[1]=ncolor[green];mat[2]=ncolor[blue];
01797 break;
01798 }
01799 mat[3]=(x[3]-xmin[3])/(xmax[3]-xmin[3]);
01800 glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
01801 glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
01802 glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
01803 glutSolidSphere (radius, 12, 12);
01804 glTranslatef (-(GLfloat)x[0],-(GLfloat)x[1],-(GLfloat)x[2]);
01805 nodes->goNext();
01806 } while(!nodes->isFirst());
01807 }
01808 } else {
01809 if(Run::option.debug)printf("Show Nodes as Points\n");
01810 glPointSize(scene.mesh.node[size]);
01811 glDisable(GL_LIGHTING);
01812 glBegin(GL_POINTS);
01813 if (domain->Molecules()->number()>0) {
01814
01815 Collection<Molecule> *nodes=domain->Molecules();
01816 nodes->goFirst();
01817 do {
01818 Molecule *node=nodes->Current();
01819 REAL *x=node->Coordinates();
01820 switch(scene.color.scheme) {
01821 case colorByBoundary:
01822
01823
01824
01825
01826 break;
01827 case colorByTime:
01828 Palette::pickcolor(Run::time.current,ncolor);
01829 break;
01830 case colorByType:
01831 Palette::pickcolor((REAL)node->Type(),ncolor);
01832 break;
01833 case colorByMass:
01834 Palette::pickcolor(species[node->Type()].Mass(),ncolor);
01835 break;
01836 }
01837 glColor3f(ncolor[red], ncolor[green], ncolor[blue]);
01838 glVertex3f((GLfloat)x[0],(GLfloat)x[1],(GLfloat)x[2]);
01839 nodes->goNext();
01840 } while(!nodes->isFirst());
01841 }
01842 glEnd();
01843 glEnable(GL_LIGHTING);
01844 }
01845 }
01846 glPopMatrix();
01847
01848
01849 glXSwapBuffers(dpy, win);
01850 }
01851 void animate() {
01852 if (domain->run(1)==0) {
01853
01854 finished=1;
01855 animation=0;
01857 display();
01858 return;
01859 }
01860 if(!Run::option.xterm)printf("\rTime = %g%c[K",Run::time.current,ESC);fflush(stdout);
01861 if (showpar[showRun])
01862 {
01863 display();
01864 }
01865 if (showpar[dumpWindow])
01866 {
01867 if (iwdump++%nwdump==0)
01868 dumpwindow();
01869 }
01870 }
01871 void helpCommand() {
01872 printf("e - save and exit\n");
01873 printf("h - show help\n");
01874 printf("bg - set background run (no automatic redisplay)\n");
01875 printf("dw - dump window\n");
01876 printf("fg - set foreground run (automatic redisplay)\n");
01877 printf("lim - display domain limits\n");
01878 printf("m - select from a menu\n");
01879 printf("gvec - display grid vector limits\n");
01880 printf("gv - display grid variables limits\n");
01881 printf("pv - display pore variables limits\n");
01882 printf("q - quit without saving\n");
01883 printf("r - run\n");
01884 printf("u - uniform\n");
01885 printf("var - select a variable\n");
01886 printf("w - write data at this time step into %s-<number>.dat.gz\n",Run::outputname);
01887 printf("wd - toggle window dump\n");
01888 printf(". - quit command mode\n");
01889 }
01890 void reshape(int w, int h)
01891 {
01892 double
01893 lmin,lmax;
01894 glViewport(0, 0, w, h);
01895 glMatrixMode(GL_PROJECTION);
01896 glLoadIdentity();
01897 getScaling(lmin,lmax);
01898 gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 0.1*lmin, 10*lmax);
01899 glMatrixMode(GL_MODELVIEW);
01900 glLoadIdentity();
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926 }
01927 void mouse(int button, int state, int x, int y)
01928 {
01929 lastx = x;
01930 lasty = y;
01931
01932 mouseButtons[0] = 0;
01933 mouseButtons[1] = 0;
01934 mouseButtons[2] = 0;
01935
01936 switch(button)
01937 {
01938 case LEFT_BUTTON:
01939 {
01940 mouseButtons[0] = 1;
01941 }break;
01942
01943 case MIDDLE_BUTTON:
01944 {
01945 mouseButtons[1] = 1;
01946 }break;
01947
01948 case RIGHT_BUTTON:
01949 {
01950 mouseButtons[2] = 1;
01951 }break;
01952 }
01953 }
01954 void motion(int x, int y) {
01955
01956 REAL diffx = x - lastx;
01957 REAL diffy = y - lasty;
01958
01959 lastx = x;
01960 lasty = y;
01961
01962 if(mouseButtons[0])
01963 {
01964 rotx += 0.09f * diffy;
01965 roty += 0.09f * diffx;
01966 }
01967 else if(mouseButtons[1])
01968 {
01969 zoom += 0.05f * diffy;
01970 }
01971 else if(mouseButtons[2])
01972 {
01973 tx += 0.05f * diffx;
01974 ty -= 0.05f * diffy;
01975 }
01976 }
01977
01978 void keyboard(unsigned int key) {
01979 using namespace IO;
01980 if (Run::option.debug) printf("key=%c (%d)\n",(char)key,key);
01981 if (key<32||key>127)return;
01982 switch (key)
01983 {
01984 case '+':
01985 if (finished) break;
01986 if (domain->run(1)==0) finished=1;
01987 printf("Time: %-10.3g\n",Run::time.current);fflush(stdout);
01988 break;
01989 case '-':
01990 if (finished) break;
01991 if (domain->run(-1)==0) finished=1;
01992 printf("Time: %-10.3g\n",Run::time.current);fflush(stdout);
01993 break;
01994 case 'A':
01995 case 'a':
01996 showpar[showAxes] = showpar[showAxes]==0?1:0;
01997 printf("Show Axes = %d\n",showpar[showAxes]);
01998 break;
01999 case 'B':
02000 showpar[showBoundaryFaces] = showpar[showBoundaryFaces]==0?1:0;
02001 printf("Show Boundary Faces = %d\n",showpar[showBoundaryFaces]);
02002 break;
02003 case 'c':
02004 case 'C':
02005 switchColorScheme();
02006 break;
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016 case 'G':
02017 showpar[showGrid] = showpar[showGrid]==0?1:0;
02018 printf("Show Grid = %d\n",showpar[showGrid]);
02019 break;
02020 case 'g':
02021 showpar[showBoundaryGrid] = showpar[showBoundaryGrid]==0?1:0;
02022 printf("Show Boundary Grid = %d\n",showpar[showBoundaryGrid]);
02023 break;
02024 case 'f':
02025 showpar[showFrame] = showpar[showFrame]==0?1:0;
02026 printf("Show Frame = %d\n",showpar[showFrame]);
02027 break;
02028 case 'I':
02029 case 'i':
02030
02031 break;
02032 case 'M':
02033 case 'm':
02034 consoleMenu();
02035 break;
02036 case 'N':
02037 showpar[showNodes] = showpar[showNodes]==0?1:0;
02038 printf("Show Grid Nodes = %d\n",showpar[showNodes]);
02039
02040 break;
02041 case 'n':
02042 showpar[showBoundaryVertexes] = showpar[showBoundaryVertexes]==0?1:0;
02043 printf("Show Boundary Vertexes = %d\n",showpar[showBoundaryVertexes]);
02044 break;
02045 case 'l':
02046 case 'L':
02047 readconf();
02048 break;
02049 case 'v':
02050 showpar[showBoundaryVectors] = showpar[showBoundaryVectors]==0?1:0;
02051 printf("Show Boundary Vectors = %d\n",showpar[showBoundaryVectors]);
02052 break;
02053 case 'R':
02054 case 'r':
02055 if (finished) break;
02056 animation=animation==0?1:0;
02057 if (Run::option.verbose|Run::option.debug)
02058 printf("animation=%d\n",animation);
02059 if(Run::option.xterm)printf("%c[2J",ESC);
02060 break;
02061 case 'S':
02062 finished=0;
02063 case 's':
02064 if (finished) break;
02065 if(Run::option.xterm)printf("%c[2J",ESC);
02066 if (domain->run(1)==0) {
02067
02068 finished=1;
02069 }
02071 printf("Time: %-9.3g\n",Run::time.current);fflush(stdout);
02072 break;
02073
02074
02075
02076
02077
02078
02079
02080
02081 case 'w':
02082
02083 { static int idump=0;
02084 char filename[MAXLINLEN];
02085 sprintf(filename,"%s_dump%d",Run::outputname,idump++);
02086 domain->save(filename);
02087 }
02088 break;
02089 case 'z':
02090 zoom -= 1.5;
02091 break;
02092 case 'Z':
02093 zoom += 1.5;
02094 break;
02095 case ':':
02096 case '.':
02097 commandMode();
02098 break;
02099 case 27:
02100 Exit();
02101 break;
02102 case '?':
02103 helpDisplay();
02104 break;
02105 }
02106 }
02107 static int
02108 events_loop(Display *dpy, Window win)
02109 { XEvent event;
02110 do
02111 { char buf[31];
02112 KeySym keysym;
02113 XNextEvent(dpy, &event);
02114 switch(event.type)
02115 { case Expose:
02116 break;
02117 case ConfigureNotify:
02118 reshape(event.xconfigure.width, event.xconfigure.height);
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136 break;
02137 case KeyPress:
02138 (void) XLookupString(&event.xkey, buf, sizeof(buf), &keysym, NULL);
02139 keyboard((unsigned char)keysym);
02140 break;
02141 case ButtonPress:
02142 mouse(event.xbutton.button,GLUT_DOWN,event.xbutton.x,event.xbutton.y);
02143 break;
02144 case MotionNotify:
02145 motion(event.xbutton.x, event.xbutton.y);
02146 break;
02147 default:
02148 break;
02149 }
02150 if (animation)
02151 do
02152 { animate();
02153
02154 } while(!XPending(dpy));
02155 } while (XPending(dpy));
02156 display();
02157 return 0;
02158 }
02159 void run() {
02160 while (events_loop(dpy, win)==0);
02161 }
02162 void displaymessage(char *msg)
02163 {
02164 puts(msg);
02165 }
02166 void setElementColor(int element_type, REAL rgbcolor[])
02167 {
02168 if (element_type<maxelements)
02169 for (int irgb=0; irgb<3; irgb++)
02170 disp[element_type].rgbcolor[irgb]=rgbcolor[irgb];
02171 }
02172 void getElementColor(int element_type, REAL rgbcolor[])
02173 {
02174 if (element_type<maxelements)
02175 for (int irgb=0; irgb<3; irgb++)
02176 rgbcolor[irgb]=disp[element_type].rgbcolor[irgb];
02177 else {
02178 fprintf(stderr,"getElementColor: no color for element type %d\n",element_type);
02179 fflush(stderr);
02180 }
02181 }
02182 }
02183 namespace Palette {
02184 REAL
02185 vmn,
02186 vmx,
02187 vav,
02188 dvi;
02189 void init(REAL vmin, REAL vmax) {
02190 vmn=vmin;
02191 vmx=vmax;
02192 vav=.5*(vmn+vmx);
02193 dvi=2.0/(vmx-vmn);
02194
02195
02196 }
02197 void pickcolor(REAL var, REAL color[]) {
02198 double r,g,b;
02199
02200 if (var<=vmn)
02201 { r=g=0.0; b=1.0; }
02202 else
02203 if (var>=vmx)
02204 { r=1.0; g=b=0.0; }
02205 if (var<vav) {
02206
02207
02208 g=(var-vmn)*dvi;
02209 b=1.0-g;
02210 r=0.0;
02211 } else {
02212
02213
02214 r=(var-vav)*dvi;
02215 g=1.0-r;
02216 b=0.0;
02217 }
02218 color[0]=(REAL)r;
02219 color[1]=(REAL)g;
02220 color[2]=(REAL)b;
02221 }
02222 }
02223