ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/gensurf.c
(Generate patch)

Comparing ray/src/gen/gensurf.c (file contents):
Revision 2.2 by greg, Thu Jan 30 14:11:39 1992 UTC vs.
Revision 2.6 by greg, Sat Feb 22 02:07:23 2003 UTC

# Line 1 | Line 1
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
4
5 /* Copyright (c) 1989 Regents of the University of California */
6
4   /*
5   *  gensurf.c - program to generate functional surfaces
6   *
# Line 14 | Line 11 | static char SCCSid[] = "$SunId$ LBL";
11   *  rule applied to (s,t).
12   *
13   *      4/3/87
14 + *
15 + *      4/16/02 Added conditional vertex output
16   */
17  
18   #include  "standard.h"
19  
20 < char  XNAME[] =         "X`SYS`";               /* x function name */
21 < char  YNAME[] =         "Y`SYS`";               /* y function name */
22 < char  ZNAME[] =         "Z`SYS`";               /* z function name */
20 > char  XNAME[] =         "X`SYS";                /* x function name */
21 > char  YNAME[] =         "Y`SYS";                /* y function name */
22 > char  ZNAME[] =         "Z`SYS";                /* z function name */
23  
24 + char  VNAME[] =         "valid";                /* valid vertex name */
25 +
26   #define  ABS(x)         ((x)>=0 ? (x) : -(x))
27  
28   #define  pvect(p)       printf(vformat, (p)[0], (p)[1], (p)[2])
# Line 48 | Line 49 | double  l_hermite(), l_bezier(), l_bspline(), l_datava
49   extern double  funvalue(), argument();
50  
51   typedef struct {
52 +        int  valid;     /* point is valid */
53          FVECT  p;       /* vertex position */
54          FVECT  n;       /* average normal */
55   } POINT;
# Line 134 | Line 136 | char  *argv[];
136                  compnorms(row0, row1, row2, n);
137  
138                  for (j = 0; j < n; j++) {
139 +                        int  orient = (j & 1);
140                                                          /* put polygons */
141 <                        if ((i+j) & 1)
141 >                        if (!(row0[j].valid & row1[j+1].valid))
142 >                                orient = 1;
143 >                        else if (!(row1[j].valid & row0[j+1].valid))
144 >                                orient = 0;
145 >                        if (orient)
146                                  putsquare(&row0[j], &row1[j],
147                                                  &row0[j+1], &row1[j+1]);
148                          else
# Line 158 | Line 165 | char  *file;
165   int  m, n;
166   int  pointsize;
167   {
161        extern char  *fgetword();
168          FILE  *fp;
169          char  word[64];
170          register int  size;
171          register FLOAT  *dp;
172  
173          datarec.flags = HASBORDER;              /* assume border values */
174 <        size = (m+1)*(n+1)*pointsize;
174 >        datarec.m = m+1;
175 >        datarec.n = n+1;
176 >        size = datarec.m*datarec.n*pointsize;
177          if (pointsize == 3)
178                  datarec.flags |= TRIPLETS;
179          dp = (FLOAT *)malloc(size*sizeof(FLOAT));
# Line 196 | Line 204 | int  pointsize;
204                  if (dp != NULL)
205                          datarec.data = dp;
206                  datarec.flags &= ~HASBORDER;
207 +                datarec.m = m;
208 +                datarec.n = n;
209                  size = 0;
210          }
211 <        if (size || fgetword(word, sizeof(word), fp) != NULL) {
211 >        if (datarec.m < 2 || datarec.n < 2 || size != 0 ||
212 >                        fgetword(word, sizeof(word), fp) != NULL) {
213                  fputs(file, stderr);
214                  fputs(": bad number of data points\n", stderr);
215                  exit(1);
# Line 218 | Line 229 | char  *nam;
229                                                  /* compute coordinates */
230          u = argument(1); v = argument(2);
231          if (datarec.flags & HASBORDER) {
232 <                i = u *= datarec.m;
233 <                j = v *= datarec.n;
232 >                i = u *= datarec.m-1;
233 >                j = v *= datarec.n-1;
234          } else {
235 <                i = u = u*(datarec.m+1) - .5;
236 <                j = v = v*(datarec.n+1) - .5;
235 >                i = u = u*datarec.m - .5;
236 >                j = v = v*datarec.n - .5;
237          }
238          if (i < 0) i = 0;
239          else if (i > datarec.m-2) i = datarec.m-2;
# Line 230 | Line 241 | char  *nam;
241          else if (j > datarec.n-2) j = datarec.n-2;
242                                                  /* compute value */
243          if (datarec.flags & TRIPLETS) {
244 <                dp = datarec.data + 3*(j*datarec.n + i);
245 <                if (nam == YNAME)
235 <                        dp++;
236 <                else if (nam == ZNAME)
244 >                dp = datarec.data + 3*(j*datarec.m + i);
245 >                if (nam == ZNAME)
246                          dp += 2;
247 +                else if (nam == YNAME)
248 +                        dp++;
249                  d00 = dp[0]; d01 = dp[3];
250 <                dp += 3*datarec.n;
250 >                dp += 3*datarec.m;
251                  d10 = dp[0]; d11 = dp[3];
252          } else {
253 <                dp = datarec.data + j*datarec.n + i;
253 >                dp = datarec.data + j*datarec.m + i;
254                  d00 = dp[0]; d01 = dp[1];
255 <                dp += datarec.n;
255 >                dp += datarec.m;
256                  d10 = dp[0]; d11 = dp[1];
257          }
258                                                  /* bilinear interpolation */
# Line 258 | Line 269 | POINT  *p0, *p1, *p2, *p3;
269          FVECT  v1, v2, vc1, vc2;
270          int  ok1, ok2;
271                                          /* compute exact normals */
272 <        fvsum(v1, p1->p, p0->p, -1.0);
273 <        fvsum(v2, p2->p, p0->p, -1.0);
274 <        fcross(vc1, v1, v2);
275 <        ok1 = normalize(vc1) != 0.0;
276 <        fvsum(v1, p2->p, p3->p, -1.0);
277 <        fvsum(v2, p1->p, p3->p, -1.0);
278 <        fcross(vc2, v1, v2);
279 <        ok2 = normalize(vc2) != 0.0;
272 >        ok1 = (p0->valid & p1->valid & p2->valid);
273 >        if (ok1) {
274 >                fvsum(v1, p1->p, p0->p, -1.0);
275 >                fvsum(v2, p2->p, p0->p, -1.0);
276 >                fcross(vc1, v1, v2);
277 >                ok1 = (normalize(vc1) != 0.0);
278 >        }
279 >        ok2 = (p1->valid & p2->valid & p3->valid);
280 >        if (ok2) {
281 >                fvsum(v1, p2->p, p3->p, -1.0);
282 >                fvsum(v2, p1->p, p3->p, -1.0);
283 >                fcross(vc2, v1, v2);
284 >                ok2 = (normalize(vc2) != 0.0);
285 >        }
286          if (!(ok1 | ok2))
287                  return;
288                                          /* compute normal interpolation */
# Line 343 | Line 360 | int  siz;
360   {
361          double  st[2];
362          int  end;
363 +        int  checkvalid;
364          register int  i;
365          
366          if (smooth) {
# Line 355 | Line 373 | int  siz;
373                  end = siz;
374          }
375          st[0] = s;
376 +        checkvalid = (fundefined(VNAME) == 2);
377          while (i <= end) {
378                  st[1] = (double)i/siz;
379 <                row[i].p[0] = funvalue(XNAME, 2, st);
380 <                row[i].p[1] = funvalue(YNAME, 2, st);
381 <                row[i].p[2] = funvalue(ZNAME, 2, st);
379 >                if (checkvalid && funvalue(VNAME, 2, st) <= 0.0) {
380 >                        row[i].valid = 0;
381 >                        row[i].p[0] = row[i].p[1] = row[i].p[2] = 0.0;
382 >                } else {
383 >                        row[i].valid = 1;
384 >                        row[i].p[0] = funvalue(XNAME, 2, st);
385 >                        row[i].p[1] = funvalue(YNAME, 2, st);
386 >                        row[i].p[2] = funvalue(ZNAME, 2, st);
387 >                }
388                  i++;
389          }
390   }
# Line 370 | Line 395 | register POINT  *r0, *r1, *r2;
395   int  siz;
396   {
397          FVECT  v1, v2;
373        register int  i;
398  
399          if (!smooth)                    /* not needed if no smoothing */
400                  return;
401 <                                        /* compute middle points */
401 >                                        /* compute row 1 normals */
402          while (siz-- >= 0) {
403 <                fvsum(v1, r2[0].p, r0[0].p, -1.0);
404 <                fvsum(v2, r1[1].p, r1[-1].p, -1.0);
403 >                if (!r1[0].valid)
404 >                        continue;
405 >                if (!r0[0].valid) {
406 >                        if (!r2[0].valid) {
407 >                                r1[0].n[0] = r1[0].n[1] = r1[0].n[2] = 0.0;
408 >                                continue;
409 >                        }
410 >                        fvsum(v1, r2[0].p, r1[0].p, -1.0);
411 >                } else if (!r2[0].valid)
412 >                        fvsum(v1, r1[0].p, r0[0].p, -1.0);
413 >                else
414 >                        fvsum(v1, r2[0].p, r0[0].p, -1.0);
415 >                if (!r1[-1].valid) {
416 >                        if (!r1[1].valid) {
417 >                                r1[0].n[0] = r1[0].n[1] = r1[0].n[2] = 0.0;
418 >                                continue;
419 >                        }
420 >                        fvsum(v2, r1[1].p, r1[0].p, -1.0);
421 >                } else if (!r1[1].valid)
422 >                        fvsum(v2, r1[0].p, r1[-1].p, -1.0);
423 >                else
424 >                        fvsum(v2, r1[1].p, r1[-1].p, -1.0);
425                  fcross(r1[0].n, v1, v2);
426                  normalize(r1[0].n);
427                  r0++; r1++; r2++;
# Line 425 | Line 469 | POINT  *p0, *p1, *p2, *p3;
469          eqnmat[3][2] = p3->p[v];
470          eqnmat[3][3] = 1.0;
471                                          /* invert matrix (solve system) */
472 <        if (!invmat(eqnmat, eqnmat))
472 >        if (!invmat4(eqnmat, eqnmat))
473                  return(-1);                     /* no solution */
474                                          /* compute result matrix */
475          for (j = 0; j < 4; j++)
# Line 441 | Line 485 | POINT  *p0, *p1, *p2, *p3;
485   }
486  
487  
488 < /*
445 < * invmat - computes the inverse of mat into inverse.  Returns 1
446 < * if there exists an inverse, 0 otherwise.  It uses Gaussian Elimination
447 < * method.
448 < */
449 <
450 < invmat(inverse,mat)
451 < MAT4  inverse, mat;
452 < {
453 < #define SWAP(a,b,t) (t=a,a=b,b=t)
454 <
455 <        MAT4  m4tmp;
456 <        register int i,j,k;
457 <        register double temp;
458 <
459 <        copymat4(m4tmp, mat);
460 <                                        /* set inverse to identity */
461 <        for (i = 0; i < 4; i++)
462 <                for (j = 0; j < 4; j++)
463 <                        inverse[i][j] = i==j ? 1.0 : 0.0;
464 <
465 <        for(i = 0; i < 4; i++) {
466 <                /* Look for row with largest pivot and swap rows */
467 <                temp = FTINY; j = -1;
468 <                for(k = i; k < 4; k++)
469 <                        if(ABS(m4tmp[k][i]) > temp) {
470 <                                temp = ABS(m4tmp[k][i]);
471 <                                j = k;
472 <                                }
473 <                if(j == -1)     /* No replacing row -> no inverse */
474 <                        return(0);
475 <                if (j != i)
476 <                        for(k = 0; k < 4; k++) {
477 <                                SWAP(m4tmp[i][k],m4tmp[j][k],temp);
478 <                                SWAP(inverse[i][k],inverse[j][k],temp);
479 <                                }
480 <
481 <                temp = m4tmp[i][i];
482 <                for(k = 0; k < 4; k++) {
483 <                        m4tmp[i][k] /= temp;
484 <                        inverse[i][k] /= temp;
485 <                        }
486 <                for(j = 0; j < 4; j++) {
487 <                        if(j != i) {
488 <                                temp = m4tmp[j][i];
489 <                                for(k = 0; k < 4; k++) {
490 <                                        m4tmp[j][k] -= m4tmp[i][k]*temp;
491 <                                        inverse[j][k] -= inverse[i][k]*temp;
492 <                                        }
493 <                                }
494 <                        }
495 <                }
496 <        return(1);
497 <
498 < #undef SWAP
499 < }
500 <
501 <
488 > void
489   eputs(msg)
490   char  *msg;
491   {
# Line 506 | Line 493 | char  *msg;
493   }
494  
495  
496 + void
497   wputs(msg)
498   char  *msg;
499   {
# Line 513 | Line 501 | char  *msg;
501   }
502  
503  
504 + void
505   quit(code)
506 + int  code;
507   {
508          exit(code);
509   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines