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

# Content
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