--- ray/src/ot/cvmesh.c 2003/05/14 03:08:22 2.5 +++ ray/src/ot/cvmesh.c 2004/01/29 22:21:34 2.8 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: cvmesh.c,v 2.5 2003/05/14 03:08:22 greg Exp $"; +static const char RCSid[] = "$Id: cvmesh.c,v 2.8 2004/01/29 22:21:34 greg Exp $"; #endif /* * Radiance triangle mesh conversion routines @@ -10,6 +10,7 @@ static const char RCSid[] = "$Id: cvmesh.c,v 2.5 2003/ #include "cvmesh.h" #include "otypes.h" #include "face.h" +#include "tmesh.h" /* * We need to divide faces into triangles and record auxiliary information @@ -23,11 +24,11 @@ typedef struct { int fl; /* flags of what we're storing */ OBJECT obj; /* mesh triangle ID */ FVECT vn[3]; /* normals */ - FLOAT vc[3][2]; /* uv coords. */ + RREAL vc[3][2]; /* uv coords. */ } TRIDATA; #define tdsize(fl) ((fl)&MT_UV ? sizeof(TRIDATA) : \ - (fl)&MT_N ? sizeof(TRIDATA)-6*sizeof(FLOAT) : \ + (fl)&MT_N ? sizeof(TRIDATA)-6*sizeof(RREAL) : \ sizeof(int)+sizeof(OBJECT)) #define OMARGIN (10*FTINY) /* margin around global cube */ @@ -74,11 +75,11 @@ OBJECT mo; int n; FVECT *vp; FVECT *vn; -FLOAT (*vc)[2]; +RREAL (*vc)[2]; { int tcnt = 0; int flags; - FLOAT *tn[3], *tc[3]; + RREAL *tn[3], *tc[3]; int *ord; int i, j; @@ -133,7 +134,7 @@ FLOAT (*vc)[2]; static void add2bounds(vp, vc) /* add point and uv coordinate to bounds */ FVECT vp; -FLOAT vc[2]; +RREAL vc[2]; { register int j; @@ -159,7 +160,7 @@ cvtri(mo, vp1, vp2, vp3, vn1, vn2, vn3, vc1, vc2, vc3) OBJECT mo; FVECT vp1, vp2, vp3; FVECT vn1, vn2, vn3; -FLOAT vc1[2], vc2[2], vc3[2]; +RREAL vc1[2], vc2[2], vc3[2]; { static OBJECT fobj = OVOID; char buf[32]; @@ -169,9 +170,30 @@ FLOAT vc1[2], vc2[2], vc3[2]; OBJREC *fop; int j; - flags = MT_V; - if (vn1 != NULL && vn2 != NULL && vn3 != NULL) - flags |= MT_N; + flags = MT_V; /* check what we have */ + if (vn1 != NULL && vn2 != NULL && vn3 != NULL) { + RREAL *rp; + switch (flat_tri(vp1, vp2, vp3, vn1, vn2, vn3)) { + case ISBENT: + flags |= MT_N; + /* fall through */ + case ISFLAT: + break; + case RVBENT: + flags |= MT_N; + rp = vn1; vn1 = vn3; vn3 = rp; + /* fall through */ + case RVFLAT: + rp = vp1; vp1 = vp3; vp3 = rp; + rp = vc1; vc1 = vc3; vc3 = rp; + break; + case DEGEN: + error(WARNING, "degenerate triangle"); + return(0); + default: + error(INTERNAL, "bad return from flat_tri()"); + } + } if (vc1 != NULL && vc2 != NULL && vc3 != NULL) flags |= MT_UV; if (fobj == OVOID) { /* create new triangle object */ @@ -184,7 +206,7 @@ FLOAT vc1[2], vc2[2], vc3[2]; sprintf(buf, "t%d", fobj); fop->oname = savqstr(buf); fop->oargs.nfargs = 9; - fop->oargs.farg = (FLOAT *)malloc(9*sizeof(FLOAT)); + fop->oargs.farg = (RREAL *)malloc(9*sizeof(RREAL)); if (fop->oargs.farg == NULL) goto nomem; } else { /* else reuse failed one */ @@ -301,9 +323,10 @@ cvmeshbounds() /* set mesh boundaries */ ourmesh->uvlim[1][0] = ourmesh->uvlim[1][1] = 0.; } else { for (i = 0; i < 2; i++) { - double marg; - marg = 1e-6*(ourmesh->uvlim[1][i] - - ourmesh->uvlim[0][i]); + double marg; /* expand past endpoints */ + marg = (2./(1L<<(8*sizeof(uint16)))) * + (ourmesh->uvlim[1][i] - + ourmesh->uvlim[0][i]); ourmesh->uvlim[0][i] -= marg; ourmesh->uvlim[1][i] += marg; }