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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 #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