Back to index

radiance  4R0+20100331
xshowtrace.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: xshowtrace.c,v 2.12 2005/07/30 22:02:29 greg Exp $";
00003 #endif
00004 /*
00005  *  Display an image and watch the rays get traced.
00006  *
00007  *     9/21/90       Greg Ward
00008  */
00009 
00010 #include <X11/Xlib.h>
00011 
00012 #include "standard.h"
00013 #include "paths.h"
00014 #include "view.h"
00015 
00016 #define MAXDEPTH     32            /* ridiculous ray tree depth */
00017 
00018 #ifdef  SMLFLT
00019 #define  sscanvec(s,v)      (sscanf(s,"%f %f %f",v,v+1,v+2)==3)
00020 #else
00021 #define  sscanvec(s,v)      (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3)
00022 #endif
00023 
00024 char   rtcom[64] = "rtrace -h- -otp -fa -x 1";
00025 char   xicom[] = "ximage -c 256";
00026 
00027 VIEW   ourview = STDVIEW;          /* view for picture */
00028 RESOLU ourres;                            /* picture resolution */
00029 
00030 char   *progname;                  /* program name */
00031 
00032 char   *picture;                   /* picture name */
00033 
00034 FILE   *pin;                       /* input stream */
00035 
00036 Display       *theDisplay = NULL;         /* connection to server */
00037 
00038 struct node {                      /* ray tree node */
00039        int    ipt[2];
00040        struct node   *sister;
00041        struct node   *daughter;
00042 };
00043 
00044 #define newnode()    (struct node *)calloc(1, sizeof(struct node))
00045 
00046 int    slow = 0;            /* slow trace? */
00047 
00048 void mainloop(void);
00049 static void freetree(struct node   *tp);
00050 static void tracerays(struct node  *tp);
00051 static int strtoipt(int     ipt[2], char  *str);
00052 static void setvec(int      ipt[2]);
00053 static void vector(int      ip1[2], int   ip2[2]);
00054 
00055 
00056 int
00057 main(         /* takes both the octree and the image */
00058        int    argc,
00059        char   *argv[]
00060 )
00061 {
00062        int    i;
00063        char   combuf[PATH_MAX];
00064 
00065        progname = argv[0];
00066        for (i = 1; i < argc-2; i++)
00067               if (!strcmp(argv[i], "-s"))
00068                      slow++;
00069               else if (!strcmp(argv[i], "-T"))
00070                      strcat(rtcom, " -oTp");
00071               else
00072                      break;
00073        if (i > argc-2) {
00074               fprintf(stderr, "Usage: %s [-s][-T] [rtrace args] octree picture\n",
00075                             progname);
00076               exit(1);
00077        }
00078        picture = argv[argc-1];
00079                                    /* get the viewing parameters */
00080        if (viewfile(picture, &ourview, &ourres) <= 0 ||
00081                      setview(&ourview) != NULL) {
00082               fprintf(stderr, "%s: cannot get view from \"%s\"\n",
00083                             progname, picture);
00084               exit(1);
00085        }
00086                                    /* open the display */
00087        if ((theDisplay = XOpenDisplay(NULL)) == NULL) {
00088               fprintf(stderr,
00089               "%s: cannot open display; DISPLAY variable set?\n",
00090                             progname);
00091               exit(1);
00092        }
00093                                    /* build input command */
00094        sprintf(combuf, "%s \"%s\" | %s", xicom, picture, rtcom);
00095        for ( ; i < argc-1; i++) {
00096               strcat(combuf, " ");
00097               strcat(combuf, argv[i]);
00098        }
00099                                    /* start the damn thing */
00100        if ((pin = popen(combuf, "r")) == NULL)
00101               exit(1);
00102                                    /* loop on input */
00103        mainloop();
00104                                    /* close pipe and exit */
00105        pclose(pin);
00106        exit(0);
00107 }
00108 
00109 
00110 void
00111 mainloop(void)                            /* get and process input */
00112 {
00113        static struct node   *sis[MAXDEPTH];
00114        register struct node *newp;
00115        char   buf[128];
00116        int    level;
00117        register int  i;
00118 
00119        level = 0;
00120        while (fgets(buf, sizeof(buf), pin) != NULL) {
00121               if ((newp = newnode()) == NULL) {
00122                      fprintf(stderr, "%s: memory error\n", progname);
00123                      return;
00124               }
00125               for (i = 0; buf[i] == '\t'; i++)
00126                      ;
00127               if (strtoipt(newp->ipt, buf+i) < 0) {
00128                      fprintf(stderr, "%s: bad read\n", progname);
00129                      return;
00130               }
00131               newp->sister = sis[i];
00132               sis[i] = newp;
00133               if (i < level) {
00134                      newp->daughter = sis[level];
00135                      sis[level] = NULL;
00136               }
00137               level = i;
00138               if (i == 0) {
00139                      setvec(sis[0]->ipt);
00140                      tracerays(sis[0]);
00141                      freetree(sis[0]);
00142                      sis[0] = NULL;
00143                      if (!slow)
00144                             XFlush(theDisplay);
00145               }
00146        }
00147 }
00148 
00149 
00150 static void
00151 freetree(                          /* free a trace tree */
00152        struct node   *tp
00153 )
00154 {
00155        register struct node *kid, *k2;
00156 
00157        for (kid = tp->daughter; kid != NULL; kid = k2) {
00158               k2 = kid->sister;
00159               freetree(kid);
00160        }
00161        free((void *)tp);
00162 }
00163 
00164 
00165 static void
00166 tracerays(                         /* trace a ray tree */
00167        struct node   *tp
00168 )
00169 {
00170        register struct node *kid;
00171 
00172        for (kid = tp->daughter; kid != NULL; kid = kid->sister) {
00173               vector(tp->ipt, kid->ipt);
00174               tracerays(kid);
00175        }
00176 }
00177 
00178 
00179 static int
00180 strtoipt(            /* convert string x y z to image point */
00181        int    ipt[2],
00182        char   *str
00183 )
00184 {
00185        FVECT  im_pt, pt;
00186 
00187        if (!sscanvec(str, pt))
00188               return(-1);
00189        if (DOT(pt,pt) <= FTINY)           /* origin is really infinity */
00190               ipt[0] = ipt[1] = -1;                     /* null vector */
00191        else {
00192               viewloc(im_pt, &ourview, pt);
00193               loc2pix(ipt, &ourres, im_pt[0], im_pt[1]);
00194        }
00195        return(0);
00196 }
00197 
00198 
00199 #define rwind        RootWindow(theDisplay,ourScreen)
00200 #define ourScreen    DefaultScreen(theDisplay)
00201 
00202 GC     vecGC = 0;
00203 Window gwind = 0;
00204 int    xoff, yoff;
00205 
00206 
00207 static void
00208 setvec(                     /* set up vector drawing for pick */
00209        int    ipt[2]
00210 )
00211 {
00212        extern Window xfindwind();
00213        XWindowAttributes    wa;
00214        XColor xc;
00215        XGCValues     gcv;
00216        int    rx, ry, wx, wy;
00217        Window rw, cw;
00218        unsigned int  pm;
00219                                    /* compute pointer location */
00220        if (gwind == 0) {
00221               register char *wn;
00222               for (wn = picture; *wn; wn++);
00223               while (wn > picture && wn[-1] != '/') wn--;
00224               if ((gwind = xfindwind(theDisplay, rwind, wn, 4)) == 0) {
00225                      fprintf(stderr, "%s: cannot find display window!\n",
00226                                    progname);
00227                      exit(1);
00228               }
00229        }
00230        XQueryPointer(theDisplay, gwind, &rw, &cw, &rx, &ry, &wx, &wy, &pm);
00231        xoff = wx - ipt[0];
00232        yoff = wy - ipt[1];
00233                                    /* set graphics context */
00234        if (vecGC == 0) {
00235               XGetWindowAttributes(theDisplay, gwind, &wa);
00236               xc.red = 65535; xc.green = 0; xc.blue = 0;
00237               xc.flags = DoRed|DoGreen|DoBlue;
00238               if (XAllocColor(theDisplay, wa.colormap, &xc)) {
00239                      gcv.foreground = xc.pixel;
00240                      vecGC = XCreateGC(theDisplay,gwind,GCForeground,&gcv);
00241               } else {
00242                      gcv.function = GXinvert;
00243                      vecGC = XCreateGC(theDisplay,gwind,GCFunction,&gcv);
00244               }
00245        }
00246 }
00247 
00248 
00249 static void
00250 vector(              /* draw a vector */
00251        int    ip1[2],
00252        int    ip2[2]
00253 )
00254 {
00255        if (ip2[0] == -1 && ip2[1] == -1)
00256               return;                     /* null vector */
00257        XDrawLine(theDisplay, gwind, vecGC,
00258                      ip1[0]+xoff, ip1[1]+yoff,
00259                      ip2[0]+xoff, ip2[1]+yoff);
00260        if (slow) {
00261               XFlush(theDisplay);
00262               sleep(1);
00263        }
00264 }