ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/pictool.c
Revision: 2.2
Committed: Tue Aug 18 15:02:53 2015 UTC (8 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R0
Changes since 2.1: +3 -0 lines
Log Message:
Added RCCS id's to new source files (forgotten during initial check-in)

File Contents

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