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.1 by greg, Tue Mar 11 17:08:55 2003 UTC vs.
Revision 2.9 by schorsch, Sat Mar 27 12:41:45 2004 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 57 | Line 64 | char   *nm;
64          ourmesh->nref = 1;
65          ourmesh->ldflags = 0;
66          ourmesh->mcube.cutree = EMPTY;
67 <        ourmesh->uvlim[0][0] = ourmesh->uvlim[1][0] = FHUGE;
68 <        ourmesh->uvlim[0][1] = ourmesh->uvlim[1][1] = -FHUGE;
67 >        ourmesh->uvlim[0][0] = ourmesh->uvlim[0][1] = FHUGE;
68 >        ourmesh->uvlim[1][0] = ourmesh->uvlim[1][1] = -FHUGE;
69          meshbounds[0][0] = meshbounds[0][1] = meshbounds[0][2] = FHUGE;
70          meshbounds[1][0] = meshbounds[1][1] = meshbounds[1][2] = -FHUGE;
71          return(ourmesh);
# Line 69 | Line 76 | nomem:
76  
77  
78   int
79 < cvpoly(n, vp, vn, vc)           /* convert a polygon to extended triangles */
80 < int     n;
81 < FVECT   *vp;
82 < FVECT   *vn;
83 < FLOAT   (*vc)[2];
79 > cvpoly( /* convert a polygon to extended triangles */
80 >        OBJECT  mo,
81 >        int     n,
82 >        FVECT   *vp,
83 >        FVECT   *vn,
84 >        RREAL   (*vc)[2]
85 > )
86   {
87          int     tcnt = 0;
88          int     flags;
89 <        FLOAT   *tn[3], *tc[3];
89 >        RREAL   *tn[3], *tc[3];
90          int     *ord;
91          int     i, j;
92  
# Line 97 | Line 106 | FLOAT  (*vc)[2];
106                  tc[0] = tc[1] = tc[2] = NULL;
107          }
108          if (n == 3)             /* output single triangle */
109 <                return(cvtri(vp[0], vp[1], vp[2],
109 >                return(cvtri(mo, vp[0], vp[1], vp[2],
110                                  tn[0], tn[1], tn[2],
111                                  tc[0], tc[1], tc[2]));
112  
# Line 114 | Line 123 | FLOAT  (*vc)[2];
123                  if (flags & MT_UV)
124                          for (i = 3; i--; )
125                                  tc[i] = vc[ord[i]];
126 <                i = cvtri(vp[ord[0]], vp[ord[1]], vp[ord[2]],
126 >                tcnt += cvtri(mo, vp[ord[0]], vp[ord[1]], vp[ord[2]],
127                                  tn[0], tn[1], tn[2],
128                                  tc[0], tc[1], tc[2]);
120                if (i < 0)
121                        return(i);
122                tcnt += i;
129                          /* remove vertex and rotate */
130                  n--;
131                  j = ord[0];
# Line 133 | Line 139 | FLOAT  (*vc)[2];
139  
140  
141   static void
142 < add2bounds(vp, vc)              /* add point and uv coordinate to bounds */
143 < FVECT   vp;
144 < FLOAT   vc[2];
142 > add2bounds(             /* add point and uv coordinate to bounds */
143 >        FVECT   vp,
144 >        RREAL   vc[2]
145 > )
146   {
147          register int    j;
148  
# Line 157 | Line 164 | FLOAT  vc[2];
164  
165  
166   int                             /* create an extended triangle */
167 < cvtri(vp1, vp2, vp3, vn1, vn2, vn3, vc1, vc2, vc3)
168 < FVECT   vp1, vp2, vp3;
169 < FVECT   vn1, vn2, vn3;
170 < FLOAT   vc1[2], vc2[2], vc3[2];
167 > cvtri(
168 >        OBJECT  mo,
169 >        FVECT   vp1,
170 >        FVECT   vp2,
171 >        FVECT   vp3,
172 >        FVECT   vn1,
173 >        FVECT   vn2,
174 >        FVECT   vn3,
175 >        RREAL   vc1[2],
176 >        RREAL   vc2[2],
177 >        RREAL   vc3[2]
178 > )
179   {
180 <        char    buf[32];
181 <        int     flags;
182 <        TRIDATA *ts;
183 <        OBJECT  fobj;
184 <        FACE    *f;
185 <        OBJREC  *fop;
186 <        int     j;
180 >        static OBJECT   fobj = OVOID;
181 >        char            buf[32];
182 >        int             flags;
183 >        TRIDATA         *ts;
184 >        FACE            *f;
185 >        OBJREC          *fop;
186 >        int             j;
187          
188 <        flags = MT_V;
189 <        if (vn1 != NULL && vn2 != NULL && vn3 != NULL)
190 <                flags |= MT_N;
188 >        flags = MT_V;           /* check what we have */
189 >        if (vn1 != NULL && vn2 != NULL && vn3 != NULL) {
190 >                RREAL   *rp;
191 >                switch (flat_tri(vp1, vp2, vp3, vn1, vn2, vn3)) {
192 >                case ISBENT:
193 >                        flags |= MT_N;
194 >                        /* fall through */
195 >                case ISFLAT:
196 >                        break;
197 >                case RVBENT:
198 >                        flags |= MT_N;
199 >                        rp = vn1; vn1 = vn3; vn3 = rp;
200 >                        /* fall through */
201 >                case RVFLAT:
202 >                        rp = vp1; vp1 = vp3; vp3 = rp;
203 >                        rp = vc1; vc1 = vc3; vc3 = rp;
204 >                        break;
205 >                case DEGEN:
206 >                        error(WARNING, "degenerate triangle");
207 >                        return(0);
208 >                default:
209 >                        error(INTERNAL, "bad return from flat_tri()");
210 >                }
211 >        }
212          if (vc1 != NULL && vc2 != NULL && vc3 != NULL)
213                  flags |= MT_UV;
214 <                                /* create extended triangle */
215 <        fobj = newobject();
216 <        if (fobj == OVOID)
217 <                return(-1);
218 <        fop = objptr(fobj);
219 <        fop->omod = OVOID;
220 <        fop->otype = OBJ_FACE;
221 <        sprintf(buf, "t%d", fobj);
222 <        fop->oname = savqstr(buf);
223 <        fop->oargs.nfargs = 9;
224 <        fop->oargs.farg = (FLOAT *)malloc(9*sizeof(FLOAT));
225 <        if (fop->oargs.farg == NULL)
226 <                goto nomem;
214 >        if (fobj == OVOID) {    /* create new triangle object */
215 >                fobj = newobject();
216 >                if (fobj == OVOID)
217 >                        goto nomem;
218 >                fop = objptr(fobj);
219 >                fop->omod = mo;
220 >                fop->otype = OBJ_FACE;
221 >                sprintf(buf, "t%ld", fobj);
222 >                fop->oname = savqstr(buf);
223 >                fop->oargs.nfargs = 9;
224 >                fop->oargs.farg = (RREAL *)malloc(9*sizeof(RREAL));
225 >                if (fop->oargs.farg == NULL)
226 >                        goto nomem;
227 >        } else {                /* else reuse failed one */
228 >                fop = objptr(fobj);
229 >                if (fop->otype != OBJ_FACE || fop->oargs.nfargs != 9)
230 >                        error(CONSISTENCY, "code error 1 in cvtri");
231 >        }
232          for (j = 3; j--; ) {
233                  fop->oargs.farg[j] = vp1[j];
234                  fop->oargs.farg[3+j] = vp2[j];
235                  fop->oargs.farg[6+j] = vp3[j];
236          }
237                                  /* create face record */
238 <        if ((f = getface(fop)) == NULL || f->area == 0.) {
239 <                freeobjects(fobj, 1);
238 >        f = getface(fop);
239 >        if (f->area == 0.) {
240 >                free_os(fop);
241                  return(0);
242          }
243          if (fop->os != (char *)f)
244 <                error(CONSISTENCY, "code error in cvtri");
244 >                error(CONSISTENCY, "code error 2 in cvtri");
245                                  /* follow with auxliary data */
246          f = (FACE *)realloc((void *)f, sizeof(FACE)+tdsize(flags));
247          if (f == NULL)
# Line 226 | Line 268 | FLOAT  vc1[2], vc2[2], vc3[2];
268          add2bounds(vp1, vc1);
269          add2bounds(vp2, vc2);
270          add2bounds(vp3, vc3);
271 +        fobj = OVOID;           /* we used this one */
272          return(1);
273   nomem:
274          error(SYSTEM, "out of memory in cvtri");
# Line 234 | Line 277 | nomem:
277  
278  
279   static OBJECT
280 < cvmeshtri(obj)                  /* add an extended triangle to our mesh */
281 < OBJECT  obj;
280 > cvmeshtri(                      /* add an extended triangle to our mesh */
281 >        OBJECT  obj
282 > )
283   {
284          OBJREC          *o = objptr(obj);
285          TRIDATA         *ts;
# Line 263 | Line 307 | OBJECT obj;
307                  for (i = 3; i--; )
308                          for (j = 2; j--; )
309                                  vert[i].uv[j] = ts->vc[i][j];
310 <        ts->obj = addmeshtri(ourmesh, vert);
310 >        ts->obj = addmeshtri(ourmesh, vert, o->omod);
311          if (ts->obj == OVOID)
312                  error(INTERNAL, "addmeshtri failed");
313          return(ts->obj);
# Line 271 | Line 315 | OBJECT obj;
315  
316  
317   void
318 < cvmeshbounds()                  /* set mesh boundaries */
318 > cvmeshbounds(void)                      /* set mesh boundaries */
319   {
320          int     i;
321  
# Line 279 | Line 323 | cvmeshbounds()                 /* set mesh boundaries */
323                  return;
324                                  /* fix coordinate bounds */
325          for (i = 0; i < 3; i++) {
326 <                if (meshbounds[0][i] >= meshbounds[1][i])
326 >                if (meshbounds[0][i] > meshbounds[1][i])
327                          error(USER, "no polygons in mesh");
328                  meshbounds[0][i] -= OMARGIN;
329                  meshbounds[1][i] += OMARGIN;
# Line 290 | Line 334 | cvmeshbounds()                 /* set mesh boundaries */
334          for (i = 0; i < 3; i++)
335                  ourmesh->mcube.cuorg[i] = (meshbounds[1][i]+meshbounds[0][i] -
336                                                  ourmesh->mcube.cusize)*.5;
337 <        if (ourmesh->uvlim[0][0] >= ourmesh->uvlim[1][0]) {
337 >        if (ourmesh->uvlim[0][0] > ourmesh->uvlim[1][0]) {
338                  ourmesh->uvlim[0][0] = ourmesh->uvlim[0][1] = 0.;
339                  ourmesh->uvlim[1][0] = ourmesh->uvlim[1][1] = 0.;
340          } else {
341                  for (i = 0; i < 2; i++) {
342 <                        double  marg;
343 <                        marg = 1e-6*(ourmesh->uvlim[1][i] -
344 <                                        ourmesh->uvlim[0][i]);
342 >                        double  marg;           /* expand past endpoints */
343 >                        marg = (2./(1L<<(8*sizeof(uint16)))) *
344 >                                        (ourmesh->uvlim[1][i] -
345 >                                         ourmesh->uvlim[0][i]);
346                          ourmesh->uvlim[0][i] -= marg;
347                          ourmesh->uvlim[1][i] += marg;
348                  }
# Line 307 | Line 352 | cvmeshbounds()                 /* set mesh boundaries */
352  
353  
354   static OCTREE
355 < cvmeshoct(ot)                   /* convert triangles in subtree */
356 < OCTREE  ot;
355 > cvmeshoct(                      /* convert triangles in subtree */
356 >        OCTREE  ot
357 > )
358   {
359          int     i;
360  
# Line 332 | Line 378 | OCTREE ot;
378  
379  
380   MESH *
381 < cvmesh()                        /* convert mesh and octree leaf nodes */
381 > cvmesh(void)                    /* convert mesh and octree leaf nodes */
382   {
383          if (ourmesh == NULL)
384                  return(NULL);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines