1 #include "medit.h"
2 #include "extern.h"
3 #include "sproto.h"
4
5 GLfloat altcoef=0.0;
6 static int nbimg;
7 extern int refitem,refmat,reftype,imstep,imreverse;
8 extern int *pilmat,ipilmat;
9
10 #define MAX_LST 128
11
12
13 /* rebuild display lists */
doLists(pScene sc,pMesh mesh)14 void doLists(pScene sc,pMesh mesh) {
15 int k;
16
17 /*default */
18 if ( ddebug ) printf("build display lists\n");
19
20 if ( !morphing ) glutSetCursor(GLUT_CURSOR_WAIT);
21 for (k=0; k<MAX_LIST; k++) {
22 if ( sc->dlist[k] ) glDeleteLists(sc->dlist[k],1);
23 if ( sc->clist[k] ) glDeleteLists(sc->clist[k],1);
24 sc->dlist[k] = sc->clist[k] = (GLuint)0;
25 }
26
27 /* poly lists */
28 sc->dlist[LTria] = listTria(sc,mesh);
29 sc->dlist[LQuad] = listQuad(sc,mesh);
30 if ( !mesh->nt && !mesh->nq ) {
31 sc->dlist[LTets] = listTetra(sc,mesh,0);
32 sc->dlist[LHexa] = listHexa(sc,mesh,0);
33 }
34 if ( sc->clip->active & C_VOL ) sc->clip->active |= C_REDO;
35 glutSetCursor(GLUT_CURSOR_INHERIT);
36 checkErrors();
37 }
38
39
40 /* build metric list */
doMapLists(pScene sc,pMesh mesh,int reset)41 void doMapLists(pScene sc,pMesh mesh,int reset) {
42 int k;
43
44 /*default */
45 if ( !mesh->sol ) return;
46 if ( ddebug ) printf("build map lists\n");
47 glutSetCursor(GLUT_CURSOR_WAIT);
48
49 /* delete old lists */
50 if ( reset ) {
51 for (k=0; k<MAX_LIST; k++) {
52 if ( sc->mlist[k] ) glDeleteLists(sc->mlist[k],1);
53 sc->mlist[k] = (GLuint)0;
54 }
55 }
56
57 /* create map list */
58 if ( sc->mode & S_ALTITUDE ) {
59 sc->mlist[LTria] = alt2dList(sc,mesh,LTria,sc->shrink,altcoef);
60 sc->mlist[LQuad] = alt2dList(sc,mesh,LQuad,sc->shrink,altcoef);
61 }
62 else if ( sc->mode & S_MAP ) {
63 if ( mesh->nt && !sc->mlist[LTria] )
64 sc->mlist[LTria] = listTriaMap(sc,mesh);
65 if ( mesh->nq && !sc->mlist[LQuad] )
66 sc->mlist[LQuad] = listQuadMap(sc,mesh);
67 if ( !mesh->nt && mesh->ntet && !sc->mlist[LTets] )
68 sc->mlist[LTets] = listTetraMap(sc,mesh,0);
69 if ( !mesh->nq && mesh->nhex && !sc->mlist[LHexa] )
70 sc->mlist[LHexa] = listHexaMap(sc,mesh,0);
71 }
72
73 glutSetCursor(GLUT_CURSOR_INHERIT);
74 checkErrors();
75 }
76
77
78 /* rebuild iso-values lists */
doIsoLists(pScene sc,pMesh mesh,int reset)79 void doIsoLists(pScene sc,pMesh mesh,int reset) {
80 pPoint ppt;
81 int k,kk,ret;
82
83 /*default */
84 if ( ddebug ) printf("build iso lists\n");
85 glutSetCursor(GLUT_CURSOR_WAIT);
86
87 /* delete old lists */
88 if ( reset ) {
89 for (k=0; k<MAX_LIST; k++) {
90 if ( sc->ilist[k] ) glDeleteLists(sc->ilist[k],1);
91 if ( sc->vlist[k] ) glDeleteLists(sc->vlist[k],1);
92 if ( sc->cplist ) glDeleteLists(sc->cplist,1);
93 sc->ilist[k] = sc->vlist[k] = (GLuint)0;
94 sc->cplist = (GLuint)0;
95 }
96 if ( sc->stream && sc->stream->nbstl ) {
97 for (kk=0; kk<sc->stream->nbstl; kk++) {
98 if ( sc->slist[kk] ) glDeleteLists(sc->slist[kk],1);
99 sc->slist[kk] = (GLuint)0;
100 }
101 sc->slist = (GLuint)0;
102 if ( reset < 2 ) sc->stream->nbstl = 0;
103 for (k=1; k<=mesh->np; k++) {
104 ppt = &mesh->point[k];
105 ppt->flag = 0;
106 }
107 }
108 }
109
110 /* iso-lines */
111 if ( sc->isotyp & S_ISOLINE ) {
112 if ( mesh->nt && !sc->ilist[LTria] )
113 sc->ilist[LTria] = listTriaIso(sc,mesh);
114 if ( mesh->nq && !sc->ilist[LQuad] )
115 sc->ilist[LQuad] = listQuadIso(sc,mesh);
116 }
117 /* iso-surfaces */
118 if ( sc->isotyp & S_ISOSURF ) {
119 if ( mesh->ntet && !sc->ilist[LTets] )
120 sc->ilist[LTets] = listTetraIso(sc,mesh);
121 }
122
123 /* vector */
124 if ( sc->isotyp & S_VECTOR ) {
125 if ( mesh->dim == 2 ) {
126 if ( mesh->nt && !sc->vlist[LTria] )
127 sc->vlist[LTria] = listTria2dVector(mesh);
128 if ( mesh->nq && !sc->vlist[LQuad] )
129 sc->vlist[LQuad] = listQuad2dVector(mesh);
130 }
131 else {
132 if ( mesh->ntet+mesh->nhex == 0 ) {
133 sc->vlist[LTria] = listTria3dVector(mesh);
134 }
135 else {
136 if ( mesh->ntet && !sc->vlist[LTets] )
137 sc->vlist[LTets] = listClipTetraVector(mesh);
138 else if ( mesh->nhex && !sc->vlist[LHexa] )
139 sc->vlist[LHexa] = listClipHexaVector(mesh);
140 }
141 }
142 }
143
144 /* streamlines */
145 if ( sc->isotyp & S_STREAML ) {
146 if ( !mesh->adja || !sc->slist ) {
147 sc->stream = createStream(sc,mesh);
148 if ( !sc->stream )
149 sc->isotyp &= ~S_STREAML;
150 }
151 if ( sc->stream ) {
152 if ( reftype == LPoint )
153 ret = streamRefPoint(sc,mesh);
154 else if ( mesh->dim == 3 ) {
155 if ( reftype == LTria )
156 ret = streamRefTria(sc,mesh);
157 else if ( reftype == LQuad )
158 ret = streamRefQuad(sc,mesh);
159 if ( sc->picklist ) glDeleteLists(sc->picklist,1);
160 sc->picklist = 0;
161 }
162 }
163 }
164
165 /* critical points */
166 if ( sc->isotyp & S_CRITP ) {
167 if ( mesh->dim == 2 )
168 if ( mesh->nt && !sc->cplist )
169 sc->cplist = listCritPoint(sc,mesh);
170 }
171
172 glutSetCursor(GLUT_CURSOR_INHERIT);
173 checkErrors();
174 }
175
176
resetLists(pScene sc,pMesh mesh)177 void resetLists(pScene sc,pMesh mesh) {
178 int kk;
179
180 for (kk=0; kk<MAX_LIST; kk++) {
181 if ( sc->dlist[kk] ) glDeleteLists(sc->dlist[kk],1);
182 if ( sc->mlist[kk] ) glDeleteLists(sc->mlist[kk],1);
183 if ( sc->ilist[kk] ) glDeleteLists(sc->ilist[kk],1);
184 if ( sc->clist[kk] ) glDeleteLists(sc->clist[kk],1);
185 if ( sc->cmlist[kk] ) glDeleteLists(sc->cmlist[kk],1);
186 if ( sc->vlist[kk] ) glDeleteLists(sc->vlist[kk],1);
187 if ( sc->cplist ) glDeleteLists(sc->cplist,1);
188 sc->dlist[kk] = sc->clist[kk] = sc->mlist[kk] = (GLuint)0;
189 sc->ilist[kk] = sc->vlist[kk] = sc->cplist = (GLuint)0;
190 }
191 if ( sc->glist ) glDeleteLists(sc->glist,1);
192 if ( sc->nlist ) glDeleteLists(sc->nlist,1);
193 sc->glist = sc->nlist = (GLuint)0;
194 }
195
196
keyFile(unsigned char key,int x,int y)197 void keyFile(unsigned char key,int x,int y) {
198 pScene sc;
199 pMesh mesh;
200 pTransform view;
201 char *ptr,data[128];
202 ubyte post = FALSE,clipon;
203 static int nfree = 0;
204
205 /* default */
206 sc = cv.scene[currentScene()];
207 mesh = cv.mesh[sc->idmesh];
208 view = sc->view;
209
210 switch(key) {
211 case 'L': /* load prefs */
212 if ( parsop(sc,mesh) ) {
213 refitem = reftype = 0;
214 setupPalette(sc,mesh);
215 initGrafix(sc,mesh);
216 doLists(sc,mesh);
217 if ( sc->mode & S_MAP ) doMapLists(sc,mesh,1);
218 if ( sc->isotyp ) doIsoLists(sc,mesh,1);
219 glClearColor(sc->par.back[0],sc->par.back[1],sc->par.back[2],sc->par.back[3]);
220 post = GL_TRUE;
221 }
222 break;
223 case 'W': /* save prefs */
224 saveMeditFile(mesh->name,sc);
225 break;
226
227 case 'R': /* reload mesh */
228 refitem = reftype = 0;
229 if ( !meshUpdate(sc,mesh) ) exit(1);
230 meshRef(sc,mesh);
231 matSort(sc);
232 setupPalette(sc,mesh);
233 doLists(sc,mesh);
234 if ( sc->mode & S_MAP ) doMapLists(sc,mesh,1);
235 if ( sc->isotyp ) doIsoLists(sc,mesh,1);
236 glClearColor(sc->par.back[0],sc->par.back[1],sc->par.back[2],sc->par.back[3]);
237 post = GL_TRUE;
238 break;
239
240 case 'S': /* save mesh */
241 strcpy(data,mesh->name);
242 ptr = (char*)strstr(data,".mesh");
243 if ( ptr ) *ptr = '\0';
244 sprintf(data,"%s.d.mesh",data);
245 clipon = sc->clip->active & C_ON;
246 if ( clipon )
247 clipVertices(mesh,sc,sc->clip);
248 saveMesh(sc,mesh,data,clipon);
249 break;
250
251 case 'B':
252 case 'C':
253 case 'G':
254 case 'H': /* hardcopy */
255 case 'T':
256 strcpy(data,mesh->name);
257 ptr = (char*)strstr(data,".mesh");
258 if ( ptr ) *ptr = '\0';
259 ptr = (char*)strstr(data,".gis");
260 if ( ptr ) *ptr = '\0';
261
262 if ( option != SEQUENCE ) {
263 if ( key == 'H' )
264 nfree = filnum(data,nfree,"ppm");
265 else
266 nfree = filnum(data,nfree,"ps");
267 if ( nfree == -1 ) break;
268 sprintf(data,"%s.%.3d",data,nfree);
269 }
270 else
271 sprintf(data,"%s.ppm",data);
272 if (!saveimg ) glutSetCursor(GLUT_CURSOR_WAIT);
273 if ( key == 'B' || key == 'C' || key == 'G' )
274 imgTiling(sc,data,key);
275 else
276 imgHard(sc,data,key);
277 if ( animate && !(sc->persp->pmode & CAMERA) && ++nbimg > 179 ) {
278 view->angle = 0.0;
279 nbimg = 0;
280 keyAnim('A',0,0);
281 }
282 if (!saveimg ) glutSetCursor(GLUT_CURSOR_INHERIT);
283 break;
284 case 's': /* softcopy */
285 sftcpy(sc,mesh);
286 post = FALSE;
287 break;
288 }
289 if ( post ) glutPostRedisplay();
290 }
291
menuFile(int item)292 void menuFile(int item) {
293 keyFile((unsigned char)item,0,0);
294 }
295
296
keyItem(unsigned char key,int x,int y)297 void keyItem(unsigned char key,int x,int y) {
298 pScene sc;
299 pMesh mesh;
300 pCube cube;
301 ubyte post = TRUE;
302
303 /* default */
304 sc = cv.scene[currentScene()];
305 mesh = cv.mesh[sc->idmesh];
306 cube = sc->cube;
307
308 switch(key) {
309 case 'A': /* draw axis */
310 sc->item ^= S_AXIS;
311 break;
312 case 'B': /* draw bounding box */
313 sc->item ^= S_BOX;
314 break;
315 case 'D': /*draw selection cube */
316 if ( cube->active & C_ON ) {
317 cube->active &= ~(C_ON+C_EDIT);
318 dumpCube(sc,mesh,cube);
319 }
320 else {
321 cube->active |= C_ON;
322 }
323 break;
324 case 'G': /* draw grid */
325 sc->item ^= S_GRID;
326 break;
327 case 'j': /* toggle info */
328 sc->type ^= S_DECO;
329 break;
330 case 'P': /* toggle point nums */
331 sc->item ^= S_NUMP;
332 break;
333 case 'F': /* toggle face nums */
334 sc->item ^= S_NUMF;
335 break;
336 case 'g': /* const. items */
337 if ( !sc->glist ) post = FALSE;
338 sc->item ^= S_GEOM;
339 break;
340 case 'N':
341 if ( mesh->nvn )
342 sc->type ^= S_NORMAL;
343 else
344 post = FALSE;
345 break;
346 case 'O':
347 if ( mesh->nvn ) {
348 sc->type ^= S_OPPOS;
349 if ( sc->nlist ) {
350 glDeleteLists(sc->nlist,1);
351 sc->nlist = 0;
352 }
353 else
354 post = FALSE;
355 }
356 else
357 post = FALSE;
358 break;
359 }
360 if ( post ) glutPostRedisplay();
361 }
362
menuItem(int item)363 void menuItem(int item) {
364 keyItem((unsigned char)item,0,0);
365 }
366
367
keyAnim(unsigned char key,int x,int y)368 void keyAnim(unsigned char key,int x,int y) {
369 pScene sc;
370 pMesh mesh;
371 pClip clip;
372 ubyte post = TRUE;
373 char *ptr,base[256];
374 static int depart = -1;
375
376 /* default */
377 sc = cv.scene[currentScene()];
378 mesh = cv.mesh[sc->idmesh];
379 clip = sc->clip;
380 if ( depart == -1 )
381 depart = animdep;
382
383 switch(key) {
384 case 'A': /* switch animation */
385 if ( animate ) {
386 sc->view->manim = GL_FALSE;
387 clip->cliptr->manim = GL_FALSE;
388 sc->view->angle = 0.0f;
389 glutIdleFunc(NULL);
390 }
391 else {
392 sc->view->manim = GL_TRUE;
393 clip->cliptr->manim = GL_TRUE;
394 if ( sc->persp->pmode == CAMERA )
395 glutIdleFunc(glutIdle);
396 }
397 animate = 1-animate;
398 post = FALSE;
399 break;
400 case 'I': /* save image */
401 saveimg = 1 - saveimg;
402 nbimg = 0;
403 post = GL_FALSE;
404 break;
405
406 case 'M': /* morphing */
407 if ( morphing )
408 glutIdleFunc(NULL);
409 else
410 glutIdleFunc(glutIdle);
411 morphing = 1-morphing;
412 post = FALSE;
413 break;
414 case 'R': /* next morph */
415 imreverse = 1-imreverse;
416 break;
417
418 case 'S': /* start animation */
419 if ( ddebug ) fprintf(stdout,"debut sequence %d a %d\n",animdep,animfin);
420 glutSetWindow(sc->idwin);
421 if ( option == SEQUENCE )
422 playAnim(sc,mesh,animdep,animfin);
423 if ( !saveimg ) post = FALSE;
424 break;
425
426 case 'f': /* first mesh */
427 /* get basename */
428 ptr = (char *)strrchr(mesh->name,'.');
429 if ( ptr ) *ptr = '\0';
430 strcpy(base,mesh->name);
431 resetLists(sc,mesh);
432 if ( !loadNextMesh(mesh,animdep,0) ) break;
433 doLists(sc,mesh);
434 if ( sc->mode & S_MAP ) doMapLists(sc,mesh,0);
435 if ( sc->isotyp ) doIsoLists(sc,mesh,0);
436 strcpy(mesh->name,base);
437 break;
438
439 case 'l':
440 /* get basename */
441 ptr = (char *)strrchr(mesh->name,'.');
442 if ( ptr ) *ptr = '\0';
443 strcpy(base,mesh->name);
444 resetLists(sc,mesh);
445 if ( !loadNextMesh(mesh,animfin,0) ) break;
446 doLists(sc,mesh);
447 if ( sc->mode & S_MAP ) doMapLists(sc,mesh,0);
448 if ( sc->isotyp ) doIsoLists(sc,mesh,0);
449 strcpy(mesh->name,base);
450 break;
451
452 case 'n':
453 /* get basename */
454 if ( ++depart > animfin ) depart = animdep;
455 ptr = (char *)strrchr(mesh->name,'.');
456 if ( ptr ) *ptr = '\0';
457 strcpy(base,mesh->name);
458 resetLists(sc,mesh);
459 if ( !loadNextMesh(mesh,depart,0) ) break;
460 doLists(sc,mesh);
461 if ( sc->mode & S_MAP ) doMapLists(sc,mesh,0);
462 if ( sc->isotyp ) doIsoLists(sc,mesh,0);
463 strcpy(mesh->name,base);
464 break;
465
466 case 'p':
467 /* get basename */
468 if ( --depart < animdep ) depart = animfin;
469 ptr = (char *)strrchr(mesh->name,'.');
470 if ( ptr ) *ptr = '\0';
471 strcpy(base,mesh->name);
472 resetLists(sc,mesh);
473 if ( !loadNextMesh(mesh,depart,0) ) break;
474 doLists(sc,mesh);
475 if ( sc->mode & S_MAP ) doMapLists(sc,mesh,0);
476 if ( sc->isotyp ) doIsoLists(sc,mesh,0);
477 strcpy(mesh->name,base);
478 break;
479 }
480
481 if ( post == TRUE ) glutPostRedisplay();
482 }
483
menuAnim(int item)484 void menuAnim(int item) {
485 keyAnim((unsigned char)item,0,0);
486 }
487
keyTrajet(unsigned char key,int x,int y)488 void keyTrajet(unsigned char key,int x,int y) {
489 pScene sc;
490 pMesh mesh;
491
492 sc = cv.scene[currentScene()];
493 mesh = cv.mesh[sc->idmesh];
494 switch(key) {
495 case 'C': /* add control point */
496 pathAdd(sc,x,y);
497 break;
498 case 'S': /* show all points */
499 sc->type ^= S_PATH;
500 /*if ( sc->path.tlist ) glDeleteLists(sc->path.tlist,1);*/
501 if ( sc->type & S_PATH && !sc->path.tlist )
502 sc->path.tlist = pathList(sc);
503 break;
504 case 'F': /* follow path */
505 break;
506 case 'L': /* load path */
507 pathLoad(mesh->name,sc);
508 break;
509 case 'W': /* save path */
510 pathSave(mesh->name,sc);
511 break;
512 }
513 glutPostRedisplay();
514 }
515
menuTrajet(int item)516 void menuTrajet(int item) {
517 keyTrajet((unsigned char)item,0,0);
518 }
519
keyMode(unsigned char key,int x,int y)520 void keyMode(unsigned char key,int x,int y) {
521 pScene sc;
522 pMesh mesh;
523 ubyte post = TRUE,dolist = FALSE,material;
524
525 sc = cv.scene[currentScene()];
526 mesh = cv.mesh[sc->idmesh];
527 material = sc->mode & S_MATERIAL;
528
529 switch(key) {
530 case 'D': /* depth lines */
531 if ( sc->mode == DEPTH ) break;
532 sc->mode = DEPTH;
533 break;
534 case 'S': /* toggle smooth shading */
535 if ( sc->mode == FILL )
536 break;
537 sc->mode = FILL;
538 if ( material ) sc->mode |= S_MATERIAL;
539 break;
540 case 'P': /* toggle smooth shaded polys */
541 if ( sc->mode == SHADED )
542 break;
543 sc->mode = SHADED;
544 if ( material ) sc->mode |= S_MATERIAL;
545 break;
546 case 'H': /* hidden lines */
547 if ( sc->mode == HIDDEN ) break;
548 sc->mode = HIDDEN;
549 if ( material ) sc->mode |= S_MATERIAL;
550 break;
551 case 'W': /* wireframe */
552 if ( sc->mode == WIRE ) break;
553 sc->mode = WIRE;
554 if ( material ) sc->mode |= S_MATERIAL;
555 break;
556 case 'n': /* toggle normals */
557 if ( mesh->nvn == 0 ) {
558 post = FALSE;
559 break;
560 }
561 sc->type ^= S_FLAT;
562 dolist = TRUE;
563 break;
564 default:
565 post = FALSE;
566 break;
567 }
568 if ( dolist == TRUE ) doLists(sc,mesh);
569 if ( post == TRUE ) glutPostRedisplay();
570 }
571
menuMode(int item)572 void menuMode(int item) {
573 keyMode((unsigned char)item,0,0);
574 }
575
576
menuScene(int item)577 void menuScene(int item) {
578 keyScene((unsigned char)item,0,0);
579 }
580
keyView(unsigned char key,int x,int y)581 void keyView(unsigned char key,int x,int y) {
582 pScene sc,sc1;
583 pMesh mesh;
584 float dmax;
585 ubyte post = FALSE;
586
587 sc = cv.scene[currentScene()];
588 mesh = cv.mesh[sc->idmesh];
589 /*glutSetMenu(vmenu);*/
590
591 switch(key) {
592 case 'R':
593 sc->type |= S_RESET;
594 dmax = mesh->xmax - mesh->xmin;
595 dmax = max(dmax,mesh->ymax - mesh->ymin);
596 dmax = max(dmax,mesh->zmax - mesh->zmin);
597 sc->cx = sc->cy = sc->cz = 0.0f;
598 sc->dmax = fabs(dmax);
599 if ( sc->persp->pmode == PERSPECTIVE ) {
600 resetTransform(sc->view);
601 initPersp(sc->persp,sc->dmax);
602 }
603 else if ( sc->persp->pmode == CAMERA ) {
604 initPersp(sc->persp,sc->dmax);
605 initCamera(sc,sc->camera->vecup);
606 sc->persp->pmode = CAMERA;
607 }
608 reshapeScene(sc->par.xs,sc->par.ys);
609 post = TRUE;
610 break;
611 case 'C':
612 copyView(sc->view,sc->camera,sc->persp);
613 copyClip(sc->clip);
614 break;
615 case 'L': /* link view */
616 if ( !linkView(sc) ) return;
617 reshapeScene(sc->par.xs,sc->par.ys);
618 post = TRUE;
619 break;
620 case 'P':
621 if ( pasteView(sc->view,sc->camera,sc->persp) &&
622 pasteClip(sc->clip) ) {
623 reshapeScene(sc->par.xs,sc->par.ys);
624 post = TRUE;
625 }
626 break;
627 case 'U':
628 unlinkView(sc);
629 break;
630
631 case 'D': /* duplicate view */
632 if ( cv.nbs == MAX_SCENE ) break;
633 if ( !cv.scene[++cv.nbs] ) {
634 cv.scene[cv.nbs] = (pScene)M_calloc(1,sizeof(Scene),"menus.scene");
635 if ( !cv.scene[cv.nbs] ) break;
636 sc1 = cv.scene[cv.nbs];
637 sc1->material = (pMaterial)calloc(2+sc->par.nbmat,sizeof(Material));
638 assert(sc1->material);
639 }
640 sc1 = cv.scene[cv.nbs];
641 memcpy(sc1,sc,sizeof(Scene));
642 memcpy(sc1->material,sc->material,sc->par.nbmat*sizeof(Material));
643 memcpy(&sc1->par,&sc->par,sizeof(Param));
644 if ( !createScene(sc1,sc1->idmesh) ) {
645 fprintf(stdout," ## Unable to create\n");
646 return;
647 }
648 copyView(sc->view,sc->camera,sc->persp);
649 copyClip(sc->clip);
650 pasteView(sc1->view,sc1->camera,sc1->persp);
651 pasteClip(sc1->clip);
652 break;
653 }
654 if ( post ) glutPostRedisplay();
655 }
656
menuView(int item)657 void menuView(int item) {
658 keyView((unsigned char)item,0,0);
659 }
660
keyColor(unsigned char key,int x,int y)661 void keyColor(unsigned char key,int x,int y) {
662 pScene sc;
663 pMesh mesh;
664 pMaterial pm;
665 int i,k;
666 ubyte post = TRUE,dolist = FALSE;
667
668 sc = cv.scene[currentScene()];
669 mesh = cv.mesh[sc->idmesh];
670
671 switch(key) {
672 case 'b': /* reverse backcolor */
673 sc->par.back[0] = 1.0f - sc->par.back[0];
674 sc->par.back[1] = 1.0f - sc->par.back[1];
675 sc->par.back[2] = 1.0f - sc->par.back[2];
676 glClearColor(sc->par.back[0],sc->par.back[1],sc->par.back[2],sc->par.back[3]);
677 if ( !sc->par.linc ) {
678 sc->par.line[0] = 1.0f - sc->par.line[0];
679 sc->par.line[1] = 1.0f - sc->par.line[1];
680 sc->par.line[2] = 1.0f - sc->par.line[2];
681 }
682 break;
683 case 'e': /* toggle matcolors */
684 sc->mode ^= S_MATERIAL;
685 dolist = TRUE;
686 break;
687 case 'E': /* edit matcolors */
688 post = FALSE;
689 matEdit(sc);
690 break;
691 case 'r':
692 if ( refmat<0 || ipilmat == sc->par.nbmat ) break;
693 pilmat[++ipilmat] = refmat;
694 pm = &sc->material[refmat];
695 pm->flag = 1;
696 updatePoints(sc,mesh,refmat);
697 if ( sc->picklist ) glDeleteLists(sc->picklist,1);
698 sc->picklist = 0;
699 refmat = -1;
700 dolist = TRUE;
701 post = TRUE;
702 break;
703 case 'R': /* reset materials */
704 for (k=0; k<sc->par.nbmat; k++) {
705 pm = &sc->material[k];
706 for (i=LTria; i<=LHexa; i++)
707 pm->depmat[i] = abs(pm->depmat[i]);
708 }
709 dolist = TRUE;
710 break;
711 default:
712 post = FALSE;
713 }
714 if ( dolist ) doLists(sc,mesh);
715 if ( post ) glutPostRedisplay();
716 }
717
menuColor(int item)718 void menuColor(int item) {
719 keyColor((unsigned char)item,0,0);
720 }
721
722
keyClip(unsigned char key,int x,int y)723 void keyClip(unsigned char key,int x,int y) {
724 pScene sc;
725 pMesh mesh;
726 pClip clip;
727 ubyte post = TRUE;
728
729 /* default */
730 sc = cv.scene[currentScene()];
731 mesh = cv.mesh[sc->idmesh];
732 clip = sc->clip;
733
734 switch(key) {
735 case 'C': /* toggle clipping */
736 if ( clip->active & C_ON )
737 clip->active &= ~(C_ON+C_EDIT);
738 else {
739 clip->active |= C_ON;
740 if ( mesh->ntet+mesh->nhex ) clip->active |= C_VOL;
741 }
742 break;
743 case 'E': /* edit clip plane */
744 if ( !(clip->active & C_ON) ) return;
745 if ( clip->active & C_FREEZE ) clip->active ^= C_FREEZE;
746 clip->active ^= C_EDIT;
747 break;
748 case 'F': /* freeze clip */
749 if ( !(clip->active & C_ON) ) return;
750 if ( clip->active & C_EDIT ) clip->active ^= C_EDIT;
751 clip->active ^= C_FREEZE;
752 break;
753 case 'H': /* toggle draw plane */
754 clip->active ^= C_HIDE;
755 break;
756 case 'I': /* inverse orientation */
757 invertClip(sc,clip);
758 clip->active |= C_REDO;
759 break;
760 case 'K': /* toggle capping */
761 clip->active ^= C_CAP;
762 clip->active |= C_REDO;
763 break;
764 case 'R': /* reset clip */
765 if ( !(clip->active & C_ON) ) break;
766 resetClip(sc,clip,mesh);
767 break;
768 case 'Z': /* toggle volclip */
769 clip->active ^= C_VOL;
770 if ( clip->active & C_VOL )
771 clip->active |= C_REDO;
772 break;
773 }
774 if ( post ) glutPostRedisplay();
775 }
776
menuClip(int item)777 void menuClip(int item) {
778 keyClip((unsigned char)item,0,0);
779 }
780
781
keyCube(unsigned char key,int x,int y)782 void keyCube(unsigned char key,int x,int y) {
783 pScene sc;
784 pMesh mesh;
785 pCube cube;
786 ubyte post = TRUE;
787
788 /* default */
789 sc = cv.scene[currentScene()];
790 mesh = cv.mesh[sc->idmesh];
791 cube = sc->cube;
792
793 switch(key) {
794 case 'C': /* toggle clipping */
795 if ( cube->active & C_ON )
796 cube->active &= ~(C_ON+C_EDIT);
797 else
798 cube->active |= C_ON;
799 break;
800 case 'E': /* edit clip plane */
801 if ( !(cube->active & C_ON) ) return;
802 if ( cube->active & C_FREEZE ) cube->active ^= C_FREEZE;
803 cube->active ^= C_EDIT;
804 break;
805 case 'F': /* freeze cube */
806 if ( !(cube->active & C_ON) ) return;
807 if ( cube->active & C_EDIT ) cube->active ^= C_EDIT;
808 cube->active ^= C_FREEZE;
809 break;
810 case 'R': /* reset cube */
811 if ( !(cube->active & C_ON) ) break;
812 resetCube(sc,cube,mesh);
813 break;
814 }
815 if ( post ) glutPostRedisplay();
816 }
817
keyFeature(unsigned char key,int x,int y)818 void keyFeature(unsigned char key,int x,int y) {
819 pScene sc;
820 pMesh mesh;
821 ubyte post=TRUE,dolist=TRUE;
822
823 /* default */
824 sc = cv.scene[currentScene()];
825 mesh = cv.mesh[sc->idmesh];
826
827 switch(key) {
828 case 'S': /* shrink mode */
829 case 'V': /* volumic shrink */
830 if ( sc->shrink < 0.99 )
831 sc->shrink = 1.0f;
832 else
833 sc->shrink = 0.95;
834 dolist = TRUE;
835 break;
836 case 'I': /* increase shrink value */
837 if ( sc->shrink > 0.99 ) break;
838 sc->shrink -= .05;
839 if ( sc->shrink < 0.1 ) sc->shrink = 0.1;
840 dolist = TRUE;
841 break;
842 case 'i': /* decrease shrink value */
843 if ( sc->shrink > 0.99 ) break;
844 sc->shrink += .05;
845 if ( sc->shrink > 0.95 ) sc->shrink = 0.95;
846 dolist = TRUE;
847 break;
848 case 's': /* scissor mode */
849 if ( mesh->dim == 2 ) break;
850 sc->type ^= S_SCISSOR;
851 if ( sc->type & S_SCISSOR )
852 glutDisplayFunc(scissorScene);
853 else {
854 glutDisplayFunc(redrawScene);
855 reshapeScene(sc->par.xs,sc->par.ys);
856 }
857 break;
858 }
859 if ( dolist == TRUE ) {
860 doLists(sc,mesh);
861 if ( sc->mode & S_MAP ) doMapLists(sc,mesh,1);
862 /*if ( sc->isotyp ) doIsoLists(sc,mesh,1);*/
863 }
864 if ( post == TRUE ) glutPostRedisplay();
865 }
866
menuFeature(int item)867 void menuFeature(int item) {
868 keyFeature((unsigned char)item,0,0);
869 }
870
871
menuImage(int item)872 void menuImage(int item) {
873 imgtype = item;
874 }
875
keyMetric(unsigned char key,int x,int y)876 void keyMetric(unsigned char key,int x,int y) {
877 pScene sc;
878 pMesh mesh;
879 pPoint ppt;
880 float maxd;
881 int k,kk;
882 ubyte post=TRUE;
883
884 /* default */
885 sc = cv.scene[currentScene()];
886 mesh = cv.mesh[sc->idmesh];
887
888 switch(key) {
889 case 'c': /* critical points */
890 if ( !mesh->nbb ) return;
891 sc->isotyp ^= S_CRITP;
892 doIsoLists(sc,mesh,0);
893 break;
894 case 'f': /* flush streamlines */
895 if ( sc->stream->nbstl ) {
896 for (kk=0; kk<sc->stream->nbstl; kk++) {
897 if ( sc->slist[kk] ) glDeleteLists(sc->slist[kk],1);
898 sc->slist[kk] = (GLuint)0;
899 }
900 sc->stream->nbstl = 0;
901 for (k=1; k<=mesh->np; k++) {
902 ppt = &mesh->point[k];
903 ppt->flag = 0;
904 }
905 }
906 break;
907 case 'l': /* iso-lines */
908 if ( !mesh->nbb ) return;
909 sc->isotyp ^= S_ISOLINE;
910 doIsoLists(sc,mesh,0);
911 break;
912 case 's': /* iso-surfaces */
913 if ( !mesh->nbb ) return;
914 sc->isotyp ^= S_ISOSURF;
915 doIsoLists(sc,mesh,0);
916 break;
917 case 'u': /* field lines animation */
918 if ( !mesh->nbb || mesh->nfield != mesh->dim ) return;
919 if ( refitem ) {
920 sc->isotyp |= S_PARTICLE;
921 createParticle(sc,mesh);
922 }
923 glutIdleFunc(streamIdle);
924 break;
925 case 'd': /* displacement */
926 if ( !mesh->nbb || mesh->nfield != mesh->dim ) return;
927 sc->mode ^= S_DISPL;
928 meshCoord(mesh,(sc->mode & S_DISPL) ? 1 : 0);
929 meshBox(mesh,0);
930 doLists(sc,mesh);
931 if ( sc->mode & S_MAP ) doMapLists(sc,mesh,1);
932 if ( sc->isotyp ) doIsoLists(sc,mesh,1);
933 break;
934
935 case 'v': /* streamlines */
936 if ( !mesh->nbb || mesh->nfield != mesh->dim ) return;
937 if ( refitem ) {
938 sc->isotyp |= S_STREAML;
939 doIsoLists(sc,mesh,0);
940 }
941 else {
942 if ( !streamIsoPoint(sc,mesh) ) {
943 post = FALSE;
944 sc->isotyp &= ~S_STREAML;
945 }
946 }
947 break;
948 case 'w': /*vector/tensor */
949 if ( mesh->nfield != mesh->dim ) {
950 if ( mesh->dim==2 && mesh->nfield == 3 ) {
951 if ( sc->picklist ) {
952 glDeleteLists(sc->picklist,1);
953 sc->picklist = 0;
954 break;
955 }
956 else {
957 sc->picklist = drawAllEllipse(sc,mesh);
958 break;
959 }
960 }
961 return;
962 }
963 sc->isotyp ^= S_VECTOR;
964 if ( mesh->dim == 3 )
965 if ( mesh->ntet+mesh->nhex && !(sc->clip->active & C_ON) )
966 return;
967 doIsoLists(sc,mesh,0);
968 break;
969
970 case 'k': /* toggle elevation */
971 if ( mesh->dim != 2 ) return;
972 sc->mode ^= S_ALTITUDE;
973 if ( altcoef == 0.0 ) {
974 maxd = max(mesh->xmax-mesh->xmin,mesh->ymax-mesh->ymin);
975 altcoef = 0.3*maxd / mesh->bbmax;
976 }
977 if ( !(sc->mode & S_ALTITUDE) )
978 sc->type |= S_RESET;
979 doMapLists(sc,mesh,1);
980 break;
981 case 'K': /* elevation coeff */
982 fprintf(stdout,"elevation coeff (%.2f): ",altcoef);
983 fflush(stdout);
984 fflush(stdin); fscanf(stdin,"%f",&altcoef);
985 if ( altcoef == 0.0 ) sc->mode |= ~S_ALTITUDE;
986 sc->type |= S_RESET;
987 doMapLists(sc,mesh,1);
988 doIsoLists(sc,mesh,1);
989 break;
990
991 case 'm': /* display metric */
992 if ( !mesh->nbb ) return;
993 sc->mode ^= S_MAP;
994 doMapLists(sc,mesh,1);
995 if ( sc->mode & S_MAP ) {
996 if ( sc->clip->active & C_ON ) sc->clip->active |= C_REDO;
997 if ( !(sc->item & S_PALETTE) )
998 sc->item ^= S_PALETTE;
999 }
1000 else if ( sc->item & S_PALETTE )
1001 sc->item ^= S_PALETTE;
1002 break;
1003 case 'p': /* toggle palette */
1004 if ( !mesh->nbb ) return;
1005 sc->item ^= S_PALETTE;
1006 break;
1007
1008 default:
1009 post = FALSE;
1010 break;
1011 }
1012 if ( post ) glutPostRedisplay();
1013 }
1014
menuMetric(int item)1015 void menuMetric(int item) {
1016 keyMetric((unsigned char)item,0,0);
1017 }
1018
1019
createMenus(pScene sc,pMesh mesh)1020 int createMenus(pScene sc,pMesh mesh) {
1021 int menu,amenu,fmenu,femenu,vmenu,mmenu,smenu;
1022 int clmenu,cmenu,vwmenu,trmenu;
1023
1024 /* default */
1025 if ( ddebug ) printf("create menus\n");
1026 smenu = 0;
1027
1028 /* File management menu */
1029 fmenu = glutCreateMenu(menuFile);
1030 glutAddMenuEntry("[L] Load prefs",'L');
1031 glutAddMenuEntry("[W] Save prefs",'W');
1032 glutAddMenuEntry(" Update mesh",'R');
1033 glutAddMenuEntry(" Save mesh",'S');
1034 glutAddMenuEntry("[H] Hardcopy PPM",'H');
1035 glutAddMenuEntry(" Hardcopy EPS (Color)",'C');
1036 glutAddMenuEntry(" Hardcopy EPS (Grey)",'G');
1037 glutAddMenuEntry(" Hardcopy EPS (B/W)",'B');
1038 glutAddMenuEntry(" Softcopy EPS",'s');
1039
1040 /* rendering mode selector */
1041 mmenu = glutCreateMenu(menuMode);
1042 glutAddMenuEntry("Wireframe",'W');
1043 glutAddMenuEntry("Depth lines",'D');
1044 glutAddMenuEntry("Hidden lines",'H');
1045 glutAddMenuEntry("Shading",'S');
1046 glutAddMenuEntry("Shading+lines",'P');
1047 if ( mesh->nvn > 0 )
1048 glutAddMenuEntry("[n] Toggle Normals",'n');
1049
1050 /* color & material menu */
1051 cmenu = glutCreateMenu(menuColor);
1052 glutAddMenuEntry("[b] Toggle backcolor",'b');
1053 glutAddMenuEntry("[e] Toggle matcolors",'e');
1054 glutAddMenuEntry("[E] Edit matcolors",'E');
1055 glutAddMenuEntry("[r] Hide material",'r');
1056 glutAddMenuEntry("[R] Reset materials",'R');
1057
1058 /* metric */
1059 if ( mesh->nbb > 0 ) {
1060 smenu = glutCreateMenu(menuMetric);
1061 glutAddMenuEntry("[m] Toggle metric",'m');
1062 glutAddMenuEntry("[p] Toggle palette",'p');
1063 if ( mesh->typage == 2 )
1064 glutAddMenuEntry("[o] Toggle iso-lines",'l');
1065 if ( mesh->ntet+mesh->nhex > 0 && mesh->nfield == 1 )
1066 glutAddMenuEntry(" Toggle iso-surfaces",'s');
1067 if ( mesh->nfield == mesh->dim ) {
1068 glutAddMenuEntry("[w] Toggle vector/tensor",'w');
1069 glutAddMenuEntry(" Toggle displacement",'d');
1070 glutAddMenuEntry("[v] Toggle streamlines",'v');
1071 glutAddMenuEntry(" Flush streamlines",'f');
1072 glutAddMenuEntry(" Particle advection",'u');
1073 if ( mesh->dim == 2 )
1074 glutAddMenuEntry(" Critical points",'c');
1075 }
1076 if ( mesh->dim == 2 ) {
1077 glutAddMenuEntry("[k] Toggle elevation",'k');
1078 glutAddMenuEntry("[K] Elevation coeff",'K');
1079 }
1080 }
1081
1082 /* Show misc. items */
1083 vmenu = glutCreateMenu(menuItem);
1084 glutAddMenuEntry("[A] Axis",'A');
1085 glutAddMenuEntry("[B] Bounding box",'B');
1086 glutAddMenuEntry("[G] Grid ",'G');
1087 if ( sc->glist )
1088 glutAddMenuEntry("[g] Geometric items",'g');
1089 glutAddMenuEntry("[j] Toggle Info",'j');
1090 glutAddMenuEntry("[P] Toggle Point num",'P');
1091 glutAddMenuEntry("[F] Toggle Face num",'F');
1092 if ( mesh->nvn ) {
1093 glutAddMenuEntry("[N] Toggle normals",'N');
1094 glutAddMenuEntry("[O] Revert normals",'O');
1095 }
1096
1097 /* clipping menu */
1098 clmenu = glutCreateMenu(menuClip);
1099 glutAddMenuEntry("[F1] Toggle clip",'C');
1100 glutAddMenuEntry("[F2] Edit clip",'E');
1101 glutAddMenuEntry("[F3] Freeze clip",'F');
1102 glutAddMenuEntry(" Inverse orient",'I');
1103 if ( mesh->ntet+mesh->nhex > 0 )
1104 glutAddMenuEntry(" Toggle capping",'K');
1105 glutAddMenuEntry(" Toggle plane",'H');
1106 glutAddMenuEntry(" -- Reset clip",'R');
1107 if ( mesh->ntet+mesh->nhex > 0 ) {
1108 sc->clip->active |= C_VOL;
1109 glutAddMenuEntry("[F4] Toggle Vclip",'Z');
1110 }
1111
1112 /* feature menu */
1113 femenu = glutCreateMenu(menuFeature);
1114 if ( mesh->ntet+mesh->nhex > 0 )
1115 glutAddMenuEntry("[F5] Toggle Vshrink",'V');
1116 else
1117 glutAddMenuEntry("[F5] Toggle shrink",'S');
1118 glutAddMenuEntry("[F6] Increase shrink",'I');
1119 glutAddMenuEntry("[F7] Decrease shrink",'i');
1120 if ( mesh->dim == 3 )
1121 glutAddMenuEntry("Toggle splitview",'s');
1122
1123 /* view handler menu */
1124 vwmenu = glutCreateMenu(menuView);
1125 glutAddMenuEntry("[i] Reset",'R');
1126 glutAddMenuEntry("[Alt-c] Copy",'C');
1127 glutAddMenuEntry("[Alt-p] Paste",'P');
1128 glutAddMenuEntry("[Alt+l] Link",'L');
1129 glutAddMenuEntry("[Alt+u] Unlink",'U');
1130 /*glutAddMenuEntry("[Alt+d] Duplicate",'D');*/
1131
1132 /* animation menu */
1133 amenu = glutCreateMenu(menuAnim);
1134 glutAddMenuEntry("[a] Toggle Anim",'A');
1135 glutAddMenuEntry("Toggle ImgSave",'I');
1136 if ( option == SEQUENCE || option == SEQUENCE + PARTICLE ) {
1137 glutAddMenuEntry("Play sequence",'S');
1138 glutAddMenuEntry("First mesh",'f');
1139 glutAddMenuEntry("Last mesh",'l');
1140 glutAddMenuEntry("Next mesh",'n');
1141 glutAddMenuEntry("Prev mesh",'p');
1142 }
1143 else if ( option == MORPHING ) {
1144 glutAddMenuEntry("Start/Stop morph.",'M');
1145 glutAddMenuEntry("Toggle AutoReverse",'R');
1146 }
1147
1148 /* trajectoire menu */
1149 if ( mesh->dim == 3 || mesh->nbb ) {
1150 trmenu = glutCreateMenu(menuTrajet);
1151 glutAddMenuEntry("New Ctrl point",'C');
1152 glutAddMenuEntry("Toggle path",'S');
1153 glutAddMenuEntry("Follow path",'F');
1154 glutAddMenuEntry("Load path",'L');
1155 glutAddMenuEntry("Save path",'W');
1156 }
1157 else
1158 trmenu = 0;
1159
1160 /* main scene menu */
1161 menu = glutCreateMenu(menuScene);
1162 glutAddSubMenu("File",fmenu);
1163 glutAddSubMenu("Render mode",mmenu);
1164 glutAddSubMenu("Colors, Materials",cmenu);
1165 if ( mesh->nbb )
1166 glutAddSubMenu("Data",smenu);
1167 glutAddSubMenu("Items",vmenu);
1168 if ( mesh->dim == 3 )
1169 glutAddSubMenu("Clipping",clmenu);
1170 glutAddSubMenu("Features",femenu);
1171 glutAddSubMenu("View",vwmenu);
1172 glutAddSubMenu("Animation",amenu);
1173 /*if ( trmenu )
1174 glutAddSubMenu("Trajectory",trmenu);
1175 */
1176 glutAddMenuEntry("",'\0');
1177 glutAddMenuEntry("Close window",'X');
1178 glutAddMenuEntry("Quit",'q');
1179
1180 return(1);
1181 }
1182