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

Comparing ray/src/ot/cvmesh.c (file contents):
Revision 2.2 by greg, Wed Mar 12 04:59:04 2003 UTC vs.
Revision 2.12 by greg, Fri Jan 24 01:26:44 2014 UTC

# Line 10 | Line 10 | static const char RCSid[] = "$Id$";
10   #include "cvmesh.h"
11   #include "otypes.h"
12   #include "face.h"
13 + #include "tmesh.h"
14  
15   /*
16   * We need to divide faces into triangles and record auxiliary information
# Line 23 | Line 24 | typedef struct {
24          int             fl;             /* flags of what we're storing */
25          OBJECT          obj;            /* mesh triangle ID */
26          FVECT           vn[3];          /* normals */
27 <        FLOAT           vc[3][2];       /* uv coords. */
27 >        RREAL           vc[3][2];       /* uv coords. */
28   } TRIDATA;
29  
30   #define tdsize(fl)      ((fl)&MT_UV ? sizeof(TRIDATA) : \
31 <                                (fl)&MT_N ? sizeof(TRIDATA)-2*sizeof(FLOAT) : \
31 >                                (fl)&MT_N ? sizeof(TRIDATA)-6*sizeof(RREAL) : \
32                                  sizeof(int)+sizeof(OBJECT))
33  
34   #define  OMARGIN        (10*FTINY)      /* margin around global cube */
# Line 36 | Line 37 | MESH   *ourmesh = NULL;                /* our global mesh data structu
37  
38   FVECT   meshbounds[2];                  /* mesh bounding box */
39  
40 + static void add2bounds(FVECT vp, RREAL vc[2]);
41 + static OBJECT cvmeshtri(OBJECT obj);
42 + static OCTREE cvmeshoct(OCTREE ot);
43  
44 +
45 +
46   MESH *
47 < cvinit(nm)                      /* initialize empty mesh */
48 < char    *nm;
47 > cvinit(                 /* initialize empty mesh */
48 >        char    *nm
49 > )
50   {
51                                  /* free old mesh, first */
52          if (ourmesh != NULL) {
# Line 68 | Line 75 | nomem:
75   }
76  
77  
71 int
72 cvpoly(n, vp, vn, vc)           /* convert a polygon to extended triangles */
73 int     n;
74 FVECT   *vp;
75 FVECT   *vn;
76 FLOAT   (*vc)[2];
77 {
78        int     tcnt = 0;
79        int     flags;
80        FLOAT   *tn[3], *tc[3];
81        int     *ord;
82        int     i, j;
83
84        if (n < 3)              /* degenerate face */
85                return(0);
86        flags = MT_V;
87        if (vn != NULL) {
88                tn[0] = vn[0]; tn[1] = vn[1]; tn[2] = vn[2];
89                flags |= MT_N;
90        } else {
91                tn[0] = tn[1] = tn[2] = NULL;
92        }
93        if (vc != NULL) {
94                tc[0] = vc[0]; tc[1] = vc[1]; tc[2] = vc[2];
95                flags |= MT_UV;
96        } else {
97                tc[0] = tc[1] = tc[2] = NULL;
98        }
99        if (n == 3)             /* output single triangle */
100                return(cvtri(vp[0], vp[1], vp[2],
101                                tn[0], tn[1], tn[2],
102                                tc[0], tc[1], tc[2]));
103
104                                /* decimate polygon (assumes convex) */
105        ord = (int *)malloc(n*sizeof(int));
106        if (ord == NULL)
107                error(SYSTEM, "out of memory in cvpoly");
108        for (i = n; i--; )
109                ord[i] = i;
110        while (n >= 3) {
111                if (flags & MT_N)
112                        for (i = 3; i--; )
113                                tn[i] = vn[ord[i]];
114                if (flags & MT_UV)
115                        for (i = 3; i--; )
116                                tc[i] = vc[ord[i]];
117                i = cvtri(vp[ord[0]], vp[ord[1]], vp[ord[2]],
118                                tn[0], tn[1], tn[2],
119                                tc[0], tc[1], tc[2]);
120                if (i < 0)
121                        return(i);
122                tcnt += i;
123                        /* remove vertex and rotate */
124                n--;
125                j = ord[0];
126                for (i = 0; i < n-1; i++)
127                        ord[i] = ord[i+2];
128                ord[i] = j;
129        }
130        free((void *)ord);
131        return(tcnt);
132 }
133
134
78   static void
79 < add2bounds(vp, vc)              /* add point and uv coordinate to bounds */
80 < FVECT   vp;
81 < FLOAT   vc[2];
79 > add2bounds(             /* add point and uv coordinate to bounds */
80 >        FVECT   vp,
81 >        RREAL   vc[2]
82 > )
83   {
84          register int    j;
85  
# Line 157 | Line 101 | FLOAT  vc[2];
101  
102  
103   int                             /* create an extended triangle */
104 < cvtri(vp1, vp2, vp3, vn1, vn2, vn3, vc1, vc2, vc3)
105 < FVECT   vp1, vp2, vp3;
106 < FVECT   vn1, vn2, vn3;
107 < FLOAT   vc1[2], vc2[2], vc3[2];
104 > cvtri(
105 >        OBJECT  mo,
106 >        FVECT   vp1,
107 >        FVECT   vp2,
108 >        FVECT   vp3,
109 >        FVECT   vn1,
110 >        FVECT   vn2,
111 >        FVECT   vn3,
112 >        RREAL   vc1[2],
113 >        RREAL   vc2[2],
114 >        RREAL   vc3[2]
115 > )
116   {
117 <        char    buf[32];
118 <        int     flags;
119 <        TRIDATA *ts;
120 <        OBJECT  fobj;
121 <        FACE    *f;
122 <        OBJREC  *fop;
123 <        int     j;
117 >        static OBJECT   fobj = OVOID;
118 >        char            buf[32];
119 >        int             flags;
120 >        TRIDATA         *ts;
121 >        FACE            *f;
122 >        OBJREC          *fop;
123 >        int             j;
124          
125 <        flags = MT_V;
126 <        if (vn1 != NULL && vn2 != NULL && vn3 != NULL)
127 <                flags |= MT_N;
125 >        flags = MT_V;           /* check what we have */
126 >        if (vn1 != NULL && vn2 != NULL && vn3 != NULL) {
127 >                RREAL   *rp;
128 >                switch (flat_tri(vp1, vp2, vp3, vn1, vn2, vn3)) {
129 >                case ISBENT:
130 >                        flags |= MT_N;
131 >                        /* fall through */
132 >                case ISFLAT:
133 >                        break;
134 >                case RVBENT:
135 >                        flags |= MT_N;
136 >                        rp = vn1; vn1 = vn3; vn3 = rp;
137 >                        /* fall through */
138 >                case RVFLAT:
139 >                        rp = vp1; vp1 = vp3; vp3 = rp;
140 >                        rp = vc1; vc1 = vc3; vc3 = rp;
141 >                        break;
142 >                case DEGEN:
143 >                        error(WARNING, "degenerate triangle");
144 >                        return(0);
145 >                default:
146 >                        error(INTERNAL, "bad return from flat_tri()");
147 >                }
148 >        }
149          if (vc1 != NULL && vc2 != NULL && vc3 != NULL)
150                  flags |= MT_UV;
151 <                                /* create extended triangle */
152 <        fobj = newobject();
153 <        if (fobj == OVOID)
154 <                return(-1);
155 <        fop = objptr(fobj);
156 <        fop->omod = OVOID;
157 <        fop->otype = OBJ_FACE;
158 <        sprintf(buf, "t%d", fobj);
159 <        fop->oname = savqstr(buf);
160 <        fop->oargs.nfargs = 9;
161 <        fop->oargs.farg = (FLOAT *)malloc(9*sizeof(FLOAT));
162 <        if (fop->oargs.farg == NULL)
163 <                goto nomem;
151 >        if (fobj == OVOID) {    /* create new triangle object */
152 >                fobj = newobject();
153 >                if (fobj == OVOID)
154 >                        goto nomem;
155 >                fop = objptr(fobj);
156 >                fop->omod = mo;
157 >                fop->otype = OBJ_FACE;
158 >                sprintf(buf, "t%ld", (long)fobj);
159 >                fop->oname = savqstr(buf);
160 >                fop->oargs.nfargs = 9;
161 >                fop->oargs.farg = (RREAL *)malloc(9*sizeof(RREAL));
162 >                if (fop->oargs.farg == NULL)
163 >                        goto nomem;
164 >        } else {                /* else reuse failed one */
165 >                fop = objptr(fobj);
166 >                if (fop->otype != OBJ_FACE || fop->oargs.nfargs != 9)
167 >                        error(CONSISTENCY, "code error 1 in cvtri");
168 >        }
169          for (j = 3; j--; ) {
170                  fop->oargs.farg[j] = vp1[j];
171                  fop->oargs.farg[3+j] = vp2[j];
172                  fop->oargs.farg[6+j] = vp3[j];
173          }
174                                  /* create face record */
175 <        if ((f = getface(fop)) == NULL || f->area == 0.) {
176 <                freeobjects(fobj, 1);
175 >        f = getface(fop);
176 >        if (f->area == 0.) {
177 >                free_os(fop);
178                  return(0);
179          }
180          if (fop->os != (char *)f)
181 <                error(CONSISTENCY, "code error in cvtri");
181 >                error(CONSISTENCY, "code error 2 in cvtri");
182                                  /* follow with auxliary data */
183          f = (FACE *)realloc((void *)f, sizeof(FACE)+tdsize(flags));
184          if (f == NULL)
# Line 226 | Line 205 | FLOAT  vc1[2], vc2[2], vc3[2];
205          add2bounds(vp1, vc1);
206          add2bounds(vp2, vc2);
207          add2bounds(vp3, vc3);
208 +        fobj = OVOID;           /* we used this one */
209          return(1);
210   nomem:
211          error(SYSTEM, "out of memory in cvtri");
# Line 234 | Line 214 | nomem:
214  
215  
216   static OBJECT
217 < cvmeshtri(obj)                  /* add an extended triangle to our mesh */
218 < OBJECT  obj;
217 > cvmeshtri(                      /* add an extended triangle to our mesh */
218 >        OBJECT  obj
219 > )
220   {
221          OBJREC          *o = objptr(obj);
222          TRIDATA         *ts;
# Line 263 | Line 244 | OBJECT obj;
244                  for (i = 3; i--; )
245                          for (j = 2; j--; )
246                                  vert[i].uv[j] = ts->vc[i][j];
247 <        ts->obj = addmeshtri(ourmesh, vert);
247 >        ts->obj = addmeshtri(ourmesh, vert, o->omod);
248          if (ts->obj == OVOID)
249                  error(INTERNAL, "addmeshtri failed");
250          return(ts->obj);
# Line 271 | Line 252 | OBJECT obj;
252  
253  
254   void
255 < cvmeshbounds()                  /* set mesh boundaries */
255 > cvmeshbounds(void)                      /* set mesh boundaries */
256   {
257          int     i;
258  
# Line 279 | Line 260 | cvmeshbounds()                 /* set mesh boundaries */
260                  return;
261                                  /* fix coordinate bounds */
262          for (i = 0; i < 3; i++) {
263 <                if (meshbounds[0][i] >= meshbounds[1][i])
263 >                if (meshbounds[0][i] > meshbounds[1][i])
264                          error(USER, "no polygons in mesh");
265                  meshbounds[0][i] -= OMARGIN;
266                  meshbounds[1][i] += OMARGIN;
# Line 295 | Line 276 | cvmeshbounds()                 /* set mesh boundaries */
276                  ourmesh->uvlim[1][0] = ourmesh->uvlim[1][1] = 0.;
277          } else {
278                  for (i = 0; i < 2; i++) {
279 <                        double  marg;
280 <                        marg = 1e-6*(ourmesh->uvlim[1][i] -
281 <                                        ourmesh->uvlim[0][i]);
279 >                        double  marg;           /* expand past endpoints */
280 >                        marg = (2./(1L<<(8*sizeof(uint16)))) *
281 >                                        (ourmesh->uvlim[1][i] -
282 >                                         ourmesh->uvlim[0][i]) + FTINY;
283                          ourmesh->uvlim[0][i] -= marg;
284                          ourmesh->uvlim[1][i] += marg;
285                  }
# Line 307 | Line 289 | cvmeshbounds()                 /* set mesh boundaries */
289  
290  
291   static OCTREE
292 < cvmeshoct(ot)                   /* convert triangles in subtree */
293 < OCTREE  ot;
292 > cvmeshoct(                      /* convert triangles in subtree */
293 >        OCTREE  ot
294 > )
295   {
296          int     i;
297  
# Line 332 | Line 315 | OCTREE ot;
315  
316  
317   MESH *
318 < cvmesh()                        /* convert mesh and octree leaf nodes */
318 > cvmesh(void)                    /* convert mesh and octree leaf nodes */
319   {
320          if (ourmesh == NULL)
321                  return(NULL);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines