ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/xshowtrace.c
Revision: 2.14
Committed: Tue Jun 3 21:31:51 2025 UTC (30 hours, 18 minutes ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.13: +2 -4 lines
Log Message:
refactor: More consistent use of global char * progname and fixargv0()

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: xshowtrace.c,v 2.13 2014/04/11 20:27:23 greg Exp $";
3 #endif
4 /*
5 * Display an image and watch the rays get traced.
6 *
7 * 9/21/90 Greg Ward
8 */
9
10 #include <X11/Xlib.h>
11
12 #include "standard.h"
13 #include "paths.h"
14 #include "view.h"
15
16 #define MAXDEPTH 32 /* ridiculous ray tree depth */
17
18 #define sscanvec(s,v) (sscanf(s,FVFORMAT,v,v+1,v+2)==3)
19
20 char rtcom[64] = "rtrace -h- -otp -fa -x 1";
21 char xicom[] = "ximage -c 256";
22
23 VIEW ourview = STDVIEW; /* view for picture */
24 RESOLU ourres; /* picture resolution */
25
26 char *picture; /* picture name */
27
28 FILE *pin; /* input stream */
29
30 Display *theDisplay = NULL; /* connection to server */
31
32 struct node { /* ray tree node */
33 int ipt[2];
34 struct node *sister;
35 struct node *daughter;
36 };
37
38 #define newnode() (struct node *)calloc(1, sizeof(struct node))
39
40 int slow = 0; /* slow trace? */
41
42 void mainloop(void);
43 static void freetree(struct node *tp);
44 static void tracerays(struct node *tp);
45 static int strtoipt(int ipt[2], char *str);
46 static void setvec(int ipt[2]);
47 static void vector(int ip1[2], int ip2[2]);
48
49
50 int
51 main( /* takes both the octree and the image */
52 int argc,
53 char *argv[]
54 )
55 {
56 int i;
57 char combuf[PATH_MAX];
58
59 fixargv0(argv[0]); /* sets global progname */
60 for (i = 1; i < argc-2; i++)
61 if (!strcmp(argv[i], "-s"))
62 slow++;
63 else if (!strcmp(argv[i], "-T"))
64 strcat(rtcom, " -oTp");
65 else
66 break;
67 if (i > argc-2) {
68 fprintf(stderr, "Usage: %s [-s][-T] [rtrace args] octree picture\n",
69 progname);
70 exit(1);
71 }
72 picture = argv[argc-1];
73 /* get the viewing parameters */
74 if (viewfile(picture, &ourview, &ourres) <= 0 ||
75 setview(&ourview) != NULL) {
76 fprintf(stderr, "%s: cannot get view from \"%s\"\n",
77 progname, picture);
78 exit(1);
79 }
80 /* open the display */
81 if ((theDisplay = XOpenDisplay(NULL)) == NULL) {
82 fprintf(stderr,
83 "%s: cannot open display; DISPLAY variable set?\n",
84 progname);
85 exit(1);
86 }
87 /* build input command */
88 sprintf(combuf, "%s \"%s\" | %s", xicom, picture, rtcom);
89 for ( ; i < argc-1; i++) {
90 strcat(combuf, " ");
91 strcat(combuf, argv[i]);
92 }
93 /* start the damn thing */
94 if ((pin = popen(combuf, "r")) == NULL)
95 exit(1);
96 /* loop on input */
97 mainloop();
98 /* close pipe and exit */
99 pclose(pin);
100 exit(0);
101 }
102
103
104 void
105 mainloop(void) /* get and process input */
106 {
107 static struct node *sis[MAXDEPTH];
108 register struct node *newp;
109 char buf[128];
110 int level;
111 register int i;
112
113 level = 0;
114 while (fgets(buf, sizeof(buf), pin) != NULL) {
115 if ((newp = newnode()) == NULL) {
116 fprintf(stderr, "%s: memory error\n", progname);
117 return;
118 }
119 for (i = 0; buf[i] == '\t'; i++)
120 ;
121 if (strtoipt(newp->ipt, buf+i) < 0) {
122 fprintf(stderr, "%s: bad read\n", progname);
123 return;
124 }
125 newp->sister = sis[i];
126 sis[i] = newp;
127 if (i < level) {
128 newp->daughter = sis[level];
129 sis[level] = NULL;
130 }
131 level = i;
132 if (i == 0) {
133 setvec(sis[0]->ipt);
134 tracerays(sis[0]);
135 freetree(sis[0]);
136 sis[0] = NULL;
137 if (!slow)
138 XFlush(theDisplay);
139 }
140 }
141 }
142
143
144 static void
145 freetree( /* free a trace tree */
146 struct node *tp
147 )
148 {
149 register struct node *kid, *k2;
150
151 for (kid = tp->daughter; kid != NULL; kid = k2) {
152 k2 = kid->sister;
153 freetree(kid);
154 }
155 free((void *)tp);
156 }
157
158
159 static void
160 tracerays( /* trace a ray tree */
161 struct node *tp
162 )
163 {
164 register struct node *kid;
165
166 for (kid = tp->daughter; kid != NULL; kid = kid->sister) {
167 vector(tp->ipt, kid->ipt);
168 tracerays(kid);
169 }
170 }
171
172
173 static int
174 strtoipt( /* convert string x y z to image point */
175 int ipt[2],
176 char *str
177 )
178 {
179 FVECT im_pt, pt;
180
181 if (!sscanvec(str, pt))
182 return(-1);
183 if (DOT(pt,pt) <= FTINY) /* origin is really infinity */
184 ipt[0] = ipt[1] = -1; /* null vector */
185 else {
186 viewloc(im_pt, &ourview, pt);
187 loc2pix(ipt, &ourres, im_pt[0], im_pt[1]);
188 }
189 return(0);
190 }
191
192
193 #define rwind RootWindow(theDisplay,ourScreen)
194 #define ourScreen DefaultScreen(theDisplay)
195
196 GC vecGC = 0;
197 Window gwind = 0;
198 int xoff, yoff;
199
200
201 static void
202 setvec( /* set up vector drawing for pick */
203 int ipt[2]
204 )
205 {
206 extern Window xfindwind();
207 XWindowAttributes wa;
208 XColor xc;
209 XGCValues gcv;
210 int rx, ry, wx, wy;
211 Window rw, cw;
212 unsigned int pm;
213 /* compute pointer location */
214 if (gwind == 0) {
215 register char *wn;
216 for (wn = picture; *wn; wn++);
217 while (wn > picture && wn[-1] != '/') wn--;
218 if ((gwind = xfindwind(theDisplay, rwind, wn, 4)) == 0) {
219 fprintf(stderr, "%s: cannot find display window!\n",
220 progname);
221 exit(1);
222 }
223 }
224 XQueryPointer(theDisplay, gwind, &rw, &cw, &rx, &ry, &wx, &wy, &pm);
225 xoff = wx - ipt[0];
226 yoff = wy - ipt[1];
227 /* set graphics context */
228 if (vecGC == 0) {
229 XGetWindowAttributes(theDisplay, gwind, &wa);
230 xc.red = 65535; xc.green = 0; xc.blue = 0;
231 xc.flags = DoRed|DoGreen|DoBlue;
232 if (XAllocColor(theDisplay, wa.colormap, &xc)) {
233 gcv.foreground = xc.pixel;
234 vecGC = XCreateGC(theDisplay,gwind,GCForeground,&gcv);
235 } else {
236 gcv.function = GXinvert;
237 vecGC = XCreateGC(theDisplay,gwind,GCFunction,&gcv);
238 }
239 }
240 }
241
242
243 static void
244 vector( /* draw a vector */
245 int ip1[2],
246 int ip2[2]
247 )
248 {
249 if (ip2[0] == -1 && ip2[1] == -1)
250 return; /* null vector */
251 XDrawLine(theDisplay, gwind, vecGC,
252 ip1[0]+xoff, ip1[1]+yoff,
253 ip2[0]+xoff, ip2[1]+yoff);
254 if (slow) {
255 XFlush(theDisplay);
256 sleep(1);
257 }
258 }