Back to index

radiance  4R0+20100331
Classes | Defines | Functions | Variables
gensurf.c File Reference
#include "standard.h"
#include "paths.h"
#include "resolu.h"
#include "rterror.h"
#include "calcomp.h"

Go to the source code of this file.

Classes

struct  POINT

Defines

#define ABS(x)   ((x)>=0 ? (x) : -(x))
#define ZEROVECT(v)   (DOT(v,v) <= FTINY*FTINY)
#define pvect(p)   printf(vformat, (p)[0], (p)[1], (p)[2])
#define HASBORDER   01
#define TRIPLETS   02
#define u   ((ax+1)%3)
#define v   ((ax+2)%3)

Functions

double l_hermite ()
double l_bezier ()
double l_bspline ()
double l_dataval ()
void loaddata (char *file, int m, int n, int pointsize)
double l_dataval (char *nam)
void putobjrow (POINT *rp, int n)
void putsquare (POINT *p0, POINT *p1, POINT *p2, POINT *p3)
void comprow (double s, POINT *row, int siz)
void compnorms (POINT *r0, POINT *r1, POINT *r2, int siz)
int norminterp (FVECT resmat[4], POINT *p0, POINT *p1, POINT *p2, POINT *p3)
int main (int argc, argv)
void putobjrow (register POINT *rp, int n)
void comprow (double s, register POINT *row, int siz)
void compnorms (register POINT *r0, register POINT *r1, register POINT *r2, int siz)
int norminterp (register FVECT resmat[4], POINT *p0, POINT *p1, POINT *p2, POINT *p3)
double l_hermite (char *nm)
double l_bezier (char *nm)
double l_bspline (char *nm)

Variables

static const char RCSid [] = "$Id: gensurf.c,v 2.18 2007/10/18 03:59:54 greg Exp $"
char XNAME [] = "X`SYS"
char YNAME [] = "Y`SYS"
char ZNAME [] = "Z`SYS"
char VNAME [] = "valid"
char vformat [] = "%18.12g %18.12g %18.12g\n"
char tsargs [] = "4 surf_dx surf_dy surf_dz surf.cal\n"
char texname [] = "Phong"
int smooth = 0
int objout = 0
char * modname
char * surfname
struct {
int flags
short m
short n
RREALdata
datarec

Class Documentation

struct POINT

Definition at line 59 of file gensurf.c.

Class Members
FVECT n
FVECT p
RREAL uv
int valid

Define Documentation

#define ABS (   x)    ((x)>=0 ? (x) : -(x))

Definition at line 31 of file gensurf.c.

#define HASBORDER   01

Definition at line 47 of file gensurf.c.

#define pvect (   p)    printf(vformat, (p)[0], (p)[1], (p)[2])

Definition at line 35 of file gensurf.c.

#define TRIPLETS   02

Definition at line 48 of file gensurf.c.

#define u   ((ax+1)%3)
#define v   ((ax+2)%3)
#define ZEROVECT (   v)    (DOT(v,v) <= FTINY*FTINY)

Definition at line 33 of file gensurf.c.


Function Documentation

void compnorms ( POINT r0,
POINT r1,
POINT r2,
int  siz 
)

Here is the caller graph for this function:

void compnorms ( register POINT r0,
register POINT r1,
register POINT r2,
int  siz 
)

Definition at line 489 of file gensurf.c.

{
       FVECT  v1, v2;

       if (!smooth)                /* not needed if no smoothing */
              return;
                                   /* compute row 1 normals */
       while (siz-- >= 0) {
              if (!r1[0].valid)
                     continue;
              if (!r0[0].valid) {
                     if (!r2[0].valid) {
                            r1[0].n[0] = r1[0].n[1] = r1[0].n[2] = 0.0;
                            continue;
                     }
                     fvsum(v1, r2[0].p, r1[0].p, -1.0);
              } else if (!r2[0].valid)
                     fvsum(v1, r1[0].p, r0[0].p, -1.0);
              else
                     fvsum(v1, r2[0].p, r0[0].p, -1.0);
              if (!r1[-1].valid) {
                     if (!r1[1].valid) {
                            r1[0].n[0] = r1[0].n[1] = r1[0].n[2] = 0.0;
                            continue;
                     }
                     fvsum(v2, r1[1].p, r1[0].p, -1.0);
              } else if (!r1[1].valid)
                     fvsum(v2, r1[0].p, r1[-1].p, -1.0);
              else
                     fvsum(v2, r1[1].p, r1[-1].p, -1.0);
              fcross(r1[0].n, v1, v2);
              normalize(r1[0].n);
              r0++; r1++; r2++;
       }
}

Here is the call graph for this function:

void comprow ( double  s,
POINT row,
int  siz 
)

Here is the caller graph for this function:

void comprow ( double  s,
register POINT row,
int  siz 
)

Definition at line 447 of file gensurf.c.

{
       double  st[2];
       int  end;
       int  checkvalid;
       register int  i;
       
       if (smooth) {
              i = -1;                     /* compute one past each end */
              end = siz+1;
       } else {
              if (s < -FTINY || s > 1.0+FTINY)
                     return;
              i = 0;
              end = siz;
       }
       st[0] = s;
       checkvalid = (fundefined(VNAME) == 2);
       while (i <= end) {
              st[1] = (double)i/siz;
              if (checkvalid && funvalue(VNAME, 2, st) <= 0.0) {
                     row[i].valid = 0;
                     row[i].p[0] = row[i].p[1] = row[i].p[2] = 0.0;
                     row[i].uv[0] = row[i].uv[1] = 0.0;
              } else {
                     row[i].valid = 1;
                     row[i].p[0] = funvalue(XNAME, 2, st);
                     row[i].p[1] = funvalue(YNAME, 2, st);
                     row[i].p[2] = funvalue(ZNAME, 2, st);
                     row[i].uv[0] = st[0];
                     row[i].uv[1] = st[1];
              }
              i++;
       }
}

Here is the call graph for this function:

double l_bezier ( )
double l_bezier ( char *  nm)

Definition at line 605 of file gensurf.c.

{
       double  t;

       t = argument(5);
       return(       argument(1) * (1.+t*(-3.+t*(3.-t))) +
              argument(2) * 3.*t*(1.+t*(-2.+t)) +
              argument(3) * 3.*t*t*(1.-t) +
              argument(4) * t*t*t );
}

Here is the call graph for this function:

double l_bspline ( )
double l_bspline ( char *  nm)

Definition at line 618 of file gensurf.c.

{
       double  t;

       t = argument(5);
       return(       argument(1) * (1./6.+t*(-1./2.+t*(1./2.-1./6.*t))) +
              argument(2) * (2./3.+t*t*(-1.+1./2.*t)) +
              argument(3) * (1./6.+t*(1./2.+t*(1./2.-1./2.*t))) +
              argument(4) * (1./6.*t*t*t) );
}

Here is the call graph for this function:

double l_dataval ( )

Here is the caller graph for this function:

double l_dataval ( char *  nam)

Definition at line 252 of file gensurf.c.

{
       double  u, v;
       register int  i, j;
       register RREAL  *dp;
       double  d00, d01, d10, d11;
                                          /* compute coordinates */
       u = argument(1); v = argument(2);
       if (datarec.flags & HASBORDER) {
              i = u *= datarec.m-1;
              j = v *= datarec.n-1;
       } else {
              i = u = u*datarec.m - .5;
              j = v = v*datarec.n - .5;
       }
       if (i < 0) i = 0;
       else if (i > datarec.m-2) i = datarec.m-2;
       if (j < 0) j = 0;
       else if (j > datarec.n-2) j = datarec.n-2;
                                          /* compute value */
       if (datarec.flags & TRIPLETS) {
              dp = datarec.data + 3*(j*datarec.m + i);
              if (nam == ZNAME)
                     dp += 2;
              else if (nam == YNAME)
                     dp++;
              d00 = dp[0]; d01 = dp[3];
              dp += 3*datarec.m;
              d10 = dp[0]; d11 = dp[3];
       } else {
              dp = datarec.data + j*datarec.m + i;
              d00 = dp[0]; d01 = dp[1];
              dp += datarec.m;
              d10 = dp[0]; d11 = dp[1];
       }
                                          /* bilinear interpolation */
       return((j+1-v)*((i+1-u)*d00+(u-i)*d01)+(v-j)*((i+1-u)*d10+(u-i)*d11));
}

Here is the call graph for this function:

double l_hermite ( )
double l_hermite ( char *  nm)

Definition at line 592 of file gensurf.c.

{
       double  t;
       
       t = argument(5);
       return(       argument(1)*((2.0*t-3.0)*t*t+1.0) +
              argument(2)*(-2.0*t+3.0)*t*t +
              argument(3)*((t-2.0)*t+1.0)*t +
              argument(4)*(t-1.0)*t*t );
}

Here is the call graph for this function:

void loaddata ( char *  file,
int  m,
int  n,
int  pointsize 
)

Definition at line 191 of file gensurf.c.

{
       FILE  *fp;
       char  word[64];
       register int  size;
       register RREAL  *dp;

       datarec.flags = HASBORDER;         /* assume border values */
       datarec.m = m+1;
       datarec.n = n+1;
       size = datarec.m*datarec.n*pointsize;
       if (pointsize == 3)
              datarec.flags |= TRIPLETS;
       dp = (RREAL *)malloc(size*sizeof(RREAL));
       if ((datarec.data = dp) == NULL) {
              fputs("Out of memory\n", stderr);
              exit(1);
       }
       if (!strcmp(file, "-")) {
              file = "<stdin>";
              fp = stdin;
       } else if ((fp = fopen(file, "r")) == NULL) {
              fputs(file, stderr);
              fputs(": cannot open\n", stderr);
              exit(1);
       }
       while (size > 0 && fgetword(word, sizeof(word), fp) != NULL) {
              if (!isflt(word)) {
                     fprintf(stderr, "%s: garbled data value: %s\n",
                                   file, word);
                     exit(1);
              }
              *dp++ = atof(word);
              size--;
       }
       if (size == (m+n+1)*pointsize) {   /* no border after all */
              dp = (RREAL *)realloc((void *)datarec.data,
                            m*n*pointsize*sizeof(RREAL));
              if (dp != NULL)
                     datarec.data = dp;
              datarec.flags &= ~HASBORDER;
              datarec.m = m;
              datarec.n = n;
              size = 0;
       }
       if (datarec.m < 2 || datarec.n < 2 || size != 0 ||
                     fgetword(word, sizeof(word), fp) != NULL) {
              fputs(file, stderr);
              fputs(": bad number of data points\n", stderr);
              exit(1);
       }
       fclose(fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
argv   
)

Definition at line 77 of file gensurf.c.

{
       POINT  *row0, *row1, *row2, *rp;
       int  i, j, m, n;
       char  stmp[256];

       varset("PI", ':', PI);
       funset("hermite", 5, ':', l_hermite);
       funset("bezier", 5, ':', l_bezier);
       funset("bspline", 5, ':', l_bspline);

       if (argc < 8)
              goto userror;

       for (i = 8; i < argc; i++)
              if (!strcmp(argv[i], "-e"))
                     scompile(argv[++i], NULL, 0);
              else if (!strcmp(argv[i], "-f"))
                     fcompile(argv[++i]);
              else if (!strcmp(argv[i], "-s"))
                     smooth++;
              else if (!strcmp(argv[i], "-o"))
                     objout++;
              else
                     goto userror;

       modname = argv[1];
       surfname = argv[2];
       m = atoi(argv[6]);
       n = atoi(argv[7]);
       if (m <= 0 || n <= 0)
              goto userror;
       if (!strcmp(argv[5], "-") || access(argv[5], 4) == 0) { /* file? */
              funset(ZNAME, 2, ':', l_dataval);
              if (!strcmp(argv[5],argv[3]) && !strcmp(argv[5],argv[4])) {
                     loaddata(argv[5], m, n, 3);
                     funset(XNAME, 2, ':', l_dataval);
                     funset(YNAME, 2, ':', l_dataval);
              } else {
                     loaddata(argv[5], m, n, 1);
                     sprintf(stmp, "%s(s,t)=%s;", XNAME, argv[3]);
                     scompile(stmp, NULL, 0);
                     sprintf(stmp, "%s(s,t)=%s;", YNAME, argv[4]);
                     scompile(stmp, NULL, 0);
              }
       } else {
              sprintf(stmp, "%s(s,t)=%s;", XNAME, argv[3]);
              scompile(stmp, NULL, 0);
              sprintf(stmp, "%s(s,t)=%s;", YNAME, argv[4]);
              scompile(stmp, NULL, 0);
              sprintf(stmp, "%s(s,t)=%s;", ZNAME, argv[5]);
              scompile(stmp, NULL, 0);
       }
       row0 = (POINT *)malloc((n+3)*sizeof(POINT));
       row1 = (POINT *)malloc((n+3)*sizeof(POINT));
       row2 = (POINT *)malloc((n+3)*sizeof(POINT));
       if (row0 == NULL || row1 == NULL || row2 == NULL) {
              fprintf(stderr, "%s: out of memory\n", argv[0]);
              quit(1);
       }
       row0++; row1++; row2++;
                                          /* print header */
       fputs("# ", stdout);
       printargs(argc, argv, stdout);
       eclock = 0;
                                          /* initialize */
       comprow(-1.0/m, row0, n);
       comprow(0.0, row1, n);
       comprow(1.0/m, row2, n);
       compnorms(row0, row1, row2, n);
       if (objout) {
              printf("\nusemtl %s\n\n", modname);
              putobjrow(row1, n);
       }
                                          /* for each row */
       for (i = 0; i < m; i++) {
                                          /* compute next row */
              rp = row0;
              row0 = row1;
              row1 = row2;
              row2 = rp;
              comprow((double)(i+2)/m, row2, n);
              compnorms(row0, row1, row2, n);
              if (objout)
                     putobjrow(row1, n);

              for (j = 0; j < n; j++) {
                     int  orient = (j & 1);
                                                 /* put polygons */
                     if (!(row0[j].valid && row1[j+1].valid))
                            orient = 1;
                     else if (!(row1[j].valid && row0[j+1].valid))
                            orient = 0;
                     if (orient)
                            putsquare(&row0[j], &row1[j],
                                          &row0[j+1], &row1[j+1]);
                     else
                            putsquare(&row1[j], &row1[j+1],
                                          &row0[j], &row0[j+1]);
              }
       }

       return 0;

userror:
       fprintf(stderr, "Usage: %s material name ", argv[0]);
       fprintf(stderr, "x(s,t) y(s,t) z(s,t) m n [-s][-o][-e expr][-f file]\n");
       return 1;
}

Here is the call graph for this function:

int norminterp ( FVECT  resmat[4],
POINT p0,
POINT p1,
POINT p2,
POINT p3 
)

Here is the caller graph for this function:

int norminterp ( register FVECT  resmat[4],
POINT p0,
POINT p1,
POINT p2,
POINT p3 
)

Definition at line 532 of file gensurf.c.

{
#define u  ((ax+1)%3)
#define v  ((ax+2)%3)

       register int  ax;
       MAT4  eqnmat;
       FVECT  v1;
       register int  i, j;

       if (!smooth)                /* no interpolation if no smoothing */
              return(-1);
                                   /* find dominant axis */
       VCOPY(v1, p0->n);
       fvsum(v1, v1, p1->n, 1.0);
       fvsum(v1, v1, p2->n, 1.0);
       fvsum(v1, v1, p3->n, 1.0);
       ax = ABS(v1[0]) > ABS(v1[1]) ? 0 : 1;
       ax = ABS(v1[ax]) > ABS(v1[2]) ? ax : 2;
                                   /* assign equation matrix */
       eqnmat[0][0] = p0->p[u]*p0->p[v];
       eqnmat[0][1] = p0->p[u];
       eqnmat[0][2] = p0->p[v];
       eqnmat[0][3] = 1.0;
       eqnmat[1][0] = p1->p[u]*p1->p[v];
       eqnmat[1][1] = p1->p[u];
       eqnmat[1][2] = p1->p[v];
       eqnmat[1][3] = 1.0;
       eqnmat[2][0] = p2->p[u]*p2->p[v];
       eqnmat[2][1] = p2->p[u];
       eqnmat[2][2] = p2->p[v];
       eqnmat[2][3] = 1.0;
       eqnmat[3][0] = p3->p[u]*p3->p[v];
       eqnmat[3][1] = p3->p[u];
       eqnmat[3][2] = p3->p[v];
       eqnmat[3][3] = 1.0;
                                   /* invert matrix (solve system) */
       if (!invmat4(eqnmat, eqnmat))
              return(-1);                 /* no solution */
                                   /* compute result matrix */
       for (j = 0; j < 4; j++)
              for (i = 0; i < 3; i++)
                     resmat[j][i] =       eqnmat[j][0]*p0->n[i] +
                                   eqnmat[j][1]*p1->n[i] +
                                   eqnmat[j][2]*p2->n[i] +
                                   eqnmat[j][3]*p3->n[i];
       return(ax);

#undef u
#undef v
}

Here is the call graph for this function:

void putobjrow ( POINT rp,
int  n 
)

Here is the caller graph for this function:

void putobjrow ( register POINT rp,
int  n 
)

Definition at line 295 of file gensurf.c.

{
       static int    nverts = 0;

       for ( ; n-- >= 0; rp++) {
              if (!rp->valid)
                     continue;
              fputs("v ", stdout);
              pvect(rp->p);
              if (smooth && !ZEROVECT(rp->n))
                     printf("\tvn %.9g %.9g %.9g\n",
                                   rp->n[0], rp->n[1], rp->n[2]);
              printf("\tvt %.9g %.9g\n", rp->uv[0], rp->uv[1]);
              rp->valid = ++nverts;
       }
}
void putsquare ( POINT p0,
POINT p1,
POINT p2,
POINT p3 
)

Definition at line 317 of file gensurf.c.

{
       static int  nout = 0;
       FVECT  norm[4];
       int  axis;
       FVECT  v1, v2, vc1, vc2;
       int  ok1, ok2;
                                   /* compute exact normals */
       ok1 = (p0->valid && p1->valid && p2->valid);
       if (ok1) {
              VSUB(v1, p1->p, p0->p);
              VSUB(v2, p2->p, p0->p);
              fcross(vc1, v1, v2);
              ok1 = (normalize(vc1) != 0.0);
       }
       ok2 = (p1->valid && p2->valid && p3->valid);
       if (ok2) {
              VSUB(v1, p2->p, p3->p);
              VSUB(v2, p1->p, p3->p);
              fcross(vc2, v1, v2);
              ok2 = (normalize(vc2) != 0.0);
       }
       if (!(ok1 | ok2))
              return;
       if (objout) {               /* output .OBJ faces */
              int    p0n=0, p1n=0, p2n=0, p3n=0;
              if (smooth) {
                     if (!ZEROVECT(p0->n))
                            p0n = p0->valid;
                     if (!ZEROVECT(p1->n))
                            p1n = p1->valid;
                     if (!ZEROVECT(p2->n))
                            p2n = p2->valid;
                     if (!ZEROVECT(p3->n))
                            p3n = p3->valid;
              }
              if (ok1 & ok2 && fdot(vc1,vc2) >= 1.0-FTINY*FTINY) {
                     printf("f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d\n",
                                   p0->valid, p0->valid, p0n,
                                   p1->valid, p1->valid, p1n,
                                   p3->valid, p3->valid, p3n,
                                   p2->valid, p2->valid, p2n);
                     return;
              }
              if (ok1)
                     printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n",
                                   p0->valid, p0->valid, p0n,
                                   p1->valid, p1->valid, p1n,
                                   p2->valid, p2->valid, p2n);
              if (ok2)
                     printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n",
                                   p2->valid, p2->valid, p2n,
                                   p1->valid, p1->valid, p1n,
                                   p3->valid, p3->valid, p3n);
              return;
       }
                                   /* compute normal interpolation */
       axis = norminterp(norm, p0, p1, p2, p3);

                                   /* put out quadrilateral? */
       if (ok1 & ok2 && fdot(vc1,vc2) >= 1.0-FTINY*FTINY) {
              printf("\n%s ", modname);
              if (axis != -1) {
                     printf("texfunc %s\n", texname);
                     printf(tsargs);
                     printf("0\n13\t%d\n", axis);
                     pvect(norm[0]);
                     pvect(norm[1]);
                     pvect(norm[2]);
                     fvsum(v1, norm[3], vc1, -0.5);
                     fvsum(v1, v1, vc2, -0.5);
                     pvect(v1);
                     printf("\n%s ", texname);
              }
              printf("polygon %s.%d\n", surfname, ++nout);
              printf("0\n0\n12\n");
              pvect(p0->p);
              pvect(p1->p);
              pvect(p3->p);
              pvect(p2->p);
              return;
       }
                                   /* put out triangles? */
       if (ok1) {
              printf("\n%s ", modname);
              if (axis != -1) {
                     printf("texfunc %s\n", texname);
                     printf(tsargs);
                     printf("0\n13\t%d\n", axis);
                     pvect(norm[0]);
                     pvect(norm[1]);
                     pvect(norm[2]);
                     fvsum(v1, norm[3], vc1, -1.0);
                     pvect(v1);
                     printf("\n%s ", texname);
              }
              printf("polygon %s.%d\n", surfname, ++nout);
              printf("0\n0\n9\n");
              pvect(p0->p);
              pvect(p1->p);
              pvect(p2->p);
       }
       if (ok2) {
              printf("\n%s ", modname);
              if (axis != -1) {
                     printf("texfunc %s\n", texname);
                     printf(tsargs);
                     printf("0\n13\t%d\n", axis);
                     pvect(norm[0]);
                     pvect(norm[1]);
                     pvect(norm[2]);
                     fvsum(v2, norm[3], vc2, -1.0);
                     pvect(v2);
                     printf("\n%s ", texname);
              }
              printf("polygon %s.%d\n", surfname, ++nout);
              printf("0\n0\n9\n");
              pvect(p2->p);
              pvect(p1->p);
              pvect(p3->p);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

struct { ... } datarec
char* modname

Definition at line 44 of file gensurf.c.

int objout = 0

Definition at line 42 of file gensurf.c.

const char RCSid[] = "$Id: gensurf.c,v 2.18 2007/10/18 03:59:54 greg Exp $" [static]

Definition at line 2 of file gensurf.c.

int smooth = 0

Definition at line 41 of file gensurf.c.

char * surfname

Definition at line 44 of file gensurf.c.

char texname[] = "Phong"

Definition at line 39 of file gensurf.c.

char tsargs[] = "4 surf_dx surf_dy surf_dz surf.cal\n"

Definition at line 38 of file gensurf.c.

char vformat[] = "%18.12g %18.12g %18.12g\n"

Definition at line 37 of file gensurf.c.

char VNAME[] = "valid"

Definition at line 29 of file gensurf.c.

char XNAME[] = "X`SYS"

Definition at line 25 of file gensurf.c.

char YNAME[] = "Y`SYS"

Definition at line 26 of file gensurf.c.

char ZNAME[] = "Z`SYS"

Definition at line 27 of file gensurf.c.