main_ogl.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
  1. /****************************************************************************
  2. *
  3. * MODULE: r3.showdspf
  4. * AUTHOR(S): Bill Brown, CERL
  5. * ported from IrisGL to OpenGL by Ken Sakai, Steve Hall,
  6. * Lockheed Martin Space Systems,
  7. * Sunnyale, California, Modification date: March 2000
  8. * PURPOSE: Visualization program which loads the isosurfaces previously calculated
  9. * using r3.mkdspf
  10. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. #include <stdlib.h>
  18. #include <grass/raster3d.h>
  19. #include <grass/config.h>
  20. #define TOGGLE(x) ((x) = (x) ? 0 : 1)
  21. #include <Xm/Xm.h>
  22. #include <Xm/Form.h>
  23. #ifdef HAVE_GL_GLWMDRAWA_H
  24. #include <GL/GLwMDrawA.h>
  25. #else
  26. #ifdef HAVE_X11_GLW_GLWMDRAWA_H
  27. #include <X11/GLw/GLwMDrawA.h>
  28. #endif
  29. #endif
  30. #include "vizual.h"
  31. #include "kns_defines.h"
  32. #include "kns_globals.h"
  33. #include <math.h>
  34. #include <unistd.h>
  35. #include <sys/types.h>
  36. #include <sys/time.h>
  37. #include <ctype.h>
  38. #ifdef __MINGW32__
  39. #include <process.h>
  40. #else
  41. #include <sys/wait.h>
  42. #endif
  43. #ifndef WAIT_ANY
  44. #define WAIT_ANY ((pid_t) -1)
  45. #endif
  46. GLuint Material_1_Dlist;
  47. OGLMotifWindowData MainOGLWindow;
  48. OGLMotifWindowData ColormapWindow;
  49. GLuint MainDlist;
  50. XtAppContext App_context;
  51. file_info Headfax; /* contains info about data itself */
  52. file_info G3header; /* contains info about data itself */
  53. int G_sign;
  54. int X_sign;
  55. long D_offset; /*offset to data in grid3 file */
  56. void set_threshold_button(int i);
  57. char *check_get_any_dspname();
  58. void do__bbox(struct dspec *D_spec);
  59. void init_dspec(struct dspec *D_spec, char *ctable);
  60. void options();
  61. void Toggle_swapbuffers(struct dspec *D_spec);
  62. void clear_screen();
  63. void check_limits(struct dspec *D_spec, int axis);
  64. void copy_head(file_info * g3head, file_info * head);
  65. char *rindex();
  66. static char ctablefile[256];
  67. static struct dspec D_spec;
  68. static struct Cap D_Cap;
  69. static void do_draw();
  70. static void do__draw();
  71. static void do__draw_solid();
  72. void init_bounds(struct dspec *D_spec);
  73. void get_trackball_rotation_matrix(float mat[4][4]);
  74. void set_trackball_rotations(struct dspec *D_spec);
  75. void setSingleSelectionMode();
  76. void setMultipleSelectionMode();
  77. int isSingleSelectionMode();
  78. void do_draw_multiple_thresholds(file_info * Headp, file_info * G3p,
  79. struct dspec *D_spec, struct Cap *Cap,
  80. unsigned int type);
  81. int dumpgif(char *name);
  82. void do_draw_with_display_list(struct dspec *D_spec);
  83. #define DEBUG 1
  84. int main(int argc, char **argv)
  85. {
  86. char buff[300], wname[200];
  87. long Window[3];
  88. char *dsp;
  89. XEvent event;
  90. int i, fdes[2];
  91. void *g3map;
  92. RASTER3D_Region g3reg;
  93. char *p, *mapset;
  94. double dmin, dmax;
  95. fd_set set;
  96. struct timeval timeout;
  97. pid_t pid;
  98. struct Option *g3, *dspf, *colr;
  99. G_gisinit(argv[0]);
  100. g3 = G_define_option();
  101. g3->key = "grid3";
  102. g3->type = TYPE_STRING;
  103. g3->required = YES;
  104. g3->gisprompt = "old,grid3,3d-raster";
  105. g3->description = "Name of an existing 3D raster map";
  106. dspf = G_define_option();
  107. dspf->key = "dspf";
  108. dspf->type = TYPE_STRING;
  109. dspf->required = YES;
  110. dspf->description = "Name of existing display file";
  111. colr = G_define_option();
  112. colr->key = "color";
  113. colr->type = TYPE_STRING;
  114. colr->required = NO;
  115. colr->description = "Name of existing color table";
  116. if (G_parser(argc, argv))
  117. exit(EXIT_FAILURE);
  118. /* set-up for select() */
  119. if (pipe(fdes))
  120. G_fatal_error("Unable to open pipe");
  121. pid = fork();
  122. if (pid == (pid_t) 0) { /* child */
  123. close(fdes[1]);
  124. /* use this to name graphics window */
  125. strcpy(wname, g3->answer);
  126. if (NULL == (dsp =
  127. check_get_any_dspname(dspf->answer, g3->answer, NULL)))
  128. exit(EXIT_FAILURE);
  129. /* TODO - check color file */
  130. /* changed 7/93; normals were pointing to interior as default */
  131. G_sign = 1;
  132. X_sign = -1;
  133. /* opens grid3 file to read in original data
  134. */
  135. Rast3d_set_error_fun(Rast3d_print_error);
  136. /* open g3 file for reading */
  137. if (NULL == (mapset = G_find_file2("grid3", g3->answer, ""))) {
  138. sprintf(buff, "Unable to find 3D raster map for <%s>", g3->answer);
  139. G_fatal_error(buff);
  140. }
  141. g3map = Rast3d_open_cell_old(g3->answer, mapset, RASTER3D_DEFAULT_WINDOW,
  142. RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT);
  143. if (NULL == g3map) {
  144. sprintf(buff, "Unable to open 3D raster map <%s>", g3->answer);
  145. G_fatal_error(buff);
  146. }
  147. if (0 == Rast3d_range_load(g3map)) {
  148. sprintf(buff, "Unable to read range of 3D raster map <%s>", g3->answer);
  149. G_fatal_error(buff);
  150. }
  151. Rast3d_range_min_max(g3map, &dmin, &dmax);
  152. Rast3d_get_region_struct_map(g3map, &g3reg);
  153. viz_make_header(&G3header, dmin, dmax, &g3reg);
  154. init_caps(&D_Cap, &g3reg);
  155. /* open display file for reading */
  156. /* changes 9/2000: Bev Wallace <beverly.t.wallace@lmco.com> */
  157. /* sprintf(buff,"grid3/%s/dsp", g3->answer);
  158. * if(NULL == (mapset = G_find_file2 (buff, dsp, ""))){
  159. */
  160. /* Remove the mapset within buff, add to G_find_file2 - Bev Wallace */
  161. i = strcspn(wname, "@");
  162. if (i > 0)
  163. wname[i] = (char)NULL;
  164. sprintf(buff, "grid3/%s/dsp", wname);
  165. if (NULL == (mapset = G_find_file2(buff, dsp, mapset))) {
  166. sprintf(buff, "Unable to find display file for <%s>", dsp);
  167. G_fatal_error(buff);
  168. }
  169. if ((Headfax.dspfinfp = G_fopen_old(buff, dsp, mapset)) == NULL) {
  170. fprintf(stderr, "Unable to open <%s> for reading\n",
  171. Headfax.dspfinfp);
  172. exit(EXIT_FAILURE);
  173. }
  174. /* read header info from dspf file into GLOBAL variable Headfax */
  175. if (dfread_header(&Headfax) < 0) {
  176. fprintf(stderr, "Unable to read display file header\n");
  177. exit(EXIT_FAILURE);
  178. }
  179. /* set 3dmap for data in Headfax */
  180. Headfax.g3mapin = g3map;
  181. /* currently seems rather redundant, but may have future use to
  182. keep them seperate. */
  183. copy_head(&G3header, &Headfax);
  184. /* INIT */
  185. init_dspec(&D_spec, colr->answer);
  186. /* INITIALIZATION OF THE D_spec.B or D_spec.E CAN HAPPEN MORE THAN ONCE */
  187. init_bounds(&D_spec);
  188. D_spec.Swap_buf = 1;
  189. init_graphics(wname, argc, argv, &D_spec);
  190. draw_colortable(&D_spec, &Headfax, Window);
  191. winset_main();
  192. D_spec.c_flag = 1; /* reset flag */
  193. Toggle_swapbuffers(&D_spec); /* make sure they sync up */
  194. Toggle_swapbuffers(&D_spec);
  195. for (;;) {
  196. int nbytes, fdstatus;
  197. timeout.tv_sec = 0;
  198. timeout.tv_usec = 10000;
  199. FD_ZERO(&set);
  200. FD_SET(fdes[0], &set);
  201. if ((fdstatus =
  202. select(FD_SETSIZE, &set, NULL, NULL, &timeout)) == 1) {
  203. if (FD_ISSET(fdes[0], &set) &&
  204. (nbytes = read(fdes[0], buff, 299)) > 0) {
  205. p = buff;
  206. p[nbytes] = '\0';
  207. dispatch_cmd(p);
  208. }
  209. }
  210. else if (fdstatus == -1) {
  211. G_fatal_error("File Descriptor error");
  212. }
  213. while (XtAppPending(App_context)) {
  214. XtAppNextEvent(App_context, &event);
  215. XtDispatchEvent(&event);
  216. }
  217. }
  218. }
  219. else if (pid < (pid_t) 0) {
  220. G_fatal_error("Fork failed!");
  221. }
  222. else { /* parent */
  223. close(fdes[0]);
  224. options();
  225. /* get input from the keyboard */
  226. fprintf(stderr, "enter desired manipulations then press return\n\n");
  227. fprintf(stderr, "Q ? + - r d l L (xyz)# (XYZ)# S B(xyz)# "
  228. "E(xyz)# R g C c w W i h t T# \n");
  229. fprintf(stderr, " > ");
  230. fflush(stderr);
  231. for (;;) {
  232. int linelen;
  233. if (waitpid(WAIT_ANY, NULL, WNOHANG) != 0)
  234. break; /* Child exited */
  235. if (NULL == fgets(buff, 300, stdin))
  236. break;
  237. linelen = strlen(buff);
  238. if (write(fdes[1], &buff, linelen) != linelen)
  239. G_fatal_error("Unable to write to child process.");
  240. if (waitpid(WAIT_ANY, NULL, WNOHANG) != 0)
  241. break; /* Child exited */
  242. /* get input from the keyboard */
  243. fprintf(stderr,
  244. "enter desired manipulations then press return\n\n");
  245. fprintf(stderr,
  246. "Q ? + - r d l L (xyz)# (XYZ)# S B(xyz)# "
  247. "E(xyz)# R g C c w W i h t T# \n");
  248. fprintf(stderr, " > ");
  249. fflush(stderr);
  250. }
  251. fprintf(stderr, "Goodbye!\n\n");
  252. }
  253. return 0;
  254. }
  255. int dispatch_cmd(char *p)
  256. {
  257. int tmp, tmp2, drawable_cmd;
  258. char cmd, axis;
  259. static int dobox = DRAW_BBOX;
  260. char cfilename[128], ctablename[128];
  261. int j;
  262. int tmp4;
  263. drawable_cmd = 0;
  264. while (*p) { /* assign valid keyboard entries to D_spec structure */
  265. cmd = *p++;
  266. switch (cmd) {
  267. case '#': /* rest of line is a comment */
  268. *p = 0; /* throw away rest of line */
  269. break;
  270. case 'n':
  271. G_sign = -G_sign;
  272. X_sign = -X_sign;
  273. break;
  274. case 'b':
  275. dobox = dobox ? 0 : DRAW_BBOX;
  276. break;
  277. case '+':
  278. if (!isSingleSelectionMode())
  279. setSingleSelectionMode();
  280. D_spec.Thresh++;
  281. if (D_spec.Thresh > Headfax.linefax.nthres - 1)
  282. D_spec.Thresh = 0;
  283. set_threshold_button(D_spec.Thresh + 1);
  284. do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | dobox);
  285. drawable_cmd = 1;
  286. break;
  287. case '-':
  288. D_spec.Thresh--;
  289. if (!isSingleSelectionMode())
  290. setSingleSelectionMode();
  291. if (D_spec.Thresh < 0)
  292. D_spec.Thresh = Headfax.linefax.nthres - 1;
  293. set_threshold_button(D_spec.Thresh + 1);
  294. do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | dobox);
  295. drawable_cmd = 1;
  296. break;
  297. case '?':
  298. {
  299. int i;
  300. for (i = 0; i < Headfax.linefax.nthres; i++)
  301. fprintf(stderr, "%c %3d for threshold value %5.2f\n",
  302. i == D_spec.Thresh ? '*' : ' ', i + 1,
  303. Headfax.linefax.tvalue[i]);
  304. fprintf(stderr, "Rotations: X %d Y %d Z %d\n", D_spec.xrot,
  305. D_spec.yrot, D_spec.zrot);
  306. }
  307. break;
  308. case 'l': /* list thresholds */
  309. D_spec.nt = 0;
  310. G_squeeze(p);
  311. while (isdigit(*p)) {
  312. int i;
  313. i = atoi(p);
  314. if (i < 1 || i > Headfax.linefax.nthres)
  315. fprintf(stderr,
  316. "Range is 1 to %d\n", Headfax.linefax.nthres);
  317. else {
  318. D_spec.t[D_spec.nt] = i - 1;
  319. D_spec.nt++;
  320. }
  321. p++;
  322. if (i >= 10)
  323. p++;
  324. if (i >= 100)
  325. p++;
  326. G_squeeze(p);
  327. }
  328. *p = 0; /* throw away rest of line */
  329. break;
  330. case 'L': /*display list */
  331. if (!D_spec.nt)
  332. break;
  333. if (D_spec.c_flag)
  334. clear_screen();
  335. tmp = D_spec.c_flag;
  336. D_spec.c_flag = 0;
  337. tmp2 = D_spec.Thresh;
  338. D_spec.Swap_buf = 0;
  339. if (isSingleSelectionMode())
  340. setMultipleSelectionMode();
  341. if (D_spec.nt) {
  342. for (j = 0; j < Headfax.linefax.nthres; j++) {
  343. unset_threshold_button(j + 1);
  344. }
  345. for (j = 0; j < D_spec.nt; j++) {
  346. set_threshold_button(D_spec.t[j] + 1);
  347. }
  348. }
  349. do_draw_multiple_thresholds(&Headfax, &G3header, &D_spec, &D_Cap,
  350. DRAW_ISO | dobox);
  351. new_swapbuffers();
  352. D_spec.Swap_buf = 1;
  353. D_spec.c_flag = tmp;
  354. D_spec.Thresh = tmp2;
  355. drawable_cmd = 1;
  356. break;
  357. case 't': /* show only this threshold */
  358. G_squeeze(p);
  359. if (isdigit(*p)) {
  360. int i;
  361. i = atoi(p);
  362. if (i < 1 || i > Headfax.linefax.nthres)
  363. fprintf(stderr, "Range is 1 to %d\n",
  364. Headfax.linefax.nthres);
  365. D_spec.Thresh = i - 1;
  366. if (!isSingleSelectionMode())
  367. setSingleSelectionMode();
  368. set_threshold_button(D_spec.Thresh + 1);
  369. do_draw(&Headfax, &G3header, &D_spec, &D_Cap,
  370. DRAW_ISO | dobox);
  371. drawable_cmd = 1;
  372. *p = 0; /* throw away rest of line */
  373. }
  374. else
  375. fprintf(stderr, "check keyboard entry instructions \n"), *p =
  376. 0;
  377. break;
  378. case 'T': /* show thresholds between hi & lo */
  379. G_squeeze(p);
  380. if (2 != sscanf(p, "%d %d", &(D_spec.low), &(D_spec.hi))) {
  381. /*DEBUG*/
  382. fprintf(stderr, ":><>>> T %d %d\n", (D_spec.low),
  383. (D_spec.hi));
  384. fprintf(stderr, "check keyboard entry instructions \n");
  385. *p = 0;
  386. D_spec.low = 0;
  387. D_spec.hi = Headfax.linefax.nthres - 1;
  388. }
  389. else {
  390. D_spec.low--; /* convert from user to internal #s */
  391. D_spec.hi--;
  392. }
  393. drawable_cmd = 1;
  394. *p = 0; /* throw away rest of line */
  395. break;
  396. case 'B': /* initial value along specified axis */
  397. case 'E': /* ending value along specified axis */
  398. G_squeeze(p);
  399. axis = *p++;
  400. G_squeeze(p);
  401. if (isdigit(*p)) {
  402. G_squeeze(p);
  403. tmp = atoi(p);
  404. *p = 0; /*throw away rest of line */
  405. }
  406. else {
  407. fprintf(stderr, "enter number also\n");
  408. break;
  409. }
  410. switch (axis) {
  411. case 'x':
  412. if (cmd == 'B')
  413. D_spec.B[X] = tmp;
  414. else
  415. D_spec.E[X] = tmp;
  416. tmp = X;
  417. break;
  418. case 'y':
  419. if (cmd == 'B')
  420. D_spec.B[Y] = tmp;
  421. else
  422. D_spec.E[Y] = tmp;
  423. tmp = Y;
  424. break;
  425. case 'z':
  426. if (cmd == 'B')
  427. D_spec.B[Z] = tmp;
  428. else
  429. D_spec.E[Z] = tmp;
  430. tmp = Z;
  431. break;
  432. }
  433. check_limits(&D_spec, tmp);
  434. break;
  435. case 'R':
  436. init_bounds(&D_spec);
  437. break;
  438. case 'S': /* Specular highlight */
  439. G_squeeze(p);
  440. if (isdigit(*p)) {
  441. D_spec.Specular = (float)atof(p);
  442. *p = 0;
  443. change_spec(D_spec.Specular);
  444. }
  445. else
  446. fprintf(stderr, "check keyboard entry instructions \n"), *p =
  447. 0;
  448. break;
  449. case 'r':
  450. fprintf(stderr, " - Rotation Mode -\n"
  451. " 1) Drag with LEFT mouse button to rotate\n"
  452. " 2) Drag right/left with MIDDLE mouse button to zoom in/out\n"
  453. " 3) Click RIGHT mouse button to exit Rotation Mode\n\n");
  454. tmp4 = D_spec.c_flag;
  455. D_spec.c_flag = 1;
  456. rotate_model(&D_spec);
  457. clear_screen();
  458. D_spec.c_flag = tmp4;
  459. break;
  460. case 's': /* use swapbuffers */
  461. /*
  462. Toggle_swapbuffers (&D_spec);
  463. */
  464. break;
  465. case 'd': /* draw it */
  466. G_squeeze(p);
  467. if (isdigit(*p)) {
  468. int i;
  469. i = atoi(p);
  470. if (i == 1)
  471. D_spec.Thresh = D_spec.low;
  472. else
  473. D_spec.Thresh = D_spec.hi;
  474. }
  475. if (!isSingleSelectionMode())
  476. setSingleSelectionMode();
  477. set_threshold_button(D_spec.Thresh + 1);
  478. do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | dobox);
  479. drawable_cmd = 1;
  480. *p = 0;
  481. break;
  482. case 'u': /* Update the screen in double buffer mode */
  483. new_swapbuffers();
  484. break;
  485. case 'D': /* draw solid */
  486. do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_SOLID | dobox);
  487. drawable_cmd = 1;
  488. break;
  489. case 'x': /* rotate around x-axis */
  490. G_squeeze(p);
  491. if (isdigit(*p) || *p == '-' || *p == '+') {
  492. D_spec.xrot = atoi(p);
  493. fprintf(stderr, "(RotX, RotY, RotZ) = (%d, %d, %d)\n\n",
  494. D_spec.xrot, D_spec.yrot, D_spec.zrot);
  495. set_trackball_rotations(&D_spec);
  496. do_draw_with_display_list(&D_spec);
  497. *p = 0;
  498. }
  499. else
  500. fprintf(stderr, "check keyboard entry instructions \n"), *p =
  501. 0;
  502. break;
  503. case 'X': /* scale in x-direction */
  504. G_squeeze(p);
  505. if (isdigit(*p) || *p == '-' || *p == '+') {
  506. D_spec.xscale = atof(p);
  507. do_draw(&Headfax, &G3header, &D_spec, &D_Cap, dobox);
  508. *p = 0;
  509. }
  510. else
  511. fprintf(stderr, "check keyboard entry instructions \n"), *p =
  512. 0;
  513. break;
  514. case 'y': /* rotate around y-axis */
  515. G_squeeze(p);
  516. if (isdigit(*p) || *p == '-' || *p == '+') {
  517. D_spec.yrot = atoi(p);
  518. fprintf(stderr, "(RotX, RotY, RotZ) = (%d, %d, %d)\n\n",
  519. D_spec.xrot, D_spec.yrot, D_spec.zrot);
  520. set_trackball_rotations(&D_spec);
  521. do_draw_with_display_list(&D_spec);
  522. *p = 0;
  523. }
  524. else
  525. fprintf(stderr, "check keyboard entry instructions \n"), *p =
  526. 0;
  527. break;
  528. case 'Y': /* scale in y direction */
  529. G_squeeze(p);
  530. if (isdigit(*p) || *p == '-' || *p == '+') {
  531. D_spec.yscale = atof(p);
  532. do_draw(&Headfax, &G3header, &D_spec, &D_Cap, dobox);
  533. *p = 0;
  534. }
  535. else
  536. fprintf(stderr, "check keyboard entry instructions \n"), *p =
  537. 0;
  538. break;
  539. case 'z': /* rotate around z-axis */
  540. G_squeeze(p);
  541. if (isdigit(*p) || *p == '-' || *p == '+') {
  542. D_spec.zrot = atoi(p);
  543. fprintf(stderr, "(RotX, RotY, RotZ) = (%d, %d, %d)\n\n",
  544. D_spec.xrot, D_spec.yrot, D_spec.zrot);
  545. set_trackball_rotations(&D_spec);
  546. do_draw_with_display_list(&D_spec);
  547. *p = 0;
  548. }
  549. else
  550. fprintf(stderr, "check keyboard entry instructions \n"), *p =
  551. 0;
  552. break;
  553. case 'Z': /* scale in z direction */
  554. G_squeeze(p);
  555. if (isdigit(*p) || *p == '-' || *p == '+') {
  556. D_spec.zscale = atof(p);
  557. do_draw(&Headfax, &G3header, &D_spec, &D_Cap, dobox);
  558. *p = 0;
  559. }
  560. else
  561. fprintf(stderr, "check keyboard entry instructions \n"), *p =
  562. 0;
  563. break;
  564. case 'g': /* toggle grid */
  565. TOGGLE(D_spec.grid);
  566. do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | dobox);
  567. break;
  568. case 'C': /* toggle clear flag */
  569. TOGGLE(D_spec.c_flag);
  570. break;
  571. case 'c': /* redraw the screen */
  572. clear_screen();
  573. new_swapbuffers();
  574. break;
  575. case 'w': /* dump image to file */
  576. dumpgif(G_squeeze(++p));
  577. *p = 0;
  578. break;
  579. case 'W': /* TEST dump image to file */
  580. dumprect(G_squeeze(++p));
  581. *p = 0;
  582. break;
  583. /* TEST READ image from file */
  584. case 'i':
  585. loadrect(G_squeeze(++p));
  586. *p = 0;
  587. break;
  588. case 'Q': /* QUIT */
  589. if (D_spec.cfile != NULL)
  590. fclose(D_spec.cfile);
  591. exit(0);
  592. break;
  593. case 'h': /* help */
  594. options();
  595. break;
  596. case 'p': /* display a single plane 1-6 */
  597. #ifdef NEVER
  598. /* This code cores so I am taking it out. Ken Sakai */
  599. G_squeeze(p);
  600. if (isdigit(*p)) {
  601. D_spec.plane = atoi(p) - 1;
  602. if (D_spec.plane >= 0 && D_spec.plane <= 5) {
  603. /* call plane drawing code */
  604. do_draw(&Headfax, &G3header, &D_spec, &D_Cap,
  605. DRAW_CAP | ((1 << D_spec.plane) << 16));
  606. drawable_cmd = 1;
  607. }
  608. else
  609. fprintf(stderr, "must be number between 1-6\n");
  610. }
  611. else {
  612. /* call code to draw all planes */
  613. do_draw(&Headfax, &G3header, &D_spec, &D_Cap,
  614. DRAW_CAP | (0x3f << 16));
  615. drawable_cmd = 1;
  616. }
  617. *p = 0;
  618. #endif
  619. break;
  620. case 'I': /* toggle in_out flag */
  621. TOGGLE(D_spec.in_out);
  622. break;
  623. case 'F': /* new color File */
  624. G_squeeze(p);
  625. if (2 != sscanf(p, "%s %s", cfilename, ctablename))
  626. no_color_file(&D_spec, ctablefile);
  627. else {
  628. if (0 > new_color_file(cfilename, ctablename, &D_spec))
  629. no_color_file(&D_spec, ctablefile);
  630. }
  631. *p = 0;
  632. break;
  633. default:
  634. *p = 0;
  635. break;
  636. }
  637. }
  638. return (drawable_cmd ? 2 : 1);
  639. }
  640. void dspf_get_zscale(float *zscale)
  641. {
  642. *zscale = D_spec.zscale;
  643. }
  644. /* note that currently using G3header */
  645. void dspf_get_res(float *xres, float *yres, float *zres)
  646. {
  647. *xres = (G3header.east - G3header.west) / G3header.xdim;
  648. *yres = (G3header.north - G3header.south) / G3header.ydim;
  649. *zres = (G3header.top - G3header.bottom) / G3header.zdim;
  650. }
  651. /* note that currently using G3header */
  652. void dspf_getorigin(float *west, float *south, float *bottom)
  653. {
  654. #ifdef DEBUG
  655. static int first = 1;
  656. if (first < 10) { /* DEBUG */
  657. fprintf(stderr, "WEST = %f\nSOUTH = %f\nBOTTOM = %f\n", *west, *south,
  658. *bottom);
  659. first++;
  660. }
  661. #endif
  662. *west = G3header.west;
  663. *south = G3header.south;
  664. *bottom = G3header.bottom;
  665. }
  666. /*-------------------------------------------------------------------
  667. do_draw ()
  668. This function is the original immediate mode drawing routine that
  669. calculates as well as draws the current isosurface dataset. An OpenGL
  670. display list which stores all of the raw OpenGL drawing directives
  671. is created by this function that can be used to redraw
  672. the geometry without having to recompute the isosurface data. The use
  673. of this OpenGL display list by functions such as do_draw_with_display_list()
  674. GREATLY speeds up the process of rendering, especially when rendering is
  675. being done over the network.
  676. -------------------------------------------------------------------
  677. */
  678. void
  679. do_draw(file_info * Headp, file_info * G3p, struct dspec *D_spec,
  680. struct Cap *Cap, unsigned int type)
  681. {
  682. static double x, y, z;
  683. float mat[4][4];
  684. x = Headfax.xdim * D_spec->xscale / 2;
  685. y = Headfax.ydim * D_spec->yscale / 2;
  686. z = Headfax.zdim * D_spec->zscale / 2;
  687. glPushMatrix();
  688. glTranslatef(0.0, 0.0, D_spec->ztrans); /* move it away from eye */
  689. if (D_spec->c_flag)
  690. clear_screen();
  691. /* Do trackball rotations */
  692. get_trackball_rotation_matrix(mat);
  693. glMultMatrixf((float *)mat);
  694. glTranslatef(-x, -y, -z);
  695. glDeleteLists(MainDlist, 1);
  696. glNewList(MainDlist, GL_COMPILE_AND_EXECUTE);
  697. if (type & DRAW_BBOX)
  698. do__bbox(D_spec);
  699. if (type & DRAW_ISO)
  700. do__draw(Headp, D_spec);
  701. else if (type & DRAW_SOLID)
  702. do__draw_solid(Headp, G3p, D_spec, Cap);
  703. else if (type & DRAW_CAP)
  704. draw_cap_side(D_spec, Headp, G3p, Cap, (type >> 16) & 0x3f);
  705. /* bring over arguement to DRAW_CAP in high 16 bits to low 16 */
  706. /* and AND with 00111111 for sides 1-6 */
  707. /* todo, only draw visible sides, and dont use Zbuffer */
  708. if (type & DRAW_BBOX)
  709. do__bbox(D_spec);
  710. glEndList();
  711. if (D_spec->Swap_buf)
  712. new_swapbuffers();
  713. glPopMatrix();
  714. }
  715. /*-------------------------------------------------------------------
  716. void draw_ctable()
  717. This function draws the colortable window.
  718. -------------------------------------------------------------------
  719. */
  720. void draw_ctable()
  721. {
  722. long a[2];
  723. draw_colortable(&D_spec, &Headfax, a);
  724. }
  725. /*-------------------------------------------------------------------
  726. void draw_multiple()
  727. This function draws multiple thresholds in immediate mode and updates
  728. the current display list
  729. -------------------------------------------------------------------
  730. */
  731. void draw_multiple()
  732. {
  733. int temp;
  734. if (!D_spec.nt)
  735. return;
  736. temp = D_spec.Thresh;
  737. D_spec.Swap_buf = 0;
  738. do_draw_multiple_thresholds(&Headfax, &G3header, &D_spec, &D_Cap,
  739. DRAW_ISO | DRAW_BBOX);
  740. new_swapbuffers();
  741. D_spec.Swap_buf = 1;
  742. D_spec.Thresh = temp;
  743. }
  744. /*-------------------------------------------------------------------
  745. do_draw_immediate_mode()
  746. This function draws the current scene in immediate mode and updates
  747. the current display list
  748. -------------------------------------------------------------------
  749. */
  750. void do_draw_immediate_mode()
  751. {
  752. do_draw(&Headfax, &G3header, &D_spec, &D_Cap, DRAW_ISO | DRAW_BBOX);
  753. }
  754. /*-------------------------------------------------------------------
  755. do_draw_with_display_list()
  756. This function draws the current scene display list
  757. -------------------------------------------------------------------
  758. */
  759. void do_draw_with_display_list(struct dspec *D_spec)
  760. {
  761. static double x, y, z;
  762. float mat[4][4];
  763. x = Headfax.xdim * D_spec->xscale / 2;
  764. y = Headfax.ydim * D_spec->yscale / 2;
  765. z = Headfax.zdim * D_spec->zscale / 2;
  766. glPushMatrix();
  767. glTranslatef(0.0, 0.0, D_spec->ztrans); /* move it away from eye */
  768. if (D_spec->c_flag)
  769. clear_screen();
  770. /* first xyz, then yxz, now zyx */
  771. /* Do trackball rotations */
  772. get_trackball_rotation_matrix(mat);
  773. glMultMatrixf((float *)mat);
  774. glTranslatef(-x, -y, -z);
  775. glCallList(MainDlist);
  776. if (D_spec->Swap_buf)
  777. new_swapbuffers();
  778. glPopMatrix();
  779. }
  780. /*-------------------------------------------------------------------
  781. do_draw_no_transformations()
  782. This function draws a single thresholds with no translational or
  783. rotational transformations.
  784. -------------------------------------------------------------------
  785. */
  786. void
  787. do_draw_no_transformations(file_info * Headp, file_info * G3p,
  788. struct dspec *D_spec, struct Cap *Cap,
  789. unsigned int type)
  790. {
  791. if (type & DRAW_BBOX)
  792. do__bbox(D_spec);
  793. if (type & DRAW_ISO)
  794. do__draw(Headp, D_spec);
  795. else if (type & DRAW_SOLID)
  796. do__draw_solid(Headp, G3p, D_spec, Cap);
  797. else if (type & DRAW_CAP)
  798. draw_cap_side(D_spec, Headp, G3p, Cap, (type >> 16) & 0x3f);
  799. /* bring over arguement to DRAW_CAP in high 16 bits to low 16 */
  800. /* and AND with 00111111 for sides 1-6 */
  801. }
  802. /*-------------------------------------------------------------------
  803. do_draw_multiple_thresholds()
  804. This function computes and draws multiple thresholds at once. OpenGL
  805. drawing commands are stored in an OpenGL display list for later use.
  806. -------------------------------------------------------------------
  807. */
  808. void
  809. do_draw_multiple_thresholds(file_info * Headp, file_info * G3p,
  810. struct dspec *D_spec, struct Cap *Cap,
  811. unsigned int type)
  812. {
  813. static int first = 1;
  814. static double x, y, z;
  815. int j;
  816. float mat[4][4];
  817. x = Headfax.xdim * D_spec->xscale / 2;
  818. y = Headfax.ydim * D_spec->yscale / 2;
  819. z = Headfax.zdim * D_spec->zscale / 2;
  820. glPushMatrix();
  821. glTranslatef(0.0, 0.0, D_spec->ztrans); /* move it away from eye */
  822. if (D_spec->c_flag)
  823. clear_screen();
  824. /* Do trackball rotations */
  825. get_trackball_rotation_matrix(mat);
  826. glMultMatrixf((float *)mat);
  827. glTranslatef(-x, -y, -z);
  828. glDeleteLists(MainDlist, 1);
  829. glNewList(MainDlist, GL_COMPILE_AND_EXECUTE);
  830. for (j = 0; j < D_spec->nt; j++) {
  831. D_spec->Thresh = D_spec->t[j];
  832. do_draw_no_transformations(Headp, G3p, D_spec, Cap, type);
  833. }
  834. glEndList();
  835. if (D_spec->Swap_buf)
  836. new_swapbuffers();
  837. glPopMatrix();
  838. }
  839. void do__bbox(struct dspec *D_spec)
  840. {
  841. static int first = 1;
  842. static float x, y, z;
  843. static float c[8][3]; /*holds the corner points for bounding box */
  844. static float gxl[100][3], gxh[100][3], gyl[100][3], gyh[100][3];
  845. int gx, gy;
  846. glDisable(GL_LIGHTING);
  847. /*
  848. ** do rotations here
  849. */
  850. /*if (first) */
  851. {
  852. x = Headfax.xdim * D_spec->xscale;
  853. y = Headfax.ydim * D_spec->yscale;
  854. z = Headfax.zdim * D_spec->zscale;
  855. /* init corner array */
  856. c[1][0] = c[2][0] = c[5][0] = c[6][0] = x;
  857. c[0][0] = c[3][0] = c[4][0] = c[7][0] = 0;
  858. c[0][1] = c[1][1] = c[4][1] = c[5][1] = y;
  859. c[3][1] = c[2][1] = c[7][1] = c[6][1] = 0;
  860. c[0][2] = c[1][2] = c[3][2] = c[2][2] = z;
  861. c[4][2] = c[5][2] = c[7][2] = c[6][2] = 0;
  862. /* init grid array */
  863. if (D_spec->grid) {
  864. for (gy = 1; gy < Headfax.ydim; gy++) {
  865. gyl[gy][0] = 0;
  866. gyh[gy][0] = x;
  867. gyl[gy][1] = gy * D_spec->yscale;
  868. gyh[gy][1] = gy * D_spec->yscale;
  869. gyl[gy][2] = 0;
  870. gyh[gy][2] = 0;
  871. }
  872. for (gx = 1; gx < Headfax.xdim; gx++) {
  873. gxl[gx][0] = gx * D_spec->xscale;
  874. gxh[gx][0] = gx * D_spec->xscale;
  875. gxl[gx][1] = 0;
  876. gxh[gx][1] = y;
  877. /*gxl[gx][2] = z; gxh[gx][2] = z; */
  878. gxl[gx][2] = 0;
  879. gxh[gx][2] = 0;
  880. }
  881. /*init_plane(c,p,sides); this is a much earlier idea JCM */
  882. /* build plane vertex info (3verts)from the above info used for normals */
  883. /* based on the planes as defined in cap_data.c */
  884. /* to have normals pointing the correct direction CCW ordering of vertices */
  885. /*side 0 xy plane z = zdim */
  886. D_spec->p[0][0][0] = c[0][0];
  887. D_spec->p[0][0][1] = c[0][1];
  888. D_spec->p[0][0][2] = c[0][2];
  889. D_spec->p[0][1][0] = c[3][0];
  890. D_spec->p[0][1][1] = c[3][1];
  891. D_spec->p[0][1][2] = c[3][2];
  892. D_spec->p[0][2][0] = c[1][0];
  893. D_spec->p[0][2][1] = c[1][1];
  894. D_spec->p[0][2][2] = c[1][2];
  895. /*side 1 xy plane z = 0 */
  896. D_spec->p[1][0][0] = c[4][0];
  897. D_spec->p[1][0][1] = c[4][1];
  898. D_spec->p[1][0][2] = c[4][2];
  899. D_spec->p[1][1][0] = c[5][0];
  900. D_spec->p[1][1][1] = c[5][1];
  901. D_spec->p[1][1][2] = c[5][2];
  902. D_spec->p[1][2][0] = c[7][0];
  903. D_spec->p[1][2][1] = c[7][1];
  904. D_spec->p[1][2][2] = c[7][2];
  905. /*side 2 yz plane x=xdim */
  906. D_spec->p[2][0][0] = c[1][0];
  907. D_spec->p[2][0][1] = c[1][1];
  908. D_spec->p[2][0][2] = c[1][2];
  909. D_spec->p[2][1][0] = c[2][0];
  910. D_spec->p[2][1][1] = c[2][1];
  911. D_spec->p[2][1][2] = c[2][2];
  912. D_spec->p[2][2][0] = c[5][0];
  913. D_spec->p[2][2][1] = c[5][1];
  914. D_spec->p[2][2][2] = c[5][2];
  915. /*side 3 yz plane x=0 */
  916. D_spec->p[3][0][0] = c[6][0];
  917. D_spec->p[3][0][1] = c[6][1];
  918. D_spec->p[3][0][2] = c[6][2];
  919. D_spec->p[3][1][0] = c[7][0];
  920. D_spec->p[3][1][1] = c[7][1];
  921. D_spec->p[3][1][2] = c[7][2];
  922. D_spec->p[3][2][0] = c[3][0];
  923. D_spec->p[3][2][1] = c[3][1];
  924. D_spec->p[3][2][2] = c[3][2];
  925. /*side 4 zx plane y=ydim */
  926. D_spec->p[4][0][0] = c[4][0];
  927. D_spec->p[4][0][1] = c[4][1];
  928. D_spec->p[4][0][2] = c[4][2];
  929. D_spec->p[4][1][0] = c[0][0];
  930. D_spec->p[4][1][1] = c[0][1];
  931. D_spec->p[4][1][2] = c[0][2];
  932. D_spec->p[4][2][0] = c[1][0];
  933. D_spec->p[4][2][1] = c[1][1];
  934. D_spec->p[4][2][2] = c[1][2];
  935. /*side 5 zx plane y=0 */
  936. D_spec->p[5][0][0] = c[7][0];
  937. D_spec->p[5][0][1] = c[7][1];
  938. D_spec->p[5][0][2] = c[7][2];
  939. D_spec->p[5][1][0] = c[6][0];
  940. D_spec->p[5][1][1] = c[6][1];
  941. D_spec->p[5][1][2] = c[6][2];
  942. D_spec->p[5][2][0] = c[3][0];
  943. D_spec->p[5][2][1] = c[3][1];
  944. D_spec->p[5][2][2] = c[3][2];
  945. }
  946. first = 0;
  947. }
  948. /* draw bounding box */
  949. glColor3ub(255, 0, 0);
  950. glBegin(GL_LINE_LOOP);
  951. glVertex3fv(c[0]);
  952. glVertex3fv(c[1]);
  953. glVertex3fv(c[2]);
  954. glVertex3fv(c[3]);
  955. glEnd();
  956. glBegin(GL_LINES);
  957. glVertex3fv(c[0]);
  958. glVertex3fv(c[4]);
  959. glVertex3fv(c[1]);
  960. glVertex3fv(c[5]);
  961. glVertex3fv(c[2]);
  962. glVertex3fv(c[6]);
  963. glVertex3fv(c[3]);
  964. glVertex3fv(c[7]);
  965. glEnd();
  966. glBegin(GL_LINE_LOOP);
  967. glVertex3fv(c[4]);
  968. glVertex3fv(c[5]);
  969. glVertex3fv(c[6]);
  970. glVertex3fv(c[7]);
  971. glEnd();
  972. glRasterPos3f(-0.5, y, z);
  973. new_charstr("0");
  974. glRasterPos3f(x + 0.5, y, z);
  975. new_charstr("1");
  976. glRasterPos3f(-0.5, 0, z);
  977. new_charstr("3");
  978. glRasterPos3f(x + 0.5, 0, z);
  979. new_charstr("2");
  980. glRasterPos3f(-0.5, y, 0);
  981. new_charstr("4");
  982. glRasterPos3f(x + 0.5, y, 0);
  983. new_charstr("5");
  984. glRasterPos3f(-0.5, 0, 0);
  985. new_charstr("7");
  986. glRasterPos3f(x + 0.5, 0, 0);
  987. new_charstr("6");
  988. if (D_spec->grid) {
  989. for (gy = 1; gy < Headfax.ydim; gy++) {
  990. glRasterPos3f(-0.5, gy * D_spec->yscale, 0);
  991. /* sprintf(label,"%d",gy);new_charstr(label); */
  992. glBegin(GL_LINE_STRIP);
  993. glVertex3fv(gyl[gy]);
  994. glVertex3fv(gyh[gy]);
  995. glEnd();
  996. glRasterPos3f(x + 0.5, gy * D_spec->yscale, 0);
  997. /*
  998. new_charstr(label);
  999. */
  1000. }
  1001. for (gx = 1; gx < Headfax.xdim; gx++) {
  1002. glRasterPos3f(gx * D_spec->xscale, -0.5, 0);
  1003. /*
  1004. sprintf(label,"%d",gx);new_charstr(label);
  1005. */
  1006. glBegin(GL_LINE_STRIP);
  1007. glVertex3fv(gxl[gx]);
  1008. glVertex3fv(gxh[gx]);
  1009. glEnd();
  1010. glRasterPos3f(gx * D_spec->xscale, y + 0.5, 0);
  1011. /*
  1012. new_charstr(label);
  1013. */
  1014. }
  1015. }
  1016. glEnable(GL_LIGHTING);
  1017. }
  1018. void do__draw(file_info * Headp, struct dspec *D_spec)
  1019. {
  1020. static int first = 1;
  1021. if (first)
  1022. first = 0;
  1023. else
  1024. reset_reads(&Headfax);
  1025. /* fprintf (stderr, "Threshold %d = %f\n",
  1026. D_spec->Thresh + 1, Headp->linefax.tvalue[D_spec->Thresh]);
  1027. fflush(stderr); */
  1028. switch (Headp->linefax.litmodel) {
  1029. case 1:
  1030. fdraw_polys(D_spec);
  1031. break;
  1032. case 2:
  1033. case3:
  1034. gdraw_polys(D_spec);
  1035. break;
  1036. }
  1037. }
  1038. void
  1039. do__draw_solid(file_info * Headp, file_info * G3header, struct dspec *D_spec,
  1040. struct Cap *Cap)
  1041. {
  1042. int min, max;
  1043. min = D_spec->low;
  1044. max = D_spec->hi;
  1045. D_spec->Thresh = min;
  1046. do__draw(Headp, D_spec); /* Draw low thresh */
  1047. D_spec->Thresh = max;
  1048. do__draw(Headp, D_spec); /* Draw hi thresh */
  1049. build_thresh_arrays(D_spec, Headp);
  1050. /* draw_cap_side (D_spec, Headp, G3header, Cap, -1); */
  1051. /* hey - so we cannot watch solids! MN 2001 */
  1052. }
  1053. /*************************** init_bounds *************************************/
  1054. /* this subroutine resets the display boundaries along the xyz axis */
  1055. void init_bounds(struct dspec *D_spec)
  1056. {
  1057. D_spec->B[X] = 0;
  1058. D_spec->B[Y] = 0;
  1059. D_spec->B[Z] = 0;
  1060. D_spec->E[X] = Headfax.xdim;
  1061. D_spec->E[Y] = Headfax.ydim;
  1062. D_spec->E[Z] = Headfax.zdim;
  1063. }
  1064. void init_dspec(struct dspec *D_spec, char *ctable)
  1065. {
  1066. D_spec->Thresh = 0;
  1067. D_spec->nt = 0; /* number of indexes chosen (cumulative) */
  1068. D_spec->xscale = 1.0;
  1069. D_spec->yscale = 1.0;
  1070. D_spec->zscale = 1.0;
  1071. D_spec->xrot = 0;
  1072. D_spec->yrot = 0;
  1073. D_spec->zrot = 0; /* angle in degrees */
  1074. D_spec->Xrot = 0;
  1075. D_spec->Yrot = 0;
  1076. D_spec->Zrot = 0; /* indicates if do autorotate */
  1077. D_spec->ztrans = 0;
  1078. D_spec->Specular = 10;
  1079. D_spec->low = 0;
  1080. D_spec->hi = Headfax.linefax.nthres - 1;
  1081. D_spec->in_out = 0; /*defined as INSIDE */
  1082. D_spec->grid = 0;
  1083. if (0 > get_color_table(ctable, D_spec->ctable)) {
  1084. fprintf(stderr, "Using default color table\n");
  1085. get_default_table(&Headfax, D_spec->ctable);
  1086. }
  1087. }
  1088. /******************************* options ************************************/
  1089. void options()
  1090. {
  1091. /*DISPLAY INSTRUCTIONS FOR THE KEYBOARD INTERACTIVE PROGRAM */
  1092. fprintf(stderr, "\nTHE INTERACTIVE OPTIONS ARE:\n\n");
  1093. fprintf(stderr, "?, (t #), (T # #), +, -\n");
  1094. fprintf(stderr, "(x #) (y #) (z #) (X #) (Y #) (Z #)\n ");
  1095. fprintf(stderr, "B(x,y,z)#), (E(x,y,z)#), R, d ,g, s ,W, w,i,c,Q\n");
  1096. fprintf(stderr, "\nUSAGE AND MEANING:\n\n");
  1097. fprintf(stderr, "? lists available thresholds\n");
  1098. fprintf(stderr, "l index# index# ... add thresholds to display list\n");
  1099. fprintf(stderr,
  1100. "L display list of thresholds entered with \"l\" directive\n");
  1101. /*
  1102. fprintf(stderr,"t index# add threshold to display list \n");
  1103. */
  1104. fprintf(stderr, "T index# reset so only this threshold is displayed\n");
  1105. fprintf(stderr,
  1106. "+(+++) display thresholds with consecutively increasing index#\n");
  1107. fprintf(stderr,
  1108. "-(---) display thresholds with consecutively decreasing index#\n\n");
  1109. fprintf(stderr,
  1110. "x int# absolute rotation around x-axis in degrees(int) \n");
  1111. fprintf(stderr,
  1112. "y int# absolute rotation around y-axis in degrees(int) \n");
  1113. fprintf(stderr,
  1114. "z int# absolute rotation around z-axis in degrees(int) \n");
  1115. fprintf(stderr, "r rotate_model\n");
  1116. fprintf(stderr, "g toggle grid display\n");
  1117. fprintf(stderr, "X int# scale model in x\n");
  1118. fprintf(stderr, "Y int# scale model in y\n");
  1119. fprintf(stderr, "Z int# scale model in z\n\n");
  1120. fprintf(stderr, "S int# specular highlight control\n");
  1121. fprintf(stderr, "B(x,y,z)int# begin display along (x,y,z) axis at #\n");
  1122. fprintf(stderr, "E(x,y,z)int# end display along (x,y,z)axis #\n");
  1123. fprintf(stderr, "R resets display along axis to show all data\n\n");
  1124. fprintf(stderr, "C toggles the c_flag\n");
  1125. fprintf(stderr, "c clears the display (no thresholds)\n");
  1126. fprintf(stderr, "w filename write gif file image\n");
  1127. fprintf(stderr, "W filename dump raw image buffer file\n");
  1128. fprintf(stderr, "i filename read raw image buffer file\n");
  1129. fprintf(stderr, "d draw \n");
  1130. fprintf(stderr, "Q QUIT\n");
  1131. fprintf(stderr, "h help\n");
  1132. }
  1133. void Toggle_swapbuffers(struct dspec *D_spec)
  1134. {
  1135. clear_screen();
  1136. }
  1137. void clear_screen()
  1138. {
  1139. glDisable(GL_LIGHTING);
  1140. glClearColor(1., 1., 1., 1.);
  1141. glClear(GL_COLOR_BUFFER_BIT);
  1142. glClearDepth(1.);
  1143. glClear(GL_DEPTH_BUFFER_BIT);
  1144. glEnable(GL_LIGHTING);
  1145. }
  1146. /********************************************************************/
  1147. /* check begin & end planes for specified axis to make sure:
  1148. 1.) Begin < End
  1149. 2.) Begin > 0 & End < max */
  1150. /********************************************************************/
  1151. void check_limits(struct dspec *D_spec, int axis)
  1152. {
  1153. int max;
  1154. int tmp;
  1155. max = (axis == X) ? Headfax.xdim :
  1156. (axis == Y) ? Headfax.ydim : Headfax.zdim;
  1157. if (D_spec->B[axis] > D_spec->E[axis]) {
  1158. tmp = D_spec->B[axis];
  1159. D_spec->B[axis] = D_spec->E[axis];
  1160. D_spec->E[axis] = tmp;
  1161. }
  1162. if (D_spec->B[axis] < 0)
  1163. D_spec->B[axis] = 0;
  1164. if (D_spec->E[axis] > max)
  1165. D_spec->E[axis] = max;
  1166. }
  1167. void do_translate(file_info * Headp, struct dspec *D_spec)
  1168. {
  1169. float xd, yd, zd, trd;
  1170. xd = Headp->xdim * D_spec->xscale;
  1171. yd = Headp->ydim * D_spec->yscale;
  1172. zd = Headp->zdim * D_spec->zscale;
  1173. /* pick greatest dimension to use for translation of viewer from origin */
  1174. if (xd < yd)
  1175. trd = yd;
  1176. else
  1177. trd = xd;
  1178. if (trd < zd)
  1179. trd = zd;
  1180. glTranslatef(0.0, 0.0, -trd * 1.6); /* move it away from eye */
  1181. }
  1182. void copy_head(file_info * g3head, file_info * head)
  1183. {
  1184. head->north = g3head->north;
  1185. head->south = g3head->south;
  1186. head->east = g3head->east;
  1187. head->west = g3head->west;
  1188. head->top = g3head->top;
  1189. head->bottom = g3head->bottom;
  1190. head->ns_res = g3head->ns_res;
  1191. head->ew_res = g3head->ew_res;
  1192. head->tb_res = g3head->tb_res;
  1193. head->zone = g3head->zone;
  1194. head->proj = g3head->proj;
  1195. }