Make the axis appears before the curve surface shows up.
[dyninst.git] / visiClients / terrain / src / colorize.c
1 /*
2  * Copyright (c) 1989, 1990 Barton P. Miller, Morgan Clark, Timothy Torzewski
3  *     Jeff Hollingsworth, and Bruce Irvin. All rights reserved.
4  *
5  * This software is furnished under the condition that it may not
6  * be provided or otherwise made available to, or used by, any
7  * other person.  No title to or ownership of the software is
8  * hereby transferred.  The name of the principals
9  * may not be used in any advertising or publicity related to this
10  * software without specific, written prior authorization.
11  * Any use of this software must include the above copyright notice.
12  *
13  */
14
15 #ifndef lint
16 static char Copyright[] = "@(#) Copyright (c) 1989, 1990 Barton P. Miller,\
17  Morgan Clark, Timothy Torzewski, Jeff Hollingsworth, and Bruce Irvin.\
18  All rights reserved.";
19
20 static char rcsid[] = "@(#) $Header: /home/jaw/CVSROOT_20081103/CVSROOT/core/visiClients/terrain/src/colorize.c,v 1.2 1997/05/19 19:43:02 tung Exp $";
21 #endif
22
23 /*
24  * colorize.c - colorize surfaces according to their height.
25  *
26  * $Log: colorize.c,v $
27  * Revision 1.2  1997/05/19 19:43:02  tung
28  * Make the axis appears before the curve surface shows up.
29  *
30  * Revision 1.1  1997/05/12 20:15:22  naim
31  * Adding "Terrain" visualization to paradyn (commited by naim, done by tung).
32  *
33  * Revision 1.1  1992/05/19  06:30:55  lam
34  * Initial revision
35  *
36  *
37  */
38
39 #include <stdio.h>
40 #include <string.h>
41    
42 #include "misc.h"
43 #include "terrain.h"
44    
45 #define TRUE    1
46 #define FALSE   0
47
48 /* Internal representation of polygon -- a linked list of points */
49
50 struct ptLstNode_t {
51    float x,y,z;
52    struct ptLstNode_t *next;
53 };
54
55 typedef struct ptLstNode_t *ptLst_t;
56
57 /* The z-tic list -- map height (z coord) to colors */
58
59 struct ticNode_t {
60    float z;
61    int color;
62    struct ticNode_t *next;
63 };
64
65 typedef struct ticNode_t *ticLst_t;
66
67 ptLst_t findGoUnder();
68 ptLst_t findGoAbove();
69 ptLst_t makeMidPt();
70 ptLst_t copyPt();
71
72
73 extern float zmin, zmax;        /* Max & min points of the graph */
74 extern int Ntcolors;            /* Number of colors available */
75
76 static int pix = 0;
77
78 /*******************************************************************
79 * draw_colorPoly - Draw a colorized polygon.
80 *
81 * draw_colorPoly takes 4 points and draw it with colors.  The colors
82 * used are determined by the z dimension of the polygon the the z-tics.
83 * If the polygon run accross more than one z-tics, the polygon will
84 * be cut up and assigned with diffrernt colors.
85 *
86 *******************************************************************/
87
88 draw_colorPoly(x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4, remap, pix_map)
89 float x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4;
90 int remap;
91 int pix_map;
92 {
93    static ticLst_t tics=NULL;
94    ticLst_t curTic;
95    ptLst_t drawLst, curPt;
96    
97    int i;
98    float curZ, ticSize;
99
100    /* Initialize the tic list (mapping between z and colors if that */
101    /* has not been done yet or there is change in maxz.             */
102
103    if (remap == -1 && tics != NULL)
104    {
105       for (i = 0; tics->next != NULL; tics = tics->next)
106           free(tics);
107
108       free(tics);
109       tics = NULL;
110    }
111       
112    if (tics==NULL) {
113       curTic = tics = (ticLst_t) terrain_alloc(sizeof(struct ticNode_t));
114        
115       curZ = zmin;
116       ticSize = (zmax - zmin)/Ntcolors;
117       for (i=0; i<Ntcolors - 1; i++) {
118          curTic->z = curZ+=ticSize;
119          curTic->color = i;
120          curTic->next = (ticLst_t) terrain_alloc(sizeof(struct ticNode_t));
121          curTic = curTic->next;
122       }
123       curTic->z = curZ+=ticSize;
124       curTic->color = i;
125       curTic->next = NULL;
126    }
127    
128 #ifdef COLORIZE_DEBUG
129    
130    printf("(%1.2lf %1.2lf %1.1lf)-(%1.2lf %1.2lf %1.1lf)-(%1.2lf %1.2lf %1.1lf)-(%1.2lf %1.2lf %1.1lf)\n", x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4);
131    
132 #endif
133
134    /* Convert the points into internation representation */
135
136    drawLst = (ptLst_t) terrain_alloc(sizeof(struct ptLstNode_t));
137    drawLst->x = x1;
138    drawLst->y = y1;
139    drawLst->z = z1;
140    drawLst->next = (ptLst_t) terrain_alloc(sizeof(struct ptLstNode_t));
141    
142    curPt = drawLst->next;
143
144    curPt->x = x2;
145    curPt->y = y2;
146    curPt->z = z2;
147    curPt->next = (ptLst_t) terrain_alloc(sizeof(struct ptLstNode_t));
148
149    curPt = curPt->next;
150
151    curPt->x = x3;
152    curPt->y = y3;
153    curPt->z = z3;
154    curPt->next = (ptLst_t) terrain_alloc(sizeof(struct ptLstNode_t));
155
156    curPt = curPt->next;
157
158    curPt->x = x4;
159    curPt->y = y4;
160    curPt->z = z4;
161    curPt->next = NULL;
162
163    /* set whether draw on pixmap or on actual window */
164    pix = pix_map;
165
166    /* Do the real job */
167
168    colorize(drawLst, tics);
169    
170 #ifdef COLORIZE_DEBUG
171    
172    printf("\n");
173    
174 #endif
175    
176 }
177
178
179
180 /*********************************************************************
181 *
182 * colorPoly - draw the polygon defined by "pts" with "color"
183 *             This routine calls the X driver.
184 *
185 *********************************************************************/
186
187
188 colorPoly(pts, color)
189 ptLst_t pts;
190 int color;
191 {
192    ptLst_t curPt;
193    int i, size=0;
194    unsigned *dpts;
195
196    /* Check how many points the polygon has */
197
198    for(curPt = pts; curPt->next != pts; curPt = curPt->next) {
199       
200 #ifdef COLORIZE_DEBUG
201       
202       printf("  %10.6lf %10.6lf %10.6lf -- %d\n",
203              curPt->x, curPt->y, curPt->z, color);
204       
205 #endif
206       
207       size++;
208    }
209    
210 #ifdef COLORIZE_DEBUG
211    
212    printf("     %10.6lf %10.6lf %10.6lf -- %d\n",
213           curPt->x, curPt->y, curPt->z, color);
214    
215 #endif
216    
217    size++;
218
219    dpts = (unsigned *)terrain_alloc(sizeof(unsigned)*size*2);
220    
221    for (i=0, curPt = pts; i<size; i++, curPt = curPt->next)
222       map3d_xy(curPt->x, curPt->y, curPt->z, 
223                &(dpts[i<<1]), &(dpts[(i<<1)+1]));
224    
225
226    if (pix > 0)
227       X11_colorPoly_window(dpts, size, color);
228
229       X11_colorPoly(dpts, size, color);
230
231    free(dpts);
232 }
233
234
235
236 /*********************************************************************
237 *
238 * colorize - find out the lowerest point of the polygon and start
239 *            the colorization rolling from there.
240 *
241
242 *********************************************************************/
243
244
245 colorize(pts, tics)
246 ptLst_t pts;                    /* Points of the polygon */
247 ticLst_t tics;                  /* List of all tics  */
248 {
249    ticLst_t curTic;
250    ptLst_t curPt;
251    float minZ;
252    
253    /* Search for the lowerest point */
254    curPt = pts;
255    minZ = curPt->z;
256    for (curPt = pts; curPt->next != NULL; curPt = curPt->next)
257       minZ = (curPt->next->z < minZ)? curPt->next->z : minZ;
258    
259    /* Make the list circular */
260    curPt->next = pts;
261    
262    /* Skip irrevalent tics */
263    curTic = tics;
264    while ((curTic->next != NULL) && (curTic->z <= minZ))
265       curTic = curTic->next;
266    
267    if (curTic->next == NULL)
268       colorPoly(pts, curTic->color);
269    else
270       colorizeLayers(pts, curTic);
271    
272    return;
273 }
274
275
276
277
278
279 /*********************************************************************
280 *
281 * colorizeLayers - cut the polygon into levels accroding to the z-tics,
282 *                  and draw them with colors.
283 *
284 *********************************************************************/
285
286
287 colorizeLayers(pts, tic)
288 ptLst_t pts;
289 ticLst_t tic;
290 {
291    ptLst_t curPt, startPt, goUnderPt, goAbovePt, drawPt, newPt;
292    ticLst_t curTic;
293    int done = FALSE;
294    
295    curTic = tic;
296    startPt = pts;               /* Keep the while loop happy */
297    
298    /* Start filling the surface now */
299    while((curTic->next != NULL) && (startPt != NULL)) {
300       
301       /* Find a start point */
302       if ((curPt = findGoUnder(startPt, startPt, curTic->z)) == NULL) {
303          /* All points are under the current tic */
304          colorPoly(startPt, curTic->color);
305          freePtLst(startPt);
306          startPt = NULL;
307       } else {
308          /* Calculate the real start point and add that to the list */
309          startPt = curPt;
310          if (startPt->z != curTic->z) {
311             newPt = makeMidPt(startPt, curTic->z);
312             newPt->next = startPt->next;
313             startPt->next = newPt;
314             curPt = startPt = goUnderPt = newPt;
315          } else {
316             curPt = goUnderPt = startPt;
317          }
318          
319          /* Walk through all points in that level and form sub-polygons */
320          /* Note that there can be more than one sub-polygon in one level */
321
322          done = FALSE;
323          while(!done) {
324             if ((goAbovePt = findGoAbove(curPt, startPt, curTic->z)) == NULL) {
325
326                /* Done if we run out of points */
327
328                colorPoly(startPt, curTic->color);
329                freePtLst(startPt);
330                return;
331             } else {
332
333                /* Find the end point of the sub-polygon */
334
335                if (goAbovePt->z != curTic->z) {
336                   newPt = makeMidPt(goAbovePt, curTic->z);
337                   newPt->next = goAbovePt->next;
338                   drawPt = copyPt(goUnderPt);
339                   curPt = goUnderPt->next = newPt;
340                   goAbovePt->next = copyPt(newPt);
341                   goAbovePt->next->next = drawPt;
342                } else {
343                   newPt = copyPt(goAbovePt);
344                   curPt = goAbovePt->next = newPt;
345                   drawPt = copyPt(goUnderPt);
346                   goUnderPt->next = newPt;
347                   goAbovePt->next = drawPt;
348                }
349                
350                /* Draw it ! */
351
352                colorPoly(drawPt, curTic->color);
353                freePtLst(drawPt);
354             }
355             
356             /* Search for next point under the tic and start over */
357             if ((goUnderPt = findGoUnder(curPt, startPt, curTic->z)) == NULL)
358                done = TRUE;
359             else {
360                if (goUnderPt->z != curTic->z) {
361                   newPt = makeMidPt(goUnderPt, curTic->z);
362                   newPt->next = goUnderPt->next;
363                   goUnderPt->next = newPt;
364                   curPt = goUnderPt = newPt;
365                } else {
366                   curPt = goUnderPt;
367                }
368             }
369          }
370          
371 #ifdef COLORIZE_DEBUG
372          
373          for (curPt=startPt; curPt->next!=startPt; curPt=curPt->next)
374             printf("   (%1.1lf,%1.1lf,%1.1lf)-", curPt->x, curPt->y, curPt->z);
375          
376          printf("   (%1.1lf,%1.1lf,%1.1lf)\n", curPt->x, curPt->y, curPt->z);
377          
378 #endif
379          
380       }
381       
382       curTic = curTic->next;
383    }
384    
385    /* If there are remaining points, they must be above all the tics */
386    if (startPt != NULL) {
387       colorPoly(startPt, curTic->color);
388       freePtLst(startPt);
389    }
390    
391    return;
392 }
393
394
395
396
397 /*********************************************************************
398 *
399 * findGoUnder - walk along the current sub-polygon and find a coordinate
400 *               which has the z coordinate value of "z" and its last point
401 *               is above the surface z and its next point below z.
402 *               Note that the point may not be a existing point.  It can
403 *               be somewhere between the existing points.
404 *
405 * Returns:
406 *    ptLst_t : The new point found.
407 *              NULL means all points of the current sun-polygon are
408 *              above z.
409 *
410 *********************************************************************/
411
412
413 ptLst_t
414 findGoUnder(startPt, endPt, z)
415 ptLst_t startPt, endPt;         /* Range of the search */
416 float z;                        /* the z coordinate of the new point */
417 {
418    ptLst_t curPt;
419    
420 #ifdef COLORIZE_DEBUG
421    printf("V          ");
422    
423    for (curPt=startPt; curPt->next!=startPt; curPt=curPt->next) {
424       if (curPt==endPt)
425          printf("[%1.1lf,%1.1lf,%1.1lf]-", curPt->x, curPt->y, curPt->z);
426       else
427          printf("(%1.1lf,%1.1lf,%1.1lf)-", curPt->x, curPt->y, curPt->z);
428    }
429    
430    if (curPt==endPt)
431       printf("[%1.1lf,%1.1lf,%1.1lf]\n", curPt->x, curPt->y, curPt->z);
432    else
433       printf("(%1.1lf,%1.1lf,%1.1lf)\n", curPt->x, curPt->y, curPt->z);
434    
435 #endif
436    
437    if (startPt->z >= z && startPt->next->z < z) {
438       
439 #ifdef COLORIZE_DEBUG
440       
441       printf("V            %1.1lf >= %1.1lf, %1.1lf < %1.1lf\n",
442              startPt->z, z, startPt->next->z, z);
443       
444 #endif
445       
446       return startPt;
447    }
448    
449    for (curPt=startPt->next;
450         (curPt != endPt) && !(curPt->z >= z && curPt->next->z < z);
451         curPt = curPt->next)
452       
453 #ifdef COLORIZE_DEBUG
454       
455       printf("V            %1.1lf >= %1.1lf, %1.1lf < %1.1lf\n",
456              curPt->z, z, curPt->next->z, z);
457    
458    printf("V            The anser is : %c\n", (curPt != endPt)?'T':'F');
459    
460 #else
461    ;
462 #endif
463    
464    return (curPt != endPt)? curPt : NULL;
465 }
466
467
468
469
470 /*********************************************************************
471 *
472 * findGoAbove - walk along the current sub-polygon and find a coordinate
473 *               which has the z coordinate value of "z" and its last point
474 *               is below the surface z and its next point is above z.
475 *               Note that the point may not be a existing point.  It can
476 *               be somewhere between the existing points.
477 *
478 * Returns:
479 *    ptLst_t : The new point found.
480 *              NULL means all points of the current sun-polygon are
481 *              above z.
482 *
483 *********************************************************************/
484
485
486 ptLst_t
487 findGoAbove(startPt, endPt, z)
488 ptLst_t startPt, endPt;         /* Start & end pts of the current polygon */
489 float z;                        /* The z coordinate value to be tested */
490 {
491    ptLst_t curPt;
492    
493 #ifdef COLORIZE_DEBUG
494    printf("^          ");
495    
496    for (curPt=startPt; curPt->next!=startPt; curPt=curPt->next) {
497       if (curPt==endPt)
498          printf("[%1.1lf,%1.1lf,%1.1lf]-", curPt->x, curPt->y, curPt->z);
499       else
500          printf("(%1.1lf,%1.1lf,%1.1lf)-", curPt->x, curPt->y, curPt->z);
501    }
502    
503    if (curPt==endPt)
504       printf("[%1.1lf,%1.1lf,%1.1lf]\n", curPt->x, curPt->y, curPt->z);
505    else
506       printf("(%1.1lf,%1.1lf,%1.1lf)\n", curPt->x, curPt->y, curPt->z);
507    
508 #endif
509    
510    if (startPt->z < z && startPt->next->z >= z)
511       return startPt;
512    
513 #ifdef COLORIZE_DEBUG
514    
515    printf("^            %1.1lf <= %1.1lf, %1.1lf > %1.1lf\n",
516           startPt->z, z, startPt->next->z, z);
517    
518 #endif
519    
520    for (curPt=startPt->next;
521         (curPt != endPt) && !(curPt->z < z && curPt->next->z >= z);
522         curPt = curPt->next)
523       
524 #ifdef COLORIZE_DEBUG
525       
526       printf("^            %1.1lf <= %1.1lf, %1.1lf > %1.1lf\n",
527              curPt->z, z, curPt->next->z, z);
528    
529    printf("^            The anser is : %c\n", (curPt != endPt)?'T':'F');
530    
531 #else
532    ;
533 #endif
534    
535    return (curPt != endPt)? curPt : NULL;
536    
537 }
538
539
540
541
542
543 /*********************************************************************
544 *
545 * makeMidPt - produce a new point which is between two given points and
546 *             with it has the value "z" as its z coordinate.
547 *             One can think of the point as the intersection between
548 *             the line pt, pts->next and a horizontal line z.
549 *
550 * Returns:
551 *    ptLst_t : The new point.
552 *
553 *********************************************************************/
554
555
556 ptLst_t
557 makeMidPt(pts, z)
558 ptLst_t pts;
559 float z;
560 {
561    ptLst_t newPt;               /* The new 'middle' point */
562    float zIndex;
563    
564    if ((newPt = (ptLst_t) terrain_alloc(sizeof(struct ptLstNode_t))) == NULL) {
565       printf("Memory allocation error\n");
566       exit(-1);
567    }
568
569    /* x & y coordinate are between pts and pts->next and weighted by z */
570    
571    zIndex = (pts->z - z)/(pts->z -  pts->next->z);
572    newPt->z = z;
573    newPt->x = pts->x + ((pts->next->x - pts->x) * zIndex);
574    newPt->y = pts->y + ((pts->next->y - pts->y) * zIndex);
575    newPt->next = NULL;
576    
577    return newPt;
578 }
579
580
581
582
583 /*********************************************************************
584 *
585 * freePtLst - Free a list of points.
586 *
587 *********************************************************************/
588
589
590 freePtLst(pts)
591 ptLst_t pts;
592 {
593    ptLst_t lastPt, curPt;
594    
595    curPt = pts;
596    while(curPt->next != pts) {
597       lastPt = curPt;
598       curPt = curPt->next;
599       free(lastPt);
600    }
601    
602    free(curPt);
603    
604    return;
605 }
606
607
608
609
610 /*********************************************************************
611 *
612 * copyPt - duplicate a point.
613 *
614 * Returns:
615 *  ptLst_t  : The new copy of the point given
616 *
617 *********************************************************************/
618
619 ptLst_t
620 copyPt(source)
621 ptLst_t source;
622 {
623    ptLst_t target;
624    
625    if ((target = (ptLst_t) terrain_alloc(sizeof(struct ptLstNode_t))) == NULL) {
626       printf("Memory allocation error.\n");
627       exit(-1);
628    }
629    
630 #ifdef BCOPY
631    bcopy(source, target, sizeof(struct ptLstNode_t));
632 #else
633    memcpy(target, source, sizeof(struct ptLstNode_t));
634 #endif
635    
636    return target;
637 }