12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400 |
- /****************************************************************************
- *
- * MODULE: r3.showdspf
- * AUTHOR(S): Bill Brown, CERL
- * ported from IrisGL to OpenGL by Ken Sakai, Steve Hall,
- * Lockheed Martin Space Systems,
- * Sunnyale, California, Modification date: March 2000
- * PURPOSE: Visualization program which loads the isosurfaces previously calculated
- * using r3.mkdspf
- * COPYRIGHT: (C) 2000 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
- *
- *****************************************************************************/
- #include <stdlib.h>
- #include <grass/raster3d.h>
- #include <grass/config.h>
- #define TOGGLE(x) ((x) = (x) ? 0 : 1)
- #include <Xm/Xm.h>
- #include <Xm/Form.h>
- #ifdef HAVE_GL_GLWMDRAWA_H
- #include <GL/GLwMDrawA.h>
- #else
- #ifdef HAVE_X11_GLW_GLWMDRAWA_H
- #include <X11/GLw/GLwMDrawA.h>
- #endif
- #endif
- #include "vizual.h"
- #include "kns_defines.h"
- #include "kns_globals.h"
- #include <math.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <ctype.h>
- #ifdef __MINGW32__
- #include <process.h>
- #else
- #include <sys/wait.h>
- #endif
- #ifndef WAIT_ANY
- #define WAIT_ANY ((pid_t) -1)
- #endif
- GLuint Material_1_Dlist;
- OGLMotifWindowData MainOGLWindow;
- OGLMotifWindowData ColormapWindow;
- GLuint MainDlist;
- XtAppContext App_context;
- file_info Headfax; /* contains info about data itself */
- file_info G3header; /* contains info about data itself */
- int G_sign;
- int X_sign;
- long D_offset; /*offset to data in grid3 file */
- void set_threshold_button(int i);
- char *check_get_any_dspname();
- void do__bbox(struct dspec *D_spec);
- void init_dspec(struct dspec *D_spec, char *ctable);
- void options();
- void Toggle_swapbuffers(struct dspec *D_spec);
- void clear_screen();
- void check_limits(struct dspec *D_spec, int axis);
- void copy_head(file_info * g3head, file_info * head);
- char *rindex();
- static char ctablefile[256];
- static struct dspec D_spec;
- static struct Cap D_Cap;
- static void do_draw();
- static void do__draw();
- static void do__draw_solid();
- void init_bounds(struct dspec *D_spec);
- void get_trackball_rotation_matrix(float mat[4][4]);
- void set_trackball_rotations(struct dspec *D_spec);
- void setSingleSelectionMode();
- void setMultipleSelectionMode();
- int isSingleSelectionMode();
- void do_draw_multiple_thresholds(file_info * Headp, file_info * G3p,
- struct dspec *D_spec, struct Cap *Cap,
- unsigned int type);
- int dumpgif(char *name);
- void do_draw_with_display_list(struct dspec *D_spec);
- #define DEBUG 1
- int main(int argc, char **argv)
- {
- char buff[300], wname[200];
- long Window[3];
- char *dsp;
- XEvent event;
- int i, fdes[2];
- void *g3map;
- RASTER3D_Region g3reg;
- char *p, *mapset;
- double dmin, dmax;
- fd_set set;
- struct timeval timeout;
- pid_t pid;
- struct Option *g3, *dspf, *colr;
- G_gisinit(argv[0]);
- g3 = G_define_option();
- g3->key = "grid3";
- g3->type = TYPE_STRING;
- g3->required = YES;
- g3->gisprompt = "old,grid3,3d-raster";
- g3->description = "Name of an existing 3D raster map";
- dspf = G_define_option();
- dspf->key = "dspf";
- dspf->type = TYPE_STRING;
- dspf->required = YES;
- dspf->description = "Name of existing display file";
- colr = G_define_option();
- colr->key = "color";
- colr->type = TYPE_STRING;
- colr->required = NO;
- colr->description = "Name of existing color table";
- if (G_parser(argc, argv))
- exit(EXIT_FAILURE);
- /* set-up for select() */
- if (pipe(fdes))
- G_fatal_error("Unable to open pipe");
- pid = fork();
- if (pid == (pid_t) 0) { /* child */
- close(fdes[1]);
- /* use this to name graphics window */
- strcpy(wname, g3->answer);
- if (NULL == (dsp =
- check_get_any_dspname(dspf->answer, g3->answer, NULL)))
- exit(EXIT_FAILURE);
- /* TODO - check color file */
- /* changed 7/93; normals were pointing to interior as default */
- G_sign = 1;
- X_sign = -1;
- /* opens grid3 file to read in original data
- */
- Rast3d_set_error_fun(Rast3d_print_error);
- /* open g3 file for reading */
- if (NULL == (mapset = G_find_file2("grid3", g3->answer, ""))) {
- sprintf(buff, "Unable to find 3D raster map for <%s>", g3->answer);
- G_fatal_error(buff);
- }
- g3map = Rast3d_open_cell_old(g3->answer, mapset, RASTER3D_DEFAULT_WINDOW,
- RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT);
- if (NULL == g3map) {
- sprintf(buff, "Unable to open 3D raster map <%s>", g3->answer);
- G_fatal_error(buff);
- }
- if (0 == Rast3d_range_load(g3map)) {
- sprintf(buff, "Unable to read range of 3D raster map <%s>", g3->answer);
- G_fatal_error(buff);
- }
- Rast3d_range_min_max(g3map, &dmin, &dmax);
- Rast3d_get_region_struct_map(g3map, &g3reg);
- viz_make_header(&G3header, dmin, dmax, &g3reg);
- init_caps(&D_Cap, &g3reg);
- /* open display file for reading */
- /* changes 9/2000: Bev Wallace <beverly.t.wallace@lmco.com> */
- /* sprintf(buff,"grid3/%s/dsp", g3->answer);
- * if(NULL == (mapset = G_find_file2 (buff, dsp, ""))){
- */
- /* Remove the mapset within buff, add to G_find_file2 - Bev Wallace */
- i = strcspn(wname, "@");
- if (i > 0)
- wname[i] = (char)NULL;
- sprintf(buff, "grid3/%s/dsp", wname);
- if (NULL == (mapset = G_find_file2(buff, dsp, mapset))) {
- sprintf(buff, "Unable to find display file for <%s>", dsp);
- G_fatal_error(buff);
- }
- if ((Headfax.dspfinfp = G_fopen_old(buff, dsp, mapset)) == NULL) {
- fprintf(stderr, "Unable to open <%s> for reading\n",
- Headfax.dspfinfp);
- exit(EXIT_FAILURE);
- }
- /* read header info from dspf file into GLOBAL variable Headfax */
- if (dfread_header(&Headfax) < 0) {
- fprintf(stderr, "Unable to read display file header\n");
- exit(EXIT_FAILURE);
- }
- /* set 3dmap for data in Headfax */
- Headfax.g3mapin = g3map;
- /* currently seems rather redundant, but may have future use to
- keep them seperate. */
- copy_head(&G3header, &Headfax);
- /* INIT */
- init_dspec(&D_spec, colr->answer);
- /* INITIALIZATION OF THE D_spec.B or D_spec.E CAN HAPPEN MORE THAN ONCE */
- init_bounds(&D_spec);
- D_spec.Swap_buf = 1;
- init_graphics(wname, argc, argv, &D_spec);
- draw_colortable(&D_spec, &Headfax, Window);
- winset_main();
- D_spec.c_flag = 1; /* reset flag */
- Toggle_swapbuffers(&D_spec); /* make sure they sync up */
- Toggle_swapbuffers(&D_spec);
- for (;;) {
- int nbytes, fdstatus;
- timeout.tv_sec = 0;
- timeout.tv_usec = 10000;
- FD_ZERO(&set);
- FD_SET(fdes[0], &set);
- if ((fdstatus =
- select(FD_SETSIZE, &set, NULL, NULL, &timeout)) == 1) {
- if (FD_ISSET(fdes[0], &set) &&
- (nbytes = read(fdes[0], buff, 299)) > 0) {
- p = buff;
- p[nbytes] = '\0';
- dispatch_cmd(p);
- }
- }
- else if (fdstatus == -1) {
- G_fatal_error("File Descriptor error");
- }
- while (XtAppPending(App_context)) {
- XtAppNextEvent(App_context, &event);
- XtDispatchEvent(&event);
- }
- }
- }
- else if (pid < (pid_t) 0) {
- G_fatal_error("Fork failed!");
- }
- else { /* parent */
- close(fdes[0]);
- options();
- /* get input from the keyboard */
- fprintf(stderr, "enter desired manipulations then press return\n\n");
- fprintf(stderr, "Q ? + - r d l L (xyz)# (XYZ)# S B(xyz)# "
- "E(xyz)# R g C c w W i h t T# \n");
- fprintf(stderr, " > ");
- fflush(stderr);
- for (;;) {
- int linelen;
- if (waitpid(WAIT_ANY, NULL, WNOHANG) != 0)
- break; /* Child exited */
- if (NULL == fgets(buff, 300, stdin))
- break;
- linelen = strlen(buff);
- if (write(fdes[1], &buff, linelen) != linelen)
- G_fatal_error("Unable to write to child process.");
- if (waitpid(WAIT_ANY, NULL, WNOHANG) != 0)
- break; /* Child exited */
- /* get input from the keyboard */
- fprintf(stderr,
- "enter desired manipulations then press return\n\n");
- fprintf(stderr,
- "Q ? + - r d l L (xyz)# (XYZ)# S B(xyz)# "
- "E(xyz)# R g C c w W i h t T# \n");
- fprintf(stderr, " > ");
- fflush(stderr);
- }
- fprintf(stderr, "Goodbye!\n\n");
- }
- return 0;
- }
- int dispatch_cmd(char *p)
- {
- int tmp, tmp2, drawable_cmd;
- char cmd, axis;
- static int dobox = DRAW_BBOX;
- char cfilename[128], ctablename[128];
- int j;
- int tmp4;
- drawable_cmd = 0;
- while (*p) { /* assign valid keyboard entries to D_spec structure */
- cmd = *p++;
- switch (cmd) {
- case '#': /* rest of line is a comment */
- *p = 0; /* throw away rest of line */
- break;
- case 'n':
- G_sign = -G_sign;
- X_sign = -X_sign;
- break;
- case 'b':
- dobox = dobox ? 0 : DRAW_BBOX;
- break;
- case '+':
- if (!isSingleSelectionMode())
- setSingleSelectionMode();
- D_spec.Thresh++;
- if (D_spec.Thresh > Headfax.linefax.nthres - 1)
- D_spec.Thresh = 0;
- set_threshold_button(D_spec.Thresh + 1);
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | dobox);
- drawable_cmd = 1;
- break;
- case '-':
- D_spec.Thresh--;
- if (!isSingleSelectionMode())
- setSingleSelectionMode();
- if (D_spec.Thresh < 0)
- D_spec.Thresh = Headfax.linefax.nthres - 1;
- set_threshold_button(D_spec.Thresh + 1);
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | dobox);
- drawable_cmd = 1;
- break;
- case '?':
- {
- int i;
- for (i = 0; i < Headfax.linefax.nthres; i++)
- fprintf(stderr, "%c %3d for threshold value %5.2f\n",
- i == D_spec.Thresh ? '*' : ' ', i + 1,
- Headfax.linefax.tvalue[i]);
- fprintf(stderr, "Rotations: X %d Y %d Z %d\n", D_spec.xrot,
- D_spec.yrot, D_spec.zrot);
- }
- break;
- case 'l': /* list thresholds */
- D_spec.nt = 0;
- G_squeeze(p);
- while (isdigit(*p)) {
- int i;
- i = atoi(p);
- if (i < 1 || i > Headfax.linefax.nthres)
- fprintf(stderr,
- "Range is 1 to %d\n", Headfax.linefax.nthres);
- else {
- D_spec.t[D_spec.nt] = i - 1;
- D_spec.nt++;
- }
- p++;
- if (i >= 10)
- p++;
- if (i >= 100)
- p++;
- G_squeeze(p);
- }
- *p = 0; /* throw away rest of line */
- break;
- case 'L': /*display list */
- if (!D_spec.nt)
- break;
- if (D_spec.c_flag)
- clear_screen();
- tmp = D_spec.c_flag;
- D_spec.c_flag = 0;
- tmp2 = D_spec.Thresh;
- D_spec.Swap_buf = 0;
- if (isSingleSelectionMode())
- setMultipleSelectionMode();
- if (D_spec.nt) {
- for (j = 0; j < Headfax.linefax.nthres; j++) {
- unset_threshold_button(j + 1);
- }
- for (j = 0; j < D_spec.nt; j++) {
- set_threshold_button(D_spec.t[j] + 1);
- }
- }
- do_draw_multiple_thresholds(&Headfax, &G3header, &D_spec, &D_Cap,
- DRAW_ISO | dobox);
- new_swapbuffers();
- D_spec.Swap_buf = 1;
- D_spec.c_flag = tmp;
- D_spec.Thresh = tmp2;
- drawable_cmd = 1;
- break;
- case 't': /* show only this threshold */
- G_squeeze(p);
- if (isdigit(*p)) {
- int i;
- i = atoi(p);
- if (i < 1 || i > Headfax.linefax.nthres)
- fprintf(stderr, "Range is 1 to %d\n",
- Headfax.linefax.nthres);
- D_spec.Thresh = i - 1;
- if (!isSingleSelectionMode())
- setSingleSelectionMode();
- set_threshold_button(D_spec.Thresh + 1);
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap,
- DRAW_ISO | dobox);
- drawable_cmd = 1;
- *p = 0; /* throw away rest of line */
- }
- else
- fprintf(stderr, "check keyboard entry instructions \n"), *p =
- 0;
- break;
- case 'T': /* show thresholds between hi & lo */
- G_squeeze(p);
- if (2 != sscanf(p, "%d %d", &(D_spec.low), &(D_spec.hi))) {
- /*DEBUG*/
- fprintf(stderr, ":><>>> T %d %d\n", (D_spec.low),
- (D_spec.hi));
- fprintf(stderr, "check keyboard entry instructions \n");
- *p = 0;
- D_spec.low = 0;
- D_spec.hi = Headfax.linefax.nthres - 1;
- }
- else {
- D_spec.low--; /* convert from user to internal #s */
- D_spec.hi--;
- }
- drawable_cmd = 1;
- *p = 0; /* throw away rest of line */
- break;
- case 'B': /* initial value along specified axis */
- case 'E': /* ending value along specified axis */
- G_squeeze(p);
- axis = *p++;
- G_squeeze(p);
- if (isdigit(*p)) {
- G_squeeze(p);
- tmp = atoi(p);
- *p = 0; /*throw away rest of line */
- }
- else {
- fprintf(stderr, "enter number also\n");
- break;
- }
- switch (axis) {
- case 'x':
- if (cmd == 'B')
- D_spec.B[X] = tmp;
- else
- D_spec.E[X] = tmp;
- tmp = X;
- break;
- case 'y':
- if (cmd == 'B')
- D_spec.B[Y] = tmp;
- else
- D_spec.E[Y] = tmp;
- tmp = Y;
- break;
- case 'z':
- if (cmd == 'B')
- D_spec.B[Z] = tmp;
- else
- D_spec.E[Z] = tmp;
- tmp = Z;
- break;
- }
- check_limits(&D_spec, tmp);
- break;
- case 'R':
- init_bounds(&D_spec);
- break;
- case 'S': /* Specular highlight */
- G_squeeze(p);
- if (isdigit(*p)) {
- D_spec.Specular = (float)atof(p);
- *p = 0;
- change_spec(D_spec.Specular);
- }
- else
- fprintf(stderr, "check keyboard entry instructions \n"), *p =
- 0;
- break;
- case 'r':
- fprintf(stderr, " - Rotation Mode -\n"
- " 1) Drag with LEFT mouse button to rotate\n"
- " 2) Drag right/left with MIDDLE mouse button to zoom in/out\n"
- " 3) Click RIGHT mouse button to exit Rotation Mode\n\n");
- tmp4 = D_spec.c_flag;
- D_spec.c_flag = 1;
- rotate_model(&D_spec);
- clear_screen();
- D_spec.c_flag = tmp4;
- break;
- case 's': /* use swapbuffers */
- /*
- Toggle_swapbuffers (&D_spec);
- */
- break;
- case 'd': /* draw it */
- G_squeeze(p);
- if (isdigit(*p)) {
- int i;
- i = atoi(p);
- if (i == 1)
- D_spec.Thresh = D_spec.low;
- else
- D_spec.Thresh = D_spec.hi;
- }
- if (!isSingleSelectionMode())
- setSingleSelectionMode();
- set_threshold_button(D_spec.Thresh + 1);
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | dobox);
- drawable_cmd = 1;
- *p = 0;
- break;
- case 'u': /* Update the screen in double buffer mode */
- new_swapbuffers();
- break;
- case 'D': /* draw solid */
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_SOLID | dobox);
- drawable_cmd = 1;
- break;
- case 'x': /* rotate around x-axis */
- G_squeeze(p);
- if (isdigit(*p) || *p == '-' || *p == '+') {
- D_spec.xrot = atoi(p);
- fprintf(stderr, "(RotX, RotY, RotZ) = (%d, %d, %d)\n\n",
- D_spec.xrot, D_spec.yrot, D_spec.zrot);
- set_trackball_rotations(&D_spec);
- do_draw_with_display_list(&D_spec);
- *p = 0;
- }
- else
- fprintf(stderr, "check keyboard entry instructions \n"), *p =
- 0;
- break;
- case 'X': /* scale in x-direction */
- G_squeeze(p);
- if (isdigit(*p) || *p == '-' || *p == '+') {
- D_spec.xscale = atof(p);
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap, dobox);
- *p = 0;
- }
- else
- fprintf(stderr, "check keyboard entry instructions \n"), *p =
- 0;
- break;
- case 'y': /* rotate around y-axis */
- G_squeeze(p);
- if (isdigit(*p) || *p == '-' || *p == '+') {
- D_spec.yrot = atoi(p);
- fprintf(stderr, "(RotX, RotY, RotZ) = (%d, %d, %d)\n\n",
- D_spec.xrot, D_spec.yrot, D_spec.zrot);
- set_trackball_rotations(&D_spec);
- do_draw_with_display_list(&D_spec);
- *p = 0;
- }
- else
- fprintf(stderr, "check keyboard entry instructions \n"), *p =
- 0;
- break;
- case 'Y': /* scale in y direction */
- G_squeeze(p);
- if (isdigit(*p) || *p == '-' || *p == '+') {
- D_spec.yscale = atof(p);
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap, dobox);
- *p = 0;
- }
- else
- fprintf(stderr, "check keyboard entry instructions \n"), *p =
- 0;
- break;
- case 'z': /* rotate around z-axis */
- G_squeeze(p);
- if (isdigit(*p) || *p == '-' || *p == '+') {
- D_spec.zrot = atoi(p);
- fprintf(stderr, "(RotX, RotY, RotZ) = (%d, %d, %d)\n\n",
- D_spec.xrot, D_spec.yrot, D_spec.zrot);
- set_trackball_rotations(&D_spec);
- do_draw_with_display_list(&D_spec);
- *p = 0;
- }
- else
- fprintf(stderr, "check keyboard entry instructions \n"), *p =
- 0;
- break;
- case 'Z': /* scale in z direction */
- G_squeeze(p);
- if (isdigit(*p) || *p == '-' || *p == '+') {
- D_spec.zscale = atof(p);
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap, dobox);
- *p = 0;
- }
- else
- fprintf(stderr, "check keyboard entry instructions \n"), *p =
- 0;
- break;
- case 'g': /* toggle grid */
- TOGGLE(D_spec.grid);
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | dobox);
- break;
- case 'C': /* toggle clear flag */
- TOGGLE(D_spec.c_flag);
- break;
- case 'c': /* redraw the screen */
- clear_screen();
- new_swapbuffers();
- break;
- case 'w': /* dump image to file */
- dumpgif(G_squeeze(++p));
- *p = 0;
- break;
- case 'W': /* TEST dump image to file */
- dumprect(G_squeeze(++p));
- *p = 0;
- break;
- /* TEST READ image from file */
- case 'i':
- loadrect(G_squeeze(++p));
- *p = 0;
- break;
- case 'Q': /* QUIT */
- if (D_spec.cfile != NULL)
- fclose(D_spec.cfile);
- exit(0);
- break;
- case 'h': /* help */
- options();
- break;
- case 'p': /* display a single plane 1-6 */
- #ifdef NEVER
- /* This code cores so I am taking it out. Ken Sakai */
- G_squeeze(p);
- if (isdigit(*p)) {
- D_spec.plane = atoi(p) - 1;
- if (D_spec.plane >= 0 && D_spec.plane <= 5) {
- /* call plane drawing code */
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap,
- DRAW_CAP | ((1 << D_spec.plane) << 16));
- drawable_cmd = 1;
- }
- else
- fprintf(stderr, "must be number between 1-6\n");
- }
- else {
- /* call code to draw all planes */
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap,
- DRAW_CAP | (0x3f << 16));
- drawable_cmd = 1;
- }
- *p = 0;
- #endif
- break;
- case 'I': /* toggle in_out flag */
- TOGGLE(D_spec.in_out);
- break;
- case 'F': /* new color File */
- G_squeeze(p);
- if (2 != sscanf(p, "%s %s", cfilename, ctablename))
- no_color_file(&D_spec, ctablefile);
- else {
- if (0 > new_color_file(cfilename, ctablename, &D_spec))
- no_color_file(&D_spec, ctablefile);
- }
- *p = 0;
- break;
- default:
- *p = 0;
- break;
- }
- }
- return (drawable_cmd ? 2 : 1);
- }
- void dspf_get_zscale(float *zscale)
- {
- *zscale = D_spec.zscale;
- }
- /* note that currently using G3header */
- void dspf_get_res(float *xres, float *yres, float *zres)
- {
- *xres = (G3header.east - G3header.west) / G3header.xdim;
- *yres = (G3header.north - G3header.south) / G3header.ydim;
- *zres = (G3header.top - G3header.bottom) / G3header.zdim;
- }
- /* note that currently using G3header */
- void dspf_getorigin(float *west, float *south, float *bottom)
- {
- #ifdef DEBUG
- static int first = 1;
- if (first < 10) { /* DEBUG */
- fprintf(stderr, "WEST = %f\nSOUTH = %f\nBOTTOM = %f\n", *west, *south,
- *bottom);
- first++;
- }
- #endif
- *west = G3header.west;
- *south = G3header.south;
- *bottom = G3header.bottom;
- }
- /*-------------------------------------------------------------------
- do_draw ()
- This function is the original immediate mode drawing routine that
- calculates as well as draws the current isosurface dataset. An OpenGL
- display list which stores all of the raw OpenGL drawing directives
- is created by this function that can be used to redraw
- the geometry without having to recompute the isosurface data. The use
- of this OpenGL display list by functions such as do_draw_with_display_list()
- GREATLY speeds up the process of rendering, especially when rendering is
- being done over the network.
- -------------------------------------------------------------------
- */
- void
- do_draw(file_info * Headp, file_info * G3p, struct dspec *D_spec,
- struct Cap *Cap, unsigned int type)
- {
- static double x, y, z;
- float mat[4][4];
- x = Headfax.xdim * D_spec->xscale / 2;
- y = Headfax.ydim * D_spec->yscale / 2;
- z = Headfax.zdim * D_spec->zscale / 2;
- glPushMatrix();
- glTranslatef(0.0, 0.0, D_spec->ztrans); /* move it away from eye */
- if (D_spec->c_flag)
- clear_screen();
- /* Do trackball rotations */
- get_trackball_rotation_matrix(mat);
- glMultMatrixf((float *)mat);
- glTranslatef(-x, -y, -z);
- glDeleteLists(MainDlist, 1);
- glNewList(MainDlist, GL_COMPILE_AND_EXECUTE);
- if (type & DRAW_BBOX)
- do__bbox(D_spec);
- if (type & DRAW_ISO)
- do__draw(Headp, D_spec);
- else if (type & DRAW_SOLID)
- do__draw_solid(Headp, G3p, D_spec, Cap);
- else if (type & DRAW_CAP)
- draw_cap_side(D_spec, Headp, G3p, Cap, (type >> 16) & 0x3f);
- /* bring over arguement to DRAW_CAP in high 16 bits to low 16 */
- /* and AND with 00111111 for sides 1-6 */
- /* todo, only draw visible sides, and dont use Zbuffer */
- if (type & DRAW_BBOX)
- do__bbox(D_spec);
- glEndList();
- if (D_spec->Swap_buf)
- new_swapbuffers();
- glPopMatrix();
- }
- /*-------------------------------------------------------------------
- void draw_ctable()
- This function draws the colortable window.
- -------------------------------------------------------------------
- */
- void draw_ctable()
- {
- long a[2];
- draw_colortable(&D_spec, &Headfax, a);
- }
- /*-------------------------------------------------------------------
- void draw_multiple()
- This function draws multiple thresholds in immediate mode and updates
- the current display list
- -------------------------------------------------------------------
- */
- void draw_multiple()
- {
- int temp;
- if (!D_spec.nt)
- return;
- temp = D_spec.Thresh;
- D_spec.Swap_buf = 0;
- do_draw_multiple_thresholds(&Headfax, &G3header, &D_spec, &D_Cap,
- DRAW_ISO | DRAW_BBOX);
- new_swapbuffers();
- D_spec.Swap_buf = 1;
- D_spec.Thresh = temp;
- }
- /*-------------------------------------------------------------------
- do_draw_immediate_mode()
- This function draws the current scene in immediate mode and updates
- the current display list
- -------------------------------------------------------------------
- */
- void do_draw_immediate_mode()
- {
- do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | DRAW_BBOX);
- }
- /*-------------------------------------------------------------------
- do_draw_with_display_list()
- This function draws the current scene display list
- -------------------------------------------------------------------
- */
- void do_draw_with_display_list(struct dspec *D_spec)
- {
- static double x, y, z;
- float mat[4][4];
- x = Headfax.xdim * D_spec->xscale / 2;
- y = Headfax.ydim * D_spec->yscale / 2;
- z = Headfax.zdim * D_spec->zscale / 2;
- glPushMatrix();
- glTranslatef(0.0, 0.0, D_spec->ztrans); /* move it away from eye */
- if (D_spec->c_flag)
- clear_screen();
- /* first xyz, then yxz, now zyx */
- /* Do trackball rotations */
- get_trackball_rotation_matrix(mat);
- glMultMatrixf((float *)mat);
- glTranslatef(-x, -y, -z);
- glCallList(MainDlist);
- if (D_spec->Swap_buf)
- new_swapbuffers();
- glPopMatrix();
- }
- /*-------------------------------------------------------------------
- do_draw_no_transformations()
- This function draws a single thresholds with no translational or
- rotational transformations.
- -------------------------------------------------------------------
- */
- void
- do_draw_no_transformations(file_info * Headp, file_info * G3p,
- struct dspec *D_spec, struct Cap *Cap,
- unsigned int type)
- {
- if (type & DRAW_BBOX)
- do__bbox(D_spec);
- if (type & DRAW_ISO)
- do__draw(Headp, D_spec);
- else if (type & DRAW_SOLID)
- do__draw_solid(Headp, G3p, D_spec, Cap);
- else if (type & DRAW_CAP)
- draw_cap_side(D_spec, Headp, G3p, Cap, (type >> 16) & 0x3f);
- /* bring over arguement to DRAW_CAP in high 16 bits to low 16 */
- /* and AND with 00111111 for sides 1-6 */
- }
- /*-------------------------------------------------------------------
- do_draw_multiple_thresholds()
- This function computes and draws multiple thresholds at once. OpenGL
- drawing commands are stored in an OpenGL display list for later use.
- -------------------------------------------------------------------
- */
- void
- do_draw_multiple_thresholds(file_info * Headp, file_info * G3p,
- struct dspec *D_spec, struct Cap *Cap,
- unsigned int type)
- {
- static int first = 1;
- static double x, y, z;
- int j;
- float mat[4][4];
- x = Headfax.xdim * D_spec->xscale / 2;
- y = Headfax.ydim * D_spec->yscale / 2;
- z = Headfax.zdim * D_spec->zscale / 2;
- glPushMatrix();
- glTranslatef(0.0, 0.0, D_spec->ztrans); /* move it away from eye */
- if (D_spec->c_flag)
- clear_screen();
- /* Do trackball rotations */
- get_trackball_rotation_matrix(mat);
- glMultMatrixf((float *)mat);
- glTranslatef(-x, -y, -z);
- glDeleteLists(MainDlist, 1);
- glNewList(MainDlist, GL_COMPILE_AND_EXECUTE);
- for (j = 0; j < D_spec->nt; j++) {
- D_spec->Thresh = D_spec->t[j];
- do_draw_no_transformations(Headp, G3p, D_spec, Cap, type);
- }
- glEndList();
- if (D_spec->Swap_buf)
- new_swapbuffers();
- glPopMatrix();
- }
- void do__bbox(struct dspec *D_spec)
- {
- static int first = 1;
- static float x, y, z;
- static float c[8][3]; /*holds the corner points for bounding box */
- static float gxl[100][3], gxh[100][3], gyl[100][3], gyh[100][3];
- int gx, gy;
- glDisable(GL_LIGHTING);
- /*
- ** do rotations here
- */
- /*if (first) */
- {
- x = Headfax.xdim * D_spec->xscale;
- y = Headfax.ydim * D_spec->yscale;
- z = Headfax.zdim * D_spec->zscale;
- /* init corner array */
- c[1][0] = c[2][0] = c[5][0] = c[6][0] = x;
- c[0][0] = c[3][0] = c[4][0] = c[7][0] = 0;
- c[0][1] = c[1][1] = c[4][1] = c[5][1] = y;
- c[3][1] = c[2][1] = c[7][1] = c[6][1] = 0;
- c[0][2] = c[1][2] = c[3][2] = c[2][2] = z;
- c[4][2] = c[5][2] = c[7][2] = c[6][2] = 0;
- /* init grid array */
- if (D_spec->grid) {
- for (gy = 1; gy < Headfax.ydim; gy++) {
- gyl[gy][0] = 0;
- gyh[gy][0] = x;
- gyl[gy][1] = gy * D_spec->yscale;
- gyh[gy][1] = gy * D_spec->yscale;
- gyl[gy][2] = 0;
- gyh[gy][2] = 0;
- }
- for (gx = 1; gx < Headfax.xdim; gx++) {
- gxl[gx][0] = gx * D_spec->xscale;
- gxh[gx][0] = gx * D_spec->xscale;
- gxl[gx][1] = 0;
- gxh[gx][1] = y;
- /*gxl[gx][2] = z; gxh[gx][2] = z; */
- gxl[gx][2] = 0;
- gxh[gx][2] = 0;
- }
- /*init_plane(c,p,sides); this is a much earlier idea JCM */
- /* build plane vertex info (3verts)from the above info used for normals */
- /* based on the planes as defined in cap_data.c */
- /* to have normals pointing the correct direction CCW ordering of vertices */
- /*side 0 xy plane z = zdim */
- D_spec->p[0][0][0] = c[0][0];
- D_spec->p[0][0][1] = c[0][1];
- D_spec->p[0][0][2] = c[0][2];
- D_spec->p[0][1][0] = c[3][0];
- D_spec->p[0][1][1] = c[3][1];
- D_spec->p[0][1][2] = c[3][2];
- D_spec->p[0][2][0] = c[1][0];
- D_spec->p[0][2][1] = c[1][1];
- D_spec->p[0][2][2] = c[1][2];
- /*side 1 xy plane z = 0 */
- D_spec->p[1][0][0] = c[4][0];
- D_spec->p[1][0][1] = c[4][1];
- D_spec->p[1][0][2] = c[4][2];
- D_spec->p[1][1][0] = c[5][0];
- D_spec->p[1][1][1] = c[5][1];
- D_spec->p[1][1][2] = c[5][2];
- D_spec->p[1][2][0] = c[7][0];
- D_spec->p[1][2][1] = c[7][1];
- D_spec->p[1][2][2] = c[7][2];
- /*side 2 yz plane x=xdim */
- D_spec->p[2][0][0] = c[1][0];
- D_spec->p[2][0][1] = c[1][1];
- D_spec->p[2][0][2] = c[1][2];
- D_spec->p[2][1][0] = c[2][0];
- D_spec->p[2][1][1] = c[2][1];
- D_spec->p[2][1][2] = c[2][2];
- D_spec->p[2][2][0] = c[5][0];
- D_spec->p[2][2][1] = c[5][1];
- D_spec->p[2][2][2] = c[5][2];
- /*side 3 yz plane x=0 */
- D_spec->p[3][0][0] = c[6][0];
- D_spec->p[3][0][1] = c[6][1];
- D_spec->p[3][0][2] = c[6][2];
- D_spec->p[3][1][0] = c[7][0];
- D_spec->p[3][1][1] = c[7][1];
- D_spec->p[3][1][2] = c[7][2];
- D_spec->p[3][2][0] = c[3][0];
- D_spec->p[3][2][1] = c[3][1];
- D_spec->p[3][2][2] = c[3][2];
- /*side 4 zx plane y=ydim */
- D_spec->p[4][0][0] = c[4][0];
- D_spec->p[4][0][1] = c[4][1];
- D_spec->p[4][0][2] = c[4][2];
- D_spec->p[4][1][0] = c[0][0];
- D_spec->p[4][1][1] = c[0][1];
- D_spec->p[4][1][2] = c[0][2];
- D_spec->p[4][2][0] = c[1][0];
- D_spec->p[4][2][1] = c[1][1];
- D_spec->p[4][2][2] = c[1][2];
- /*side 5 zx plane y=0 */
- D_spec->p[5][0][0] = c[7][0];
- D_spec->p[5][0][1] = c[7][1];
- D_spec->p[5][0][2] = c[7][2];
- D_spec->p[5][1][0] = c[6][0];
- D_spec->p[5][1][1] = c[6][1];
- D_spec->p[5][1][2] = c[6][2];
- D_spec->p[5][2][0] = c[3][0];
- D_spec->p[5][2][1] = c[3][1];
- D_spec->p[5][2][2] = c[3][2];
- }
- first = 0;
- }
- /* draw bounding box */
- glColor3ub(255, 0, 0);
- glBegin(GL_LINE_LOOP);
- glVertex3fv(c[0]);
- glVertex3fv(c[1]);
- glVertex3fv(c[2]);
- glVertex3fv(c[3]);
- glEnd();
- glBegin(GL_LINES);
- glVertex3fv(c[0]);
- glVertex3fv(c[4]);
- glVertex3fv(c[1]);
- glVertex3fv(c[5]);
- glVertex3fv(c[2]);
- glVertex3fv(c[6]);
- glVertex3fv(c[3]);
- glVertex3fv(c[7]);
- glEnd();
- glBegin(GL_LINE_LOOP);
- glVertex3fv(c[4]);
- glVertex3fv(c[5]);
- glVertex3fv(c[6]);
- glVertex3fv(c[7]);
- glEnd();
- glRasterPos3f(-0.5, y, z);
- new_charstr("0");
- glRasterPos3f(x + 0.5, y, z);
- new_charstr("1");
- glRasterPos3f(-0.5, 0, z);
- new_charstr("3");
- glRasterPos3f(x + 0.5, 0, z);
- new_charstr("2");
- glRasterPos3f(-0.5, y, 0);
- new_charstr("4");
- glRasterPos3f(x + 0.5, y, 0);
- new_charstr("5");
- glRasterPos3f(-0.5, 0, 0);
- new_charstr("7");
- glRasterPos3f(x + 0.5, 0, 0);
- new_charstr("6");
- if (D_spec->grid) {
- for (gy = 1; gy < Headfax.ydim; gy++) {
- glRasterPos3f(-0.5, gy * D_spec->yscale, 0);
- /* sprintf(label,"%d",gy);new_charstr(label); */
- glBegin(GL_LINE_STRIP);
- glVertex3fv(gyl[gy]);
- glVertex3fv(gyh[gy]);
- glEnd();
- glRasterPos3f(x + 0.5, gy * D_spec->yscale, 0);
- /*
- new_charstr(label);
- */
- }
- for (gx = 1; gx < Headfax.xdim; gx++) {
- glRasterPos3f(gx * D_spec->xscale, -0.5, 0);
- /*
- sprintf(label,"%d",gx);new_charstr(label);
- */
- glBegin(GL_LINE_STRIP);
- glVertex3fv(gxl[gx]);
- glVertex3fv(gxh[gx]);
- glEnd();
- glRasterPos3f(gx * D_spec->xscale, y + 0.5, 0);
- /*
- new_charstr(label);
- */
- }
- }
- glEnable(GL_LIGHTING);
- }
- void do__draw(file_info * Headp, struct dspec *D_spec)
- {
- static int first = 1;
- if (first)
- first = 0;
- else
- reset_reads(&Headfax);
- /* fprintf (stderr, "Threshold %d = %f\n",
- D_spec->Thresh + 1, Headp->linefax.tvalue[D_spec->Thresh]);
- fflush(stderr); */
- switch (Headp->linefax.litmodel) {
- case 1:
- fdraw_polys(D_spec);
- break;
- case 2:
- case3:
- gdraw_polys(D_spec);
- break;
- }
- }
- void
- do__draw_solid(file_info * Headp, file_info * G3header, struct dspec *D_spec,
- struct Cap *Cap)
- {
- int min, max;
- min = D_spec->low;
- max = D_spec->hi;
- D_spec->Thresh = min;
- do__draw(Headp, D_spec); /* Draw low thresh */
- D_spec->Thresh = max;
- do__draw(Headp, D_spec); /* Draw hi thresh */
- build_thresh_arrays(D_spec, Headp);
- /* draw_cap_side (D_spec, Headp, G3header, Cap, -1); */
- /* hey - so we cannot watch solids! MN 2001 */
- }
- /*************************** init_bounds *************************************/
- /* this subroutine resets the display boundaries along the xyz axis */
- void init_bounds(struct dspec *D_spec)
- {
- D_spec->B[X] = 0;
- D_spec->B[Y] = 0;
- D_spec->B[Z] = 0;
- D_spec->E[X] = Headfax.xdim;
- D_spec->E[Y] = Headfax.ydim;
- D_spec->E[Z] = Headfax.zdim;
- }
- void init_dspec(struct dspec *D_spec, char *ctable)
- {
- D_spec->Thresh = 0;
- D_spec->nt = 0; /* number of indexes chosen (cumulative) */
- D_spec->xscale = 1.0;
- D_spec->yscale = 1.0;
- D_spec->zscale = 1.0;
- D_spec->xrot = 0;
- D_spec->yrot = 0;
- D_spec->zrot = 0; /* angle in degrees */
- D_spec->Xrot = 0;
- D_spec->Yrot = 0;
- D_spec->Zrot = 0; /* indicates if do autorotate */
- D_spec->ztrans = 0;
- D_spec->Specular = 10;
- D_spec->low = 0;
- D_spec->hi = Headfax.linefax.nthres - 1;
- D_spec->in_out = 0; /*defined as INSIDE */
- D_spec->grid = 0;
- if (0 > get_color_table(ctable, D_spec->ctable)) {
- fprintf(stderr, "Using default color table\n");
- get_default_table(&Headfax, D_spec->ctable);
- }
- }
- /******************************* options ************************************/
- void options()
- {
- /*DISPLAY INSTRUCTIONS FOR THE KEYBOARD INTERACTIVE PROGRAM */
- fprintf(stderr, "\nTHE INTERACTIVE OPTIONS ARE:\n\n");
- fprintf(stderr, "?, (t #), (T # #), +, -\n");
- fprintf(stderr, "(x #) (y #) (z #) (X #) (Y #) (Z #)\n ");
- fprintf(stderr, "B(x,y,z)#), (E(x,y,z)#), R, d ,g, s ,W, w,i,c,Q\n");
- fprintf(stderr, "\nUSAGE AND MEANING:\n\n");
- fprintf(stderr, "? lists available thresholds\n");
- fprintf(stderr, "l index# index# ... add thresholds to display list\n");
- fprintf(stderr,
- "L display list of thresholds entered with \"l\" directive\n");
- /*
- fprintf(stderr,"t index# add threshold to display list \n");
- */
- fprintf(stderr, "T index# reset so only this threshold is displayed\n");
- fprintf(stderr,
- "+(+++) display thresholds with consecutively increasing index#\n");
- fprintf(stderr,
- "-(---) display thresholds with consecutively decreasing index#\n\n");
- fprintf(stderr,
- "x int# absolute rotation around x-axis in degrees(int) \n");
- fprintf(stderr,
- "y int# absolute rotation around y-axis in degrees(int) \n");
- fprintf(stderr,
- "z int# absolute rotation around z-axis in degrees(int) \n");
- fprintf(stderr, "r rotate_model\n");
- fprintf(stderr, "g toggle grid display\n");
- fprintf(stderr, "X int# scale model in x\n");
- fprintf(stderr, "Y int# scale model in y\n");
- fprintf(stderr, "Z int# scale model in z\n\n");
- fprintf(stderr, "S int# specular highlight control\n");
- fprintf(stderr, "B(x,y,z)int# begin display along (x,y,z) axis at #\n");
- fprintf(stderr, "E(x,y,z)int# end display along (x,y,z)axis #\n");
- fprintf(stderr, "R resets display along axis to show all data\n\n");
- fprintf(stderr, "C toggles the c_flag\n");
- fprintf(stderr, "c clears the display (no thresholds)\n");
- fprintf(stderr, "w filename write gif file image\n");
- fprintf(stderr, "W filename dump raw image buffer file\n");
- fprintf(stderr, "i filename read raw image buffer file\n");
- fprintf(stderr, "d draw \n");
- fprintf(stderr, "Q QUIT\n");
- fprintf(stderr, "h help\n");
- }
- void Toggle_swapbuffers(struct dspec *D_spec)
- {
- clear_screen();
- }
- void clear_screen()
- {
- glDisable(GL_LIGHTING);
- glClearColor(1., 1., 1., 1.);
- glClear(GL_COLOR_BUFFER_BIT);
- glClearDepth(1.);
- glClear(GL_DEPTH_BUFFER_BIT);
- glEnable(GL_LIGHTING);
- }
- /********************************************************************/
- /* check begin & end planes for specified axis to make sure:
- 1.) Begin < End
- 2.) Begin > 0 & End < max */
- /********************************************************************/
- void check_limits(struct dspec *D_spec, int axis)
- {
- int max;
- int tmp;
- max = (axis == X) ? Headfax.xdim :
- (axis == Y) ? Headfax.ydim : Headfax.zdim;
- if (D_spec->B[axis] > D_spec->E[axis]) {
- tmp = D_spec->B[axis];
- D_spec->B[axis] = D_spec->E[axis];
- D_spec->E[axis] = tmp;
- }
- if (D_spec->B[axis] < 0)
- D_spec->B[axis] = 0;
- if (D_spec->E[axis] > max)
- D_spec->E[axis] = max;
- }
- void do_translate(file_info * Headp, struct dspec *D_spec)
- {
- float xd, yd, zd, trd;
- xd = Headp->xdim * D_spec->xscale;
- yd = Headp->ydim * D_spec->yscale;
- zd = Headp->zdim * D_spec->zscale;
- /* pick greatest dimension to use for translation of viewer from origin */
- if (xd < yd)
- trd = yd;
- else
- trd = xd;
- if (trd < zd)
- trd = zd;
- glTranslatef(0.0, 0.0, -trd * 1.6); /* move it away from eye */
- }
- void copy_head(file_info * g3head, file_info * head)
- {
- head->north = g3head->north;
- head->south = g3head->south;
- head->east = g3head->east;
- head->west = g3head->west;
- head->top = g3head->top;
- head->bottom = g3head->bottom;
- head->ns_res = g3head->ns_res;
- head->ew_res = g3head->ew_res;
- head->tb_res = g3head->tb_res;
- head->zone = g3head->zone;
- head->proj = g3head->proj;
- }
|