ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/pictool.c
Revision: 2.1
Committed: Wed Aug 12 23:07:59 2015 UTC (8 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Added Jan Wienold's evalglare to distribution

File Contents

# User Rev Content
1 greg 2.1 #include "pictool.h"
2     #include "g3sphere.h"
3     #include <math.h>
4     #include <string.h>
5    
6     #define index strchr
7    
8    
9    
10     int pict_init(pict* p)
11     {
12     p->pic = NULL;
13     p->use_lut = 0;
14     p->lut = NULL;
15     p->pjitter = 0;
16     p->comment[0] = '\0';
17     #ifdef PICT_GLARE
18     p->pinfo = NULL;
19     p->glareinfo = g3fl_create(PICT_GLSIZE);
20     #endif
21     p->valid_view = 1;
22     p->view = stdview;
23     if (!pict_update_view(p))
24     return 0;
25     p->resol.rt = PIXSTANDARD;
26     return pict_resize(p,512,512);
27     }
28    
29     void pict_new_gli(pict* p)
30     {
31     int i;
32    
33     g3Float* gli;
34     gli = g3fl_append_new(p->glareinfo);
35     for(i=0;i<PICT_GLSIZE;i++)
36     gli[i] = 0.0;
37     }
38    
39     void pict_set_comment(pict* p,const char* c)
40     {
41     strcpy(p->comment,c);
42     }
43    
44     pict* pict_get_copy(pict* p)
45     {
46     pict* res;
47    
48     if (p->use_lut) {
49     fprintf(stderr,"pict_get_copy: can't copy in lut mode");
50     return NULL;
51     }
52     res = pict_create();
53     pict_resize(res,pict_get_xsize(p),pict_get_ysize(p));
54     res->view = p->view;
55     res->resol = p->resol;
56     res->pjitter = p->pjitter;
57     return res;
58     }
59    
60     pict* pict_create()
61     {
62     pict* p = (pict*) malloc(sizeof(pict));
63    
64     if (!pict_init(p)) {
65     pict_free(p);
66     return NULL;
67     }
68     return p;
69     }
70    
71     void pict_free(pict* p)
72     {
73     if (p->pic)
74     free(p->pic);
75     #ifdef PICT_GLARE
76     if (p->pinfo)
77     free(p->pinfo);
78     g3fl_free(p->glareinfo);
79     p->pinfo = NULL;
80     #endif
81     p->pic = NULL;
82     p->lut = NULL;
83     free(p);
84     }
85     static int exp_headline(char* s,void* exparg) {
86     double* exposure;
87    
88     exposure = (double*) exparg;
89     if (isexpos(s)) {
90     (*exposure) *= exposval(s);
91     }
92     return 0;
93     }
94    
95     static double read_exposure(FILE* fp)
96     {
97     double exposure = 1;
98    
99    
100     if ((getheader(fp, exp_headline, &exposure)) < 0) {
101     fprintf(stderr,"error reading header\n");
102     return 0;
103     }
104     return exposure;
105     }
106    
107     int pict_update_view(pict* p)
108     {
109     char* ret;
110     if ((ret = setview(&(p->view)))) {
111     fprintf(stderr,"pict_update_view: %s\n",ret);
112     return 0;
113     }
114     return 1;
115     }
116    
117     int pict_set_pj(pict* p,double pj)
118     {
119     if ((pj < 0) || (pj > 1))
120     fprintf(stderr,"pict_set_pj: warning jitter factor out of range\n");
121     p->pjitter = pj;
122     return 1;
123     }
124    
125     int pict_setvup(pict* p,FVECT vup)
126     {
127     VCOPY(p->view.vup,vup);
128     return pict_update_view(p);
129     }
130    
131     int pict_trans_cam(pict* p,g3ATrans t)
132     {
133     g3Vec o = g3v_create();
134     g3Vec d = g3v_create();
135     g3Vec u = g3v_create();
136    
137     fprintf(stderr,"vdpre %f %f %f\n",p->view.vdir[0],p->view.vdir[1],p->view.vdir[2]);
138     fprintf(stderr,"vupre %f %f %f\n",p->view.vup[0],p->view.vup[1],p->view.vup[2]);
139     g3v_fromrad(o,p->view.vp);
140     g3v_fromrad(d,p->view.vdir);
141     g3v_fromrad(u,p->view.vup);
142    
143     g3v_add(d,d,o);
144     g3v_add(u,u,o);
145     g3at_apply(t,o);
146     g3at_apply(t,u);
147     g3at_apply(t,d);
148     g3v_sub(d,d,o);
149     g3v_sub(u,u,o);
150     g3v_torad(p->view.vp,o);
151     g3v_torad(p->view.vdir,d);
152     g3v_torad(p->view.vup,u);
153     fprintf(stderr,"vd %f %f %f\n",p->view.vdir[0],p->view.vdir[1],p->view.vdir[2]);
154     fprintf(stderr,"vu %f %f %f\n",p->view.vup[0],p->view.vup[1],p->view.vup[2]);
155    
156     g3v_free(o);
157     g3v_free(d);
158     g3v_free(u);
159     return pict_update_view(p);
160     }
161    
162     int pict_resize(pict* p,int x,int y)
163     {
164     p->resol.xr = x;
165     p->resol.yr = y;
166    
167     if (!(p->pic = (COLOR*) realloc(p->pic,(p->resol.xr)*(p->resol.yr)*sizeof(COLOR)))) {
168     fprintf(stderr,"Can't alloc picture\n");
169     return 0;
170     }
171     if (pict_lut_used(p)) {
172     if (!(p->lut = (COLOR*) realloc(p->lut,(p->resol.xr)*(p->resol.yr)*sizeof(COLOR)))) {
173     fprintf(stderr,"Can't alloc LUT\n");
174     return 0;
175     }
176     }
177     #ifdef PICT_GLARE
178     if (!(p->pinfo = (pixinfo*)
179     realloc(p->pinfo,(p->resol.xr)*p->resol.yr*sizeof(pixinfo)))) {
180     fprintf(stderr,"Can't alloc picture info\n");
181     return 0;
182     }
183     /* fprintf(stderr,"resize %d %d %d\n",p->resol.xr,p->resol.yr,sizeof(pixinfo));*/
184     #endif
185     return 1;
186     }
187    
188    
189     int pict_zero(pict* p)
190     {
191     int x,y,i;
192    
193     for(x=0;x<pict_get_xsize(p);x++)
194     for(y=0;y<pict_get_ysize(p);y++)
195     for(i=0;i<3;i++)
196     pict_get_color(p,x,y)[i] = 0;
197     return 1;
198     }
199    
200     struct hinfo {
201     VIEW *hv;
202     int ok;
203     double exposure;
204     };
205    
206    
207     static int
208     gethinfo( /* get view from header */
209     char *s,
210     void *v
211     )
212     {
213     if (isview(s) && sscanview(((struct hinfo*)v)->hv, s) > 0) {
214     ((struct hinfo*)v)->ok++;
215     } else if (isexpos(s)) {
216     /*fprintf(stderr,"readexp %f %f\n",((struct hinfo*)v)->exposure,exposval(s));*/
217     ((struct hinfo*)v)->exposure *= exposval(s);
218     }
219     return(0);
220     }
221    
222     int pict_read_fp(pict* p,FILE* fp)
223     {
224     struct hinfo hi;
225     int x,y,yy;
226    
227    
228     hi.hv = &(p->view);
229     hi.ok = 0;
230     hi.exposure = 1;
231     getheader(fp, gethinfo, &hi);
232     /*fprintf(stderr,"expscale %f\n",hi.exposure);*/
233    
234     if (!(pict_update_view(p)) || !(hi.ok))
235     p->valid_view = 0;
236     /* printf("dir %f %f %f\n",p->view.vdir[0],p->view.vdir[1],p->view.vdir[2]); */
237     if (fgetsresolu(&(p->resol),fp) < 0) {
238     fprintf(stderr,"No resolution given\n");
239     return 0;
240     }
241     if (!(p->resol.rt & YMAJOR)) {
242     x = p->resol.xr;
243     p->resol.xr = p->resol.yr;
244     p->resol.yr = x;
245     p->resol.rt |= YMAJOR;
246     }
247     if (!pict_resize(p,p->resol.xr,p->resol.yr))
248     return 0;
249     for(yy=0;yy<p->resol.yr;yy++) {
250     y = (p->resol.rt & YDECR) ? p->resol.yr - 1 - yy : yy;
251     if (freadscan((p->pic + y*p->resol.xr),p->resol.xr,fp) < 0) {
252     fprintf(stderr,"error reading line %d\n",y);
253     return 0;
254     }
255     for(x=0;x<p->resol.xr;x++) {
256     scalecolor(pict_get_color(p,x,y),1.0/hi.exposure);
257     }
258     }
259     #ifdef PICT_GLARE
260     pict_update_evalglare_caches(p);
261     #endif
262     return 1;
263     }
264    
265     #ifdef PICT_GLARE
266     void pict_update_evalglare_caches(pict* p)
267     {
268     int x,y,yy;
269     float lum;
270     for(yy=0;yy<p->resol.yr;yy++) {
271     y = (p->resol.rt & YDECR) ? p->resol.yr - 1 - yy : yy;
272     for(x=0;x<p->resol.xr;x++) {
273     pict_get_omega(p,x,y) = pict_get_sangle(p,x,y);
274     pict_get_dir(p,x,y,pict_get_cached_dir(p,x,y));
275     pict_get_gsn(p,x,y) = 0;
276     pict_get_pgs(p,x,y) = 0;
277     /* make picture grey */
278     lum=luminance(pict_get_color(p,x,y))/179.0;
279     pict_get_color(p,x,y)[RED]=lum;
280     pict_get_color(p,x,y)[GRN]=lum;
281     pict_get_color(p,x,y)[BLU]=lum;
282     }
283     }
284     }
285    
286     #endif
287    
288     int pict_read(pict* p,char* fn)
289     {
290     FILE* fp;
291    
292     if (!(fp = fopen(fn,"rb"))) {
293     fprintf(stderr,"Can't open %s\n",fn);
294     return 0;
295     }
296     if (!(pict_read_fp(p,fp)))
297     return 0;
298     fclose(fp);
299     return 1;
300     }
301    
302     static void ch_pct(char* line)
303     {
304     char* pct;
305    
306     while ((pct = index(line,',')))
307     *pct = '.';
308     }
309    
310     char* nextline(FILE* fp)
311     {
312     static char* line = NULL;
313     static int lsize = 500;
314     int done;
315     long fpos;
316    
317     if (!line) {
318     if (!(line = (char*) malloc((lsize + 1)*sizeof(char)))) {
319     fprintf(stderr,"allocation problem in nextline\n");
320     return NULL;
321     }
322     }
323     done = 0;
324     fpos = ftell(fp);
325     while(!done) {
326     if (!fgets(line,lsize,fp))
327     return NULL;
328     if (!index(line,'\n')) {
329     lsize *= 2;
330     if (!(line = (char*) realloc(line,(lsize + 1)*sizeof(char)))) {
331     fprintf(stderr,"allocation problem in nextline\n");
332     return NULL;
333     }
334     fseek(fp,fpos,SEEK_SET);
335     } else {
336     done = 1;
337     }
338     }
339     return line;
340     }
341    
342     static int read_tt_txt(pict* p,int bufsel,int channel,char* fn)
343     {
344     FILE* fp;
345     char* line = NULL;
346     int x,y,vsize,hsize;
347     float* col;
348     float c;
349     char* curr;
350     char** endp;
351     COLOR* picbuf;
352    
353     if (!(fp = fopen(fn,"r"))) {
354     fprintf(stderr,"pict_read_tt_txt: Can't open file %s\n",fn);
355     return 0;
356     }
357     if (!(line = nextline(fp))) {
358     fprintf(stderr,"pict_read_tt_txt: reading from file failed\n");
359     return 0;
360     }
361     if (strncmp(line,"float",strlen("float"))) {
362     fprintf(stderr,"pict_read_tt_txt: Unexpected format\n");
363     return 0;
364     }
365     if (!(line = nextline(fp))) {
366     fprintf(stderr,"pict_read_tt_txt: reading from file failed\n");
367     return 0;
368     }
369     sscanf(line,"%d %d %d %d",&x,&vsize,&y,&hsize);
370     vsize = vsize - x;
371     hsize = hsize - y;
372     if (!pict_resize(p,vsize,hsize))
373     return 0;
374     endp = malloc(sizeof(char*));
375     picbuf = (bufsel == PICT_LUT) ? p->lut : p->pic;
376     for(x=0;x<vsize;x++) {
377     if (!(line = nextline(fp))) {
378     fprintf(stderr,"pict_read_tt_txt: too few lines %d of %d\n",x,vsize);
379     free(endp);
380     return 0;
381     }
382     ch_pct(line);
383     curr = line;
384     for(y=0;y<hsize;y++) {
385     col = pict_colbuf(p,picbuf,x,y);
386     c = strtod(curr,endp);
387     if (channel & PICT_CH1)
388     col[0] = c;
389     if (channel & PICT_CH2)
390     col[1] = c;
391     if (channel & PICT_CH3)
392     col[2] = c;
393     if (curr == (*endp)) {
394     fprintf(stderr,"pict_read_tt_txt: too few values in line %d\n",x);
395     free(endp);
396     return 0;
397     }
398     curr = (*endp);
399     }
400     }
401     free(endp);
402     return 1;
403     }
404    
405     int pict_read_tt_txt(pict* p,char* fn)
406     {
407     return read_tt_txt(p,PICT_VIEW,PICT_ALLCH,fn);
408     }
409    
410     int pict_setup_lut(pict* p,char* theta_fn,char* phi_fn,char* omega_fn)
411     {
412     int xs,ys;
413    
414     p->use_lut = 1;
415     if (!read_tt_txt(p,PICT_LUT,PICT_CH1,theta_fn)) {
416     fprintf(stderr,"pict_setup_lut: error reading theta file\n");
417     p->use_lut = 0;
418     return 0;
419     }
420     xs = pict_get_xsize(p);
421     ys = pict_get_ysize(p);
422     if (!read_tt_txt(p,PICT_LUT,PICT_CH2,phi_fn)) {
423     fprintf(stderr,"pict_setup_lut: error reading phi file\n");
424     p->use_lut = 0;
425     return 0;
426     }
427     if ((xs != pict_get_xsize(p)) || (ys != pict_get_ysize(p))) {
428     fprintf(stderr,"pict_setup_lut: different resolutions for lut files\n");
429     p->use_lut = 0;
430     return 0;
431     }
432     if (!read_tt_txt(p,PICT_LUT,PICT_CH3,omega_fn)) {
433     fprintf(stderr,"pict_setup_lut: error reading omega file\n");
434     p->use_lut = 0;
435     return 0;
436     }
437     if ((xs != pict_get_xsize(p)) || (ys != pict_get_ysize(p))) {
438     fprintf(stderr,"pict_setup_lut: different resolutions for lut files\n");
439     p->use_lut = 0;
440     return 0;
441     }
442     return 1;
443     }
444    
445     int pict_update_lut(pict* p)
446     {
447     g3ATrans transf;
448     g3Vec d;
449     g3Vec u;
450     int x,y;
451    
452     d = g3v_fromrad(g3v_create(),p->view.vdir);
453     u = g3v_fromrad(g3v_create(),p->view.vup);
454     g3at_ctrans(transf,d,u);
455     for(x=0;x<p->resol.xr;x++) {
456     for(y=0;y<p->resol.yr;y++) {
457     d[G3S_RAD] = 1.0;
458     d[G3S_THETA] = DEG2RAD(pict_colbuf(p,p->lut,x,y)[0]);
459     d[G3S_PHI] = DEG2RAD(pict_colbuf(p,p->lut,x,y)[1]);
460     g3s_sphtocc(d,d);
461     g3at_apply(transf,d);
462     g3s_cctosph(d,d);
463     pict_colbuf(p,p->lut,x,y)[0] = RAD2DEG(d[G3S_THETA]);
464     pict_colbuf(p,p->lut,x,y)[1] = RAD2DEG(d[G3S_PHI]);
465     }
466     }
467     g3v_free(d);
468     g3v_free(u);
469     return 1;
470     }
471    
472    
473     int pict_write_dir(pict* p,FILE* fp)
474     {
475     int x,y;
476     FVECT dir,orig;
477    
478     for(y=0;y<p->resol.yr;y++) {
479     for(x=0;x<p->resol.xr;x++) {
480     if (!(pict_get_ray(p,x,y,orig,dir))) {
481     fprintf(fp,"%f %f %f 0.0 0.0 0.0\n",orig[0],orig[1],orig[2]);
482     } else {
483     fprintf(fp,"%f %f %f %f %f %f\n",orig[0],orig[1],orig[2],dir[0],dir[1],dir[2]);
484     }
485     }
486     }
487     return 1;
488     }
489    
490     int pict_read_from_list(pict* p,FILE* fp)
491     {
492     int x,y,sz;
493     char ln[1024];
494     double val;
495    
496     sz = 0;
497     for(y=0;y<p->resol.yr;y++) {
498     for(x=0;x<p->resol.xr;x++) {
499     if (!(fgets(ln,1023,fp))) {
500     fprintf(stderr,"pict_read_from_list: Read only %d values\n",sz);
501     return 0;
502     }
503     if (sscanf(ln,"%lg",&val) != 1) {
504     fprintf(stderr,"pict_read_from_list: errline %d\n",sz);
505     } else {
506     sz++;
507     setcolor(pict_get_color(p,x,y),val,val,val);
508     }
509     }
510     }
511     return 1;
512     }
513    
514     int pict_write(pict* p,char* fn)
515     {
516     FILE* fp;
517    
518     if (!(fp = fopen(fn,"wb"))) {
519     fprintf(stderr,"Can't open %s for writing\n",fn);
520     return 0;
521     }
522     if (!(pict_write_fp(p,fp))) {
523     fclose(fp);
524     return 0;
525     }
526     fclose(fp);
527     return 1;
528     }
529    
530     int pict_write_fp(pict* p,FILE* fp)
531     {
532     char res[100];
533     int y,yy;
534     newheader("RADIANCE",fp);
535     fputnow(fp);
536     if (strlen(p->comment) > 0)
537     fputs(p->comment,fp);
538     fputs(VIEWSTR, fp);
539     fprintview(&(p->view), fp);
540     fprintf(fp,"\n");
541     fputformat(COLRFMT,fp);
542     fprintf(fp,"\n");
543    
544     resolu2str(res,&(p->resol));
545     fprintf(fp,"%s",res);
546     for(y=0;y<p->resol.yr;y++) {
547     yy = (p->resol.rt & YDECR) ? p->resol.yr - 1 - y : y;
548     if (fwritescan((p->pic + yy*p->resol.xr),p->resol.xr,fp) < 0) {
549     fprintf(stderr,"writing pic-file failed\n");
550     return 0;
551     }
552     }
553     return 1;
554     }
555    
556     int pict_get_dir(pict* p,int x,int y,FVECT dir)
557     {
558     FVECT orig;
559     if (pict_lut_used(p)) {
560     if (!(p->lut)) {
561     fprintf(stderr,"pict_get_dir: no lut defined\n");
562     return 0;
563     }
564     dir[G3S_RAD] = 1.0;
565     dir[G3S_THETA] = DEG2RAD(pict_colbuf(p,p->lut,x,y)[0]);
566     dir[G3S_PHI] = DEG2RAD(pict_colbuf(p,p->lut,x,y)[1]);
567     g3s_sphtocc(dir,dir);
568     return 1;
569     }
570     return pict_get_ray(p,x,y,orig,dir);
571     }
572    
573     int pict_get_dir_ic(pict* p,double x,double y,FVECT dir)
574     {
575     FVECT orig;
576     if (pict_lut_used(p)) {
577     int res[2];
578     loc2pix(res,&(p->resol),x,y);
579     return pict_get_dir(p,res[0],res[1],dir);
580     }
581     return pict_get_ray_ic(p,x,y,orig,dir);
582     }
583    
584     int pict_get_ray(pict* p,int x,int y,FVECT orig,FVECT dir)
585     {
586     RREAL pc[2];
587    
588     pix2loc(pc,&(p->resol),x,p->resol.yr - 1 - y);
589     if (pict_lut_used(p)) {
590     if (viewray(orig,dir,&(p->view),pc[0],pc[1]) <= 0)
591     return 0;
592     return pict_get_dir(p,x,y,dir);
593     }
594     return pict_get_ray_ic(p,pc[0],pc[1],orig,dir);
595     }
596    
597     int pict_get_ray_ic(pict* p,double x,double y,FVECT orig,FVECT dir)
598     {
599     if (pict_lut_used(p)) {
600     int res[2];
601     loc2pix(res,&(p->resol),x,y);
602     return pict_get_ray(p,res[0],res[1],orig,dir);
603     }
604     x = (x + (0.5*p->pjitter)*(0.5-gb_random())/p->resol.xr);
605     y = (y + (0.5*p->pjitter)*(0.5-gb_random())/p->resol.yr);
606     if (viewray(orig,dir,&(p->view),x,y) < 0)
607     return 0;
608     return 1;
609     }
610    
611    
612     static int splane_normal(pict* p,double e1x,double e1y,
613     double e2x,double e2y,FVECT n)
614     {
615     FVECT e1 = {0,0,0};
616     FVECT e2 = {0,0,0};
617    
618     pict_get_dir_ic(p,e1x,e1y,e1);
619     pict_get_dir_ic(p,e2x,e2y,n);
620     VSUB(e2,n,e1);
621     VCROSS(n,e1,e2);
622     if (normalize(n) == 0.0) {
623     return 0;
624     }
625     return 1;
626     }
627    
628     double pict_get_sangle(pict* p,int x,int y)
629     {
630     int i;
631     double ang,a,hpx,hpy;
632     RREAL pc[2];
633     FVECT n[4] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
634    
635     if (pict_lut_used(p)) {
636     return pict_colbuf(p,p->lut,x,y)[2];
637     }
638     pix2loc(pc,&(p->resol),x,y);
639     hpx = (0.5/p->resol.xr);
640     hpy = (0.5/p->resol.yr);
641     pc[0] -= hpx;
642     pc[1] -= hpy;
643    
644     i = splane_normal(p,pc[0],pc[1],pc[0],(pc[1]+2.0*hpy),n[0]);
645     i &= splane_normal(p,pc[0],(pc[1]+2.0*hpy),(pc[0]+2.0*hpx),(pc[1]+2.0*hpy),n[1]);
646     i &= splane_normal(p,(pc[0]+2.0*hpx),(pc[1]+2.0*hpy),(pc[0]+2.0*hpx),pc[1],n[2]);
647     i &= splane_normal(p,(pc[0]+2.0*hpx),pc[1],pc[0],pc[1],n[3]);
648    
649     if (!i) {
650     return 0;
651     }
652     ang = 0;
653     for(i=0;i<4;i++) {
654     a = DOT(n[i],n[(i+1)%4]);
655     a = acos(a);
656     a = fabs(a);
657     ang += M_PI - a;
658     }
659     ang = ang - 2.0*M_PI;
660     if ((ang > (2.0*M_PI)) || ang < 0) {
661     fprintf(stderr,"Normal error in pict_get_sangle %f %d %d\n",ang,x,y);
662     return -1.0;
663     }
664     return ang;
665     }
666    
667     int pict_locate(pict* p,FVECT pt,int* x,int* y)
668     {
669     FVECT pp;
670     int res[2];
671    
672     if (pict_lut_used(p)) {
673     fprintf(stderr,"pict_locate: Not implemented for lut mode\n");
674     return 0;
675     }
676    
677     viewloc(pp,&(p->view),pt);
678     if (pp[2] < 0)
679     return 0;
680     loc2pix(res,&(p->resol),pp[0],pp[1]);
681     *x = res[0];
682     *y = res[1];
683     return 1;
684     }
685    
686     int pict_get_sigma(pict* p,double x,double y,FVECT vdir,FVECT vup,double* s)
687     {
688     FVECT pvdir;
689    
690     if (!pict_get_dir(p,x,y,pvdir))
691     return 0;
692     if (normalize(vdir) == 0.0) {
693     fprintf(stderr,"get_sigma: view dir is zero\n");
694     return 0;
695     }
696     if (normalize(vup) == 0.0) {
697     fprintf(stderr,"get_sigma: view up is zero\n");
698     return 0;
699     }
700     *s = acos(DOT(vdir,pvdir));
701     return 1;
702     }
703    
704     int pict_get_tau(pict* p,double x,double y,FVECT vdir,FVECT vup,double* t)
705     {
706     FVECT hv,pvdir;
707     double s;
708     int i;
709     if (!pict_get_sigma(p,x,y,vdir,vup,&s))
710     return 0;
711     if (!pict_get_dir(p,x,y,pvdir))
712     return 0;
713     VCOPY(hv,pvdir);
714     normalize(hv);
715     for(i=0;i<3;i++){
716     hv[i] /= cos(s);
717     }
718     VSUB(hv,hv,vdir);
719     normalize(hv);
720     *t = acos(fdot(vup,hv));
721     return 1;
722     }
723    
724     static int ortho_coord(FVECT vdir,FVECT vup,FVECT vv,FVECT hv)
725     {
726     if (normalize(vdir) == 0.0) {
727     fprintf(stderr,"ortho_coord: view direction is zero\n");
728     return 0;
729     }
730     if (normalize(vup) == 0.0) {
731     fprintf(stderr,"ortho_coord: view direction is zero\n");
732     return 0;
733     }
734     fcross(hv,vdir,vup);
735     fcross(vv,vdir,hv);
736     return 1;
737     }
738    
739     int pict_get_vangle(pict* p,double x,double y,FVECT vdir,FVECT vup,double* a)
740     {
741     FVECT hv,vv,pvdir;
742     if (!ortho_coord(vdir,vup,vv,hv)) {
743     return 0;
744     }
745     if (!pict_get_dir(p,x,y,pvdir))
746     return 0;
747     *a = acos(fdot(vv,pvdir)) - (M_PI/2.0) ;
748     return 1;
749     }
750    
751     int pict_get_hangle(pict* p,double x,double y,FVECT vdir,FVECT vup,double* a)
752     {
753     FVECT hv,vv,pvdir;
754     if (!ortho_coord(vdir,vup,vv,hv)) {
755     return 0;
756     }
757     if (!pict_get_dir(p,x,y,pvdir)) {
758     return 0;
759     }
760     *a = ((M_PI/2.0) - acos(fdot(hv,pvdir)));
761     return 1;
762     }
763    
764     int pict_setorigin(pict* p,FVECT orig)
765     {
766     VCOPY(p->view.vp,orig);
767     return pict_update_view(p);
768     }
769    
770     int pict_setdir(pict* p,FVECT dir)
771     {
772     VCOPY(p->view.vdir,dir);
773     return pict_update_view(p);
774     }
775    
776     int pict_sethview(pict* p,double ha)
777     {
778     p->view.horiz = ha;
779     return pict_update_view(p);
780     }
781    
782     int pict_setvview(pict* p,double va)
783     {
784     p->view.vert = va;
785     return pict_update_view(p);
786     }
787    
788     int pict_setvtype(pict* p,char vt)
789     {
790     p->view.type = vt;
791     return pict_update_view(p);
792     }
793    
794     #ifdef TEST_PICTTOOL
795    
796     char* progname = "pictool";
797    
798     int main(int argc,char** argv)
799     {
800     pict* p = pict_create();
801     FVECT dir = {0,-1,0};
802     FVECT vdir,edir;
803     FVECT up = {0,0,1};
804     int x,y,i;
805     double sang,h,v;
806    
807     if (argc < 2) {
808     fprintf(stderr,"usage: %s <pic-file>\n",argv[0]);
809     return EXIT_FAILURE;
810     }
811     fprintf(stderr,"readdd\n");
812     pict_read(p,argv[1]);
813     pict_set_comment(p,"pictool test output\n");
814     /*
815     pict_get_dir(p,100,100,edir); // YDECR
816     for(y=0;y<p->resol.yr;y++) {
817     for(x=0;x<p->resol.xr;x++) {
818     pict_get_hangle(p,x,y,dir,up,&h);
819     pict_get_vangle(p,x,y,dir,up,&v);
820     pict_get_dir(p,x,y,vdir);
821     if (acos(DOT(vdir,edir)) < DEG2RAD(3))
822     setcolor(pict_get_color(p,x,y),h+M_PI/2,v+M_PI/2,1);
823     else
824     setcolor(pict_get_color(p,x,y),h+M_PI/2,v+M_PI/2,0);
825     }
826     }
827     */
828     printf("resolution: %dx%d\n",pict_get_xsize(p),pict_get_ysize(p));
829     sang = 0.0;
830    
831     pict_new_gli(p);
832     for(x=0;x<pict_get_xsize(p);x++)
833     for(y=0;y<pict_get_ysize(p);y++) {
834     pict_get_dir(p,x,y,dir);
835     if (DOT(dir,p->view.vdir) >= 0.0) {
836     pict_get_av_omega(p,0) += pict_get_omega(p,x,y);
837     }
838     sang = pict_get_sangle(p,x,y);
839     for(i=0;i<3;i++)
840     if (sang <= 0 && pict_is_validpixel(p,x,y)) {
841     pict_get_color(p,x,y)[i] = 1;
842     } else {
843     pict_get_color(p,x,y)[i] =0;
844     }
845     }
846     printf("s %f\n",pict_get_av_omega(p,0));
847     pict_write(p,"test.pic");
848     while(1) {
849     printf("pos\n");
850     if (scanf("%d %d",&x,&y) != 2)
851     continue;
852     pict_get_dir(p,x,y,dir);
853     printf("dir: \t\t %f %f %f\n",dir[0],dir[1],dir[2]);
854     printf("solid angle: \t %f \n",pict_get_sangle(p,x,y));
855     }
856     return EXIT_SUCCESS;
857     }
858    
859     #endif