1 #include "medit.h"
2 #include "extern.h"
3 #include "sproto.h"
4
5 extern int refmat,reftype,refitem;
6 int *pilmat,ipilmat;
7 int refpick = -1;
8
9 GLfloat dazim = 1.0;
10 GLfloat delev = 1.0;
11
12 extern void mouseCamera(int button,int state,int x,int y);
13 extern void motionCamera(int x,int y);
14
15
usage()16 static void usage() {
17 fprintf(stdout,"\n");
18 fprintf(stdout,"-- Medit: OnLine Help --\n");
19
20 fprintf(stdout,"** Rendering options (toggle):\n");
21 fprintf(stdout,"f - facets l - lines g - const. entities\n");
22 fprintf(stdout,"c - obj. color e - material b - back color\n");
23 fprintf(stdout,"A - axis B - box G - grid\n");
24 fprintf(stdout,"C - capping r(R) - hide (show) refs.\n");
25 fprintf(stdout,"n - smooth/flat shading\n");
26
27 fprintf(stdout,"\n** Controls options:\n");
28 fprintf(stdout,"i - reset view a - animate I - interactive\n");
29 fprintf(stdout,"h - online help q - quit X - close window\n");
30
31 fprintf(stdout,"\n** View controls (ALT + key):\n");
32 fprintf(stdout,"c - copy d - duplicate p - paste l - link u - unlink\n");
33 fprintf(stdout,"J - toggle flight y - change axis\n");
34
35 fprintf(stdout,"\n** Misc. features\n");
36 fprintf(stdout,"L - load prefs W - save prefs\n");
37 fprintf(stdout,"H - hardcopy PPM\n");
38 fprintf(stdout,"F - face nums P - point nums # - select entity\n");
39 fprintf(stdout,"N - normals O - oppos. normals ! - select plane\n");
40 fprintf(stdout,"m - data o - iso-lines w - tensor/vector\n");
41 fprintf(stdout,"v - streamlines k - toggle elev. K - elev. coeff.\n");
42 fprintf(stdout,"j - toggle deco p - palette S - play animation\n");
43
44 fprintf(stdout,"+/- scale object z/Z scale view\n");
45 fprintf(stdout,"F1,F2,F3 - clipping: On/Off, Edit, Freeze\n");
46 }
47
48 /* special keys CAMERA mode */
specCamera(pScene sc,int key)49 void specCamera(pScene sc,int key) {
50 pCamera c;
51 double dd,azim,elev;
52 GLfloat axe[3];
53 int keyact;
54
55 c = sc->camera;
56 keyact = glutGetModifiers();
57
58 axe[0] = c->speed[2];
59 axe[1] = 0.0;
60 axe[2] = -c->speed[0];
61 dd = sqrt(axe[0]*axe[0] + axe[2]*axe[2]);
62 if ( dd != 0.0f ) {
63 axe[0] /= dd;
64 axe[2] /= dd;
65 }
66
67 switch (key) {
68 case GLUT_KEY_LEFT:
69 if ( keyact & GLUT_ACTIVE_SHIFT ) {
70 c->eye[0] += axe[0]*c->altinc;
71 c->eye[2] += axe[2]*c->altinc;
72 reshapeScene(sc->par.xs,sc->par.ys);
73 glutPostRedisplay();
74 return;
75 }
76 else {
77 azim = Azimuth(c);
78 elev = Elevation(c);
79 azim += dazim;
80 }
81 break;
82 case GLUT_KEY_RIGHT:
83 if ( keyact & GLUT_ACTIVE_SHIFT ) {
84 c->eye[0] -= axe[0]*c->altinc;
85 c->eye[2] -= axe[2]*c->altinc;
86 reshapeScene(sc->par.xs,sc->par.ys);
87 glutPostRedisplay();
88 return;
89 }
90 else {
91 azim = Azimuth(c);
92 elev = Elevation(c);
93 azim -= dazim;
94 }
95 break;
96 case GLUT_KEY_UP:
97 if ( keyact & GLUT_ACTIVE_SHIFT ) {
98 c->eye[1] += c->altinc;
99 reshapeScene(sc->par.xs,sc->par.ys);
100 glutPostRedisplay();
101 return;
102 }
103 else {
104 azim = Azimuth(c);
105 elev = Elevation(c);
106 elev -= delev;
107 }
108 break;
109 case GLUT_KEY_DOWN:
110 if ( keyact & GLUT_ACTIVE_SHIFT ) {
111 c->eye[1] -= c->altinc;
112 reshapeScene(sc->par.xs,sc->par.ys);
113 glutPostRedisplay();
114 return;
115 }
116 else {
117 azim = Azimuth(c);
118 elev = Elevation(c);
119 elev += delev;
120 }
121 break;
122 default:
123 return;
124 }
125
126 updateCamera(sc,c,azim,elev);
127
128 /* refresh scene */
129 reshapeScene(sc->par.xs,sc->par.ys);
130 glutPostRedisplay();
131 }
132
133
134 /* change center of scene */
changeCenter(pScene sc,pMesh mesh)135 static void changeCenter(pScene sc,pMesh mesh) {
136 pPoint p0;
137 pTriangle pt;
138 pQuad pq;
139 pTetra ptt;
140 pHexa ph;
141 float cx,cy,cz;
142 int i;
143
144 if ( !refitem ) return;
145 cx = cy = cz = 0.0;
146 switch(reftype) {
147 case LPoint:
148 p0 = &mesh->point[refitem];
149 cx = p0->c[0];
150 cy = p0->c[1];
151 cz = p0->c[2];
152 break;
153 case LTria:
154 pt = &mesh->tria[refitem];
155 for (i=0; i<3; i++) {
156 p0 = &mesh->point[pt->v[i]];
157 cx += 0.33 * p0->c[0];
158 cy += 0.33 * p0->c[1];
159 cz += 0.33 * p0->c[2];
160 }
161 break;
162 case LQuad:
163 pq = &mesh->quad[refitem];
164 for (i=0; i<4; i++) {
165 p0 = &mesh->point[pq->v[i]];
166 cx += 0.25 * p0->c[0];
167 cy += 0.25 * p0->c[1];
168 cz += 0.25 * p0->c[2];
169 }
170 break;
171 case LTets:
172 ptt = &mesh->tetra[refitem];
173 for (i=0; i<4; i++) {
174 p0 = &mesh->point[ptt->v[i]];
175 cx += 0.25 * p0->c[0];
176 cy += 0.25 * p0->c[1];
177 cz += 0.25 * p0->c[2];
178 }
179 break;
180 case LHexa:
181 ph = &mesh->hexa[refitem];
182 for (i=0; i<8; i++) {
183 p0 = &mesh->point[ph->v[i]];
184 cx += 0.125 * p0->c[0];
185 cy += 0.125 * p0->c[1];
186 cz += 0.125 * p0->c[2];
187 }
188 break;
189 }
190
191 /* reset translation and move to center */
192 sc->view->panx = sc->view->pany = 0.0;
193 sc->cx = -cx;
194 sc->cy = -cy;
195 sc->cz = -cz;
196 }
197
198
199 /* special keys PERSPECTIVE mode */
special(int key,int x,int y)200 void special(int key,int x,int y) {
201 pTransform view;
202 pScene sc;
203 pMesh mesh;
204 pClip clip;
205 pCube cube;
206 float pancoeff = 0.1f;
207 int keyact,idw = currentScene();
208 ubyte post = TRUE;
209
210 /* default */
211 if ( ddebug ) printf("special key %d\n",key);
212 sc = cv.scene[idw];
213
214 /* special mode camera */
215 if ( sc->persp->pmode == CAMERA ) {
216 specCamera(sc,key);
217 return;
218 }
219
220 view = sc->view;
221 mesh = cv.mesh[sc->idmesh];
222 clip = sc->clip;
223 cube = sc->cube;
224 keyact = glutGetModifiers();
225 if ( keyact & GLUT_ACTIVE_SHIFT )
226 pancoeff = 0.01;
227
228 switch(key) {
229 case GLUT_KEY_F1: /* toggle clipping plane */
230 if ( mesh->dim == 3 ) {
231 if ( cube->active & C_ON)
232 keyCube('C',0,0);
233 else
234 keyClip('C',0,0);
235 }
236 post = FALSE;
237 break;
238 case GLUT_KEY_F2: /* edit clipping plane */
239 if ( mesh->dim == 3 ) {
240 if ( cube->active & C_ON)
241 keyCube('E',0,0);
242 else if ( clip->active & C_ON )
243 keyClip('E',0,0);
244 }
245 post = FALSE;
246 break;
247 case GLUT_KEY_F3: /* freeze clipping plane */
248 if ( cube->active & C_ON )
249 keyCube('F',0,0);
250 else if ( clip->active & C_ON )
251 keyClip('F',0,0);
252 post = FALSE;
253 break;
254 case GLUT_KEY_F4: /* toggle Vclip */
255 if ( mesh->dim == 3 ) keyClip('Z',0,0);
256 post = FALSE;
257 break;
258 case GLUT_KEY_F5: /* Toggle Shrink */
259 if ( mesh->ntet+mesh->nhex > 0 )
260 keyFeature('V',0,0);
261 else
262 keyFeature('S',0,0);
263 break;
264 case GLUT_KEY_F6: /* Increase Shrink */
265 keyFeature('I',0,0);
266 break;
267 case GLUT_KEY_F7: /* Decrease Shrink */
268 keyFeature('i',0,0);
269 break;
270
271 case GLUT_KEY_LEFT: /* translate eyes or object */
272 if ( clip->active & C_EDIT ) {
273 clip->cliptr->panx -= 0.02 * sc->dmax;
274 clip->cliptr->angle = 0.0;
275 clip->active |= C_UPDATE + C_REDO;
276 }
277 else if ( keyact & GLUT_ACTIVE_CTRL ) {
278 sc->par.eyesep *= 0.9;
279 printf("eyesep %f\n",sc->par.eyesep);
280 }
281 else
282 view->panx -= pancoeff * sc->dmax;
283 break;
284 case GLUT_KEY_RIGHT:
285 if ( clip->active & C_EDIT ) {
286 clip->cliptr->panx += 0.02 * sc->dmax;
287 clip->cliptr->angle = 0.0;
288 clip->active |= C_UPDATE + C_REDO;
289 }
290 else if ( keyact & GLUT_ACTIVE_CTRL ) {
291 sc->par.eyesep *= 1.1;
292 printf("eyesep %f\n",sc->par.eyesep);
293 }
294 else
295 view->panx += pancoeff * sc->dmax;
296 break;
297 case GLUT_KEY_UP:
298 if ( clip->active & C_EDIT ) {
299 clip->cliptr->pany += 0.02 * sc->dmax;
300 clip->cliptr->angle = 0.0;
301 clip->active |= C_UPDATE + C_REDO;
302 }
303 else
304 view->pany += pancoeff * sc->dmax;
305 break;
306 case GLUT_KEY_DOWN:
307 if ( clip->active & C_EDIT ) {
308 clip->cliptr->pany -= 0.02 * sc->dmax;
309 clip->cliptr->angle = 0.0;
310 clip->active |= C_UPDATE + C_REDO;
311 }
312 else
313 view->pany -= pancoeff * sc->dmax;
314 break;
315 default:
316 return;
317 }
318 if ( post ) glutPostRedisplay();
319 }
320
321
keyScene(unsigned char key,int x,int y)322 void keyScene(unsigned char key,int x,int y) {
323 pMaterial pm;
324 pTetra ptt;
325 pHexa ph;
326 pTriangle pt;
327 pQuad pq;
328 pScene sc,sc1;
329 pMesh mesh;
330 pClip clip;
331 pCube cube;
332 pPersp p;
333 pCamera cam;
334 double dd;
335 float a,b,c,d;
336 int k,keyact,numit,idw = currentScene();
337 ubyte post = FALSE,dolist = FALSE;
338
339 if ( idw < 0 ) exit(0);
340
341 /* ESC = end medit */
342 if ( key == 'q' || key == 27 )
343 exit(0);
344 else if ( key == 'h' || key == '?' )
345 usage();
346
347 /* default */
348 sc = cv.scene[idw];
349 mesh = cv.mesh[sc->idmesh];
350 clip = sc->clip;
351 cube = sc->cube;
352 p = sc->persp;
353
354 keyact = glutGetModifiers();
355 if ( key == ' ' ) {
356 if ( option == MORPHING )
357 morphMesh(sc,mesh);
358 else if ( sc->isotyp & S_PARTICLE ) {
359 glutIdleFunc(0);
360 }
361 else {
362 cam = sc->camera;
363 cam->eye[0] += cam->spmod*cam->speed[0];
364 cam->eye[1] += cam->spmod*cam->speed[1];
365 cam->eye[2] += cam->spmod*cam->speed[2];
366 reshapeScene(sc->par.xs,sc->par.ys);
367 }
368 post = TRUE;
369 }
370
371 else if ( islower(key) ) {
372 switch(key) {
373 case 'a': /* toggle animate */
374 keyAnim('A',0,0);
375 break;
376 case 'b': /* backcolor */
377 keyColor('b',0,0);
378 break;
379 case 'c':
380 if ( keyact & GLUT_ACTIVE_ALT )
381 keyView('C',0,0);
382 else {
383 sc->mode ^= S_COLOR;
384 post = TRUE;
385 }
386 break;
387 case 'd':
388 if ( keyact & GLUT_ACTIVE_ALT ) keyView('D',0,0);
389 break;
390 case 'e':
391 keyColor('e',0,0);
392 break;
393 case 'f':
394 sc->mode ^= S_FILL;
395 post=TRUE;
396 break;
397 case 'g':
398 keyItem('g',0,0);
399 break;
400 case 'h':
401 usage();
402 break;
403 case 'i':
404 keyView('R',0,0);
405 if ( clip->active & C_ON ) resetClip(sc,clip,mesh);
406 if ( cube->active & C_ON ) resetCube(sc,cube,mesh);
407 sc1 = sc;
408 while ( sc1->slave > -1 ) {
409 sc1 = cv.scene[sc1->slave];
410 glutSetWindow(sc1->idwin);
411 keyScene('i',0,0);
412 }
413 glutSetWindow(sc->idwin);
414 break;
415 case 'j':
416 sc->type ^= S_DECO;
417 post = TRUE;
418 break;
419 case 'k':
420 keyMetric('k',0,0);
421 break;
422 case 'l':
423 if ( keyact & GLUT_ACTIVE_ALT )
424 keyView('L',0,0);
425 else
426 sc->mode ^= S_BDRY;
427 post = TRUE;
428 break;
429 case 'm': /* toggle metric */
430 if ( mesh->nbb ) keyMetric('m',0,0);
431 keyMode('n',0,0);
432 break;
433 case 'n':
434 if ( mesh->nvn ) keyMode('n',0,0);
435 break;
436 case 'o': /* iso-lines */
437 if ( mesh->nbb ) keyMetric('l',0,0);
438 break;
439 case 'p':
440 if ( keyact & GLUT_ACTIVE_ALT )
441 keyView('P',0,0);
442 else
443 keyMetric('p',0,0);
444 break;
445 case 'r':
446 if ( refmat<0 || ipilmat == sc->par.nbmat ) return;
447 pilmat[++ipilmat] = refmat;
448 pm = &sc->material[refmat];
449 pm->flag = 1;
450 updatePoints(sc,mesh,refmat);
451 if ( sc->picklist ) glDeleteLists(sc->picklist,1);
452 sc->picklist = 0;
453 refmat = -1;
454 dolist = TRUE;
455 post = TRUE;
456 break;
457 case 's':
458 if ( !refitem ) return;
459 switch(reftype) {
460 case LTria:
461 pt = &mesh->tria[refitem];
462 pt->v[0] = 0;
463 break;
464 case LQuad:
465 pq = &mesh->quad[refitem];
466 pq->v[0] = 0;
467 break;
468 case LTets:
469 ptt = &mesh->tetra[refitem];
470 ptt->v[0] = 0;
471 break;
472 case LHexa:
473 ph = &mesh->hexa[refitem];
474 ph->v[0] = 0;
475 break;
476 }
477 sc->picklist = 0;
478 dolist = TRUE;
479 post = TRUE;
480 break;
481 case 't': /* toggle texture */
482 /*keyColor('t',0,0);*/
483 break;
484 case 'u':
485 if ( keyact & GLUT_ACTIVE_ALT )
486 keyView('U',0,0);
487 break;
488 case 'v':
489 keyMetric('v',0,0);
490 break;
491 case 'w':
492 keyMetric('w',0,0);
493 break;
494 case 'x':
495 if ( cube->active & C_EDIT ) {
496 cube->cma[0] += 0.1*sc->dmax;
497 post = TRUE;
498 break;
499 }
500 case 'y':
501 if ( cube->active & C_EDIT ) {
502 cube->cma[1] += 0.1*sc->dmax;
503 post = TRUE;
504 break;
505 }
506 if ( p->pmode & CAMERA ) {
507 cam = sc->camera;
508 cam->vecup = (cam->vecup+1) % 3;
509 switch(cam->vecup) {
510 case X_AXIS: cam->altinc = (mesh->xmax-mesh->xmin); break;
511 case Y_AXIS: cam->altinc = (mesh->ymax-mesh->ymin); break;
512 case Z_AXIS: cam->altinc = (mesh->zmax-mesh->zmin); break;
513 }
514 cam->altinc *= 0.005f;
515 sc->type |= S_RESET;
516 reshapeScene(sc->par.xs,sc->par.ys);
517 }
518 /* tilt cut plane */
519 else if ( clip->active & C_EDIT )
520 tiltClip(sc,clip);
521 else return;
522 post = TRUE;
523 break;
524
525 case 'z': /* zoom in */
526 if ( cube->active & C_EDIT ) {
527 cube->cma[2] += 0.1*sc->dmax;
528 post = TRUE;
529 break;
530 }
531 else {
532 if ( p->rubber == 2 )
533 setPersp(sc,p,1);
534 else
535 p->fovy = max(0.9*p->fovy,1e-05);
536 farclip(1);
537 }
538 post = TRUE;
539
540 /* get linked view */
541 sc1 = sc;
542 while ( sc1->slave > -1 ) {
543 sc1 = cv.scene[sc1->slave];
544 memcpy(sc1->view,sc->view,sizeof(struct transform));
545 memcpy(sc1->persp,sc->persp,sizeof(struct sperspective));
546 glutSetWindow(sc1->idwin);
547 reshapeScene(sc1->par.xs,sc1->par.ys);
548 }
549 glutSetWindow(sc->idwin);
550 break;
551 }
552 }
553
554 else if ( isupper(key) ) {
555 switch(key) {
556 case 'A': /* toggle axis */
557 keyItem('A',0,0);
558 break;
559 case 'B': /* toggle box */
560 keyItem('B',0,0);
561 break;
562 case 'C': /* toggle capping */
563 keyClip('K',0,0);
564 break;
565 case 'D': /* selection cube */
566 if (mesh->dim == 3 ) keyItem('D',0,0);
567 break;
568 case 'E':
569 keyColor('E',0,0);
570 glutSetWindow(sc->idwin);
571 break;
572 case 'F': /* toggle face nums */
573 keyItem('F',0,0);
574 break;
575 case 'G': /* toggle grid */
576 keyItem('G',0,0);
577 break;
578 case 'H': /* hardcopy PPM */
579 keyFile('H',0,0);
580 break;
581 case 'I': /* follows mouse */
582 sc->type ^= S_FOLLOW;
583 sc1 = sc;
584 while ( sc1->slave > -1 ) {
585 sc1 = cv.scene[sc1->slave];
586 sc1->type = sc->type;
587 }
588 break;
589 case 'J':
590 if ( mesh->dim == 2 && !(sc->mode & S_ALTITUDE) ) break;
591 if ( p->pmode == PERSPECTIVE ) {
592 p->pmode = CAMERA;
593 glutMouseFunc(mouseCamera);
594 glutMotionFunc(motionCamera);
595 }
596 else {
597 p->pmode = PERSPECTIVE;
598 glutMouseFunc(mouse);
599 glutMotionFunc(motion);
600 }
601 sc->type = S_RESET;
602 reshapeScene(sc->par.xs,sc->par.ys);
603 post = TRUE;
604 break;
605 case 'K':
606 keyMetric('K',0,0);
607 break;
608 case 'L':
609 keyFile('L',0,0);
610 break;
611 case 'M':
612 morphing = 1-morphing;
613 post = TRUE;
614 break;
615 case 'N': /* draw normals */
616 case 'O':
617 if ( mesh->nvn )
618 keyItem(key,0,0);
619 break;
620 case 'P': /* toggle point nums */
621 keyItem('P',0,0);
622 break;
623 case 'Q':
624 /*keyMetric('q',0,0);*/
625 break;
626 case 'R':
627 if ( ipilmat < 1 ) return;
628 refmat = pilmat[ipilmat--];
629 pm = &sc->material[refmat];
630 pm->flag = 0;
631 updatePoints(sc,mesh,refmat);
632 dolist = TRUE;
633 post = TRUE;
634 break;
635 case 'S': /* softcopy */
636 /*keyFile('S',0,0);*/
637 keyAnim('S',0,0);
638 break;
639 case 'V': /* change center of scene */
640 if ( !refitem ) return;
641 changeCenter(sc,mesh);
642 reshapeScene(sc->par.xs,sc->par.ys);
643 post = TRUE;
644 /* linked view */
645 sc1 = sc;
646 while ( sc1->slave > -1 ) {
647 sc1 = cv.scene[sc1->slave];
648 sc1->cx = sc->cx;
649 sc1->cy = sc->cy;
650 sc1->cz = sc->cz;
651 memcpy(sc1->view,sc->view,sizeof(struct transform));
652 memcpy(sc1->persp,sc->persp,sizeof(struct sperspective));
653 glutSetWindow(sc1->idwin);
654 reshapeScene(sc1->par.xs,sc1->par.ys);
655 }
656 glutSetWindow(sc->idwin);
657 break;
658 case 'W':
659 keyFile('W',0,0);
660 break;
661 case 'X': /* close window */
662 if ( cube->active & C_EDIT ) {
663 cube->cma[0] -= 0.1*sc->dmax;
664 post = TRUE;
665 break;
666 }
667 if ( idw != cv.nbs ) {
668 deleteScene(sc);
669 for (k=idw+1; k<cv.nbs; k++)
670 cv.scene[k-1] = cv.scene[k];
671 cv.scene[cv.nbs-1] = 0;
672 }
673 glutHideWindow();
674 if ( --cv.nbs == 0 ) exit(0);
675 break;
676
677 case 'Y': /* close window */
678 if ( cube->active & C_EDIT ) {
679 cube->cma[1] -= 0.1*sc->dmax;
680 post = TRUE;
681 break;
682 }
683 case 'Z': /* zoom out */
684 if ( cube->active & C_EDIT ) {
685 cube->cma[2] -= 0.1*sc->dmax;
686 post = TRUE;
687 break;
688 }
689 else {
690 if ( p->rubber == 2 )
691 setPersp(sc,p,0);
692 else
693 p->fovy = min(1.1*p->fovy,179.0);
694 farclip(1);
695 }
696 post = TRUE;
697
698 /* get linked view */
699 sc1 = sc;
700 while ( sc1->slave > -1 ) {
701 sc1 = cv.scene[sc1->slave];
702 memcpy(sc1->view,sc->view,sizeof(struct transform));
703 memcpy(sc1->persp,sc->persp,sizeof(struct sperspective));
704 glutSetWindow(sc1->idwin);
705 reshapeScene(sc1->par.xs,sc1->par.ys);
706 }
707 glutSetWindow(sc->idwin);
708 break;
709 }
710 }
711
712 else {
713 switch (key) {
714 case '-':
715 if (keyact & GLUT_ACTIVE_ALT ) {
716 keyAnim('p',0,0);
717 break;
718 }
719 if ( cube->active & C_EDIT ) {
720 cube->cma[0] *= 0.95;
721 cube->cma[1] *= 0.95;
722 cube->cma[2] *= 0.95;
723 post = TRUE;
724 break;
725 }
726 if ( sc->persp->pmode == CAMERA ) {
727 cam = sc->camera;
728 cam->spmod -= 1.e-04 * sc->dmax;
729 post = TRUE;
730 break;
731 }
732 if ( p->depth < -20.0*sc->dmax ) break;
733 p->depth -= 0.1*sc->dmax;
734 farclip(1);
735 post = TRUE;
736
737 /*
738 if ( p->rubber == 2 )
739 setPersp(sc,p,0);
740 else
741 p->fovy = min(1.1*p->fovy,179.0);
742 farclip(1);
743 post = TRUE;
744 */
745 /* get linked view */
746 sc1 = sc;
747 while ( sc1->slave > -1 ) {
748 sc1 = cv.scene[sc1->slave];
749 memcpy(sc1->view,sc->view,sizeof(struct transform));
750 memcpy(sc1->persp,sc->persp,sizeof(struct sperspective));
751 glutSetWindow(sc1->idwin);
752 reshapeScene(sc1->par.xs,sc1->par.ys);
753 }
754 glutSetWindow(sc->idwin);
755 break;
756
757 case '+':
758 if (keyact & GLUT_ACTIVE_ALT ) {
759 keyAnim('n',0,0);
760 break;
761 }
762 if ( cube->active & C_EDIT ) {
763 cube->cma[0] *= 1.05;
764 cube->cma[1] *= 1.05;
765 cube->cma[2] *= 1.05;
766 post = TRUE;
767 break;
768 }
769 if ( sc->persp->pmode == CAMERA ) {
770 cam = sc->camera;
771 cam->spmod += 1.e-04 * sc->dmax;
772 post = TRUE;
773 break;
774 }
775 if ( p->depth > 0.0 ) break;
776 p->depth += 0.1*sc->dmax;
777 farclip(1);
778 post = TRUE;
779
780 /*
781 if ( p->rubber == 2 )
782 setPersp(sc,p,1);
783 else
784 p->fovy = max(0.9*p->fovy,1e-05);
785 farclip(1);
786 post = TRUE;
787 */
788 /* update linked view */
789 sc1 = sc;
790 while ( sc1->slave > -1 ) {
791 sc1 = cv.scene[sc1->slave];
792 memcpy(sc1->view,sc->view,sizeof(struct transform));
793 memcpy(sc1->camera,sc->camera,sizeof(struct camera));
794 memcpy(sc1->persp,sc->persp,sizeof(struct sperspective));
795 glutSetWindow(sc1->idwin);
796 reshapeScene(sc1->par.xs,sc1->par.ys);
797 }
798 glutSetWindow(sc->idwin);
799 break;
800
801 case '#': /* select entity */
802 fprintf(stdout,"ENTITY NUMBER: "); fflush(stdout);
803 fflush(stdin); fscanf(stdin,"%d",&numit);
804 if ( sc->picklist ) glDeleteLists(sc->picklist,1);
805 if ( numit > 0 )
806 sc->picklist = pickItem(mesh,sc,numit);
807 post = TRUE;
808 break;
809 case '!': /* clip plane */
810 if ( !(clip->active & C_ON) ) return;
811 dd = clip->eqn[3]-clip->eqn[0]*mesh->xtra \
812 - clip->eqn[1]*mesh->ytra-clip->eqn[2]*mesh->ztra;
813 fprintf(stdout,"\nCurrent plane: %gx %+gy %+gz %+g = 0\n",
814 clip->eqn[0],clip->eqn[1],clip->eqn[2],dd);
815 fprintf(stdout,"Plane coeffs : "); fflush(stdout);
816 fflush(stdin); fscanf(stdin,"%f %f %f %f",&a,&b,&c,&d);
817 resetClip(sc,clip,mesh);
818 clip->eqn[0] = a;
819 clip->eqn[1] = b;
820 clip->eqn[2] = c;
821 clip->eqn[3] = d;
822
823 fprintf(stdout,"New plane eq.: ");
824 if ( clip->eqn[0] )
825 fprintf(stdout,"%+gx",clip->eqn[0]);
826 if ( clip->eqn[1] )
827 fprintf(stdout," %+gy",clip->eqn[1]);
828 if ( clip->eqn[2] )
829 fprintf(stdout," %+gz",clip->eqn[2]);
830 if ( clip->eqn[3] )
831 fprintf(stdout," %+g",clip->eqn[3]);
832 fprintf(stdout," = 0\n");
833 clip->eqn[3] += (a*mesh->xtra+b*mesh->ytra+c*mesh->ztra);
834 post = TRUE;
835 dolist = TRUE;
836 break;
837
838 case '@': /* add trajectoire point */
839 if ( p->pmode == CAMERA )
840 pathAdd(sc,x,y);
841 break;
842
843 case '%':
844 fprintf(stdout,"reference (%d): ",refpick); fflush(stdout);
845 fflush(stdin);
846 fscanf(stdin,"%d",&refpick);
847 break;
848
849 case '&':
850 puts("ADJUST");
851 parEdit(sc);
852 break;
853 }
854 }
855
856 if ( dolist ) {
857 doLists(sc,mesh);
858 doMapLists(sc,mesh,1);
859 doIsoLists(sc,mesh,1);
860 }
861 if ( post ) glutPostRedisplay();
862 }
863
864