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

Comparing ray/src/common/mesh.c (file contents):
Revision 2.25 by greg, Tue Nov 6 01:56:37 2012 UTC vs.
Revision 2.34 by greg, Tue Jul 14 23:13:50 2020 UTC

# Line 5 | Line 5 | static const char RCSid[] = "$Id$";
5   * Mesh support routines
6   */
7  
8 #include <string.h>
9
8   #include "rtio.h"
9   #include "rtmath.h"
10   #include "rterror.h"
# Line 52 | Line 50 | static int
50   cvcmp(const char *vv1, const char *vv2)         /* compare encoded vertices */
51   {
52          const MCVERT    *v1 = (const MCVERT *)vv1, *v2 = (const MCVERT *)vv2;
53 +
54          if (v1->fl != v2->fl)
55                  return(1);
56          if (v1->xyz[0] != v2->xyz[0])
# Line 99 | Line 98 | getmesh(                               /* get new mesh data reference */
98          }
99          if ((pathname = getpath(mname, getrlibpath(), R_OK)) == NULL) {
100                  sprintf(errmsg, "cannot find mesh file \"%s\"", mname);
101 <                error(USER, errmsg);
101 >                error(SYSTEM, errmsg);
102          }
103          flags &= ~ms->ldflags;
104          if (flags)
# Line 148 | Line 147 | nextmeshtri(                           /* get next triangle ID */
147          MESH *mp
148   )
149   {
151        int             advance = 1;
150          int             pn;
151          MESHPATCH       *pp;
152  
153 <        if (*tip == OVOID) {                    /* check for first index */
156 <                *tip = 0;
157 <                advance = 0;
158 <        }
159 <        pn = *tip >> 10;
153 >        pn = ++(*tip) >> 10;                    /* next triangle (OVOID init) */
154          while (pn < mp->npatches) {
155                  pp = &mp->patch[pn];
156                  if (!(*tip & 0x200)) {          /* local triangle? */
157 <                        if ((*tip & 0x1ff) < pp->ntris - advance) {
164 <                                *tip += advance;
157 >                        if ((*tip & 0x1ff) < pp->ntris)
158                                  return(1);
166                        }
159                          *tip &= ~0x1ff;         /* move on to single-joiners */
160                          *tip |= 0x200;
169                        advance = 0;
161                  }
162                  if (!(*tip & 0x100)) {          /* single joiner? */
163 <                        if ((*tip & 0xff) < pp->nj1tris - advance) {
173 <                                *tip += advance;
163 >                        if ((*tip & 0xff) < pp->nj1tris)
164                                  return(1);
175                        }
165                          *tip &= ~0xff;          /* move on to double-joiners */
166                          *tip |= 0x100;
178                        advance = 0;
167                  }
168 <                if ((*tip & 0xff) < pp->nj2tris - advance) {
181 <                        *tip += advance;
168 >                if ((*tip & 0xff) < pp->nj2tris)
169                          return(1);
183                }
170                  *tip = ++pn << 10;              /* first in next patch */
185                advance = 0;
171          }
172          return(0);                              /* out of patches */
173   }
# Line 300 | Line 285 | getmeshpseudo(                 /* get mesh pseudo object for materia
285          OBJECT  mo
286   )
287   {
288 <        if (mo < mp->mat0 || mo >= mp->mat0 + mp->nmats)
288 >        if ((mo < mp->mat0) | (mo >= mp->mat0 + mp->nmats))
289                  error(INTERNAL, "modifier out of range in getmeshpseudo");
290          if (mp->pseudo == NULL) {
291                  int     i;
# Line 341 | Line 326 | getmeshtri(                    /* get triangle vertices */
326  
327   int32
328   addmeshvert(                    /* find/add a mesh vertex */
329 <        MESH    *mp,
329 >        MESH            *mp,
330          MESHVERT        *vp
331   )
332   {
333 <        LUENT           *lvp;
334 <        MCVERT          cv;
333 >        LUENT   *lvp;
334 >        MCVERT  cv;
335          int     i;
336  
337          if (!(vp->fl & MT_V))
# Line 387 | Line 372 | addmeshvert(                   /* find/add a mesh vertex */
372                  goto nomem;
373          if (lvp->key == NULL) {
374                  lvp->key = (char *)malloc(sizeof(MCVERT)+sizeof(int32));
375 <                memcpy((void *)lvp->key, (void *)&cv, sizeof(MCVERT));
375 >                memcpy(lvp->key, &cv, sizeof(MCVERT));
376          }
377          if (lvp->data == NULL) {        /* new vertex */
378                  MESHPATCH       *pp;
# Line 398 | Line 383 | addmeshvert(                   /* find/add a mesh vertex */
383                                  goto nomem;
384                          mp->npatches = 1;
385                  } else if (mp->patch[mp->npatches-1].nverts >= 256) {
386 +                        if (mp->npatches >= 1L<<22)
387 +                                error(INTERNAL, "too many mesh patches");
388                          if (mp->npatches % MPATCHBLKSIZ == 0) {
389 <                                mp->patch = (MESHPATCH *)realloc(
390 <                                                (void *)mp->patch,
391 <                                        (mp->npatches + MPATCHBLKSIZ)*
392 <                                                sizeof(MESHPATCH));
406 <                                memset((void *)(mp->patch + mp->npatches), '\0',
389 >                                mp->patch = (MESHPATCH *)realloc(mp->patch,
390 >                                                (mp->npatches + MPATCHBLKSIZ)*
391 >                                                        sizeof(MESHPATCH));
392 >                                memset((mp->patch + mp->npatches), '\0',
393                                          MPATCHBLKSIZ*sizeof(MESHPATCH));
394                          }
395 <                        if (mp->npatches++ >= 1L<<22)
410 <                                error(INTERNAL, "too many mesh patches");
395 >                        mp->npatches++;
396                  }
397                  pp = &mp->patch[mp->npatches-1];
398                  if (pp->xyz == NULL) {
# Line 453 | Line 438 | addmeshtri(                    /* add a new mesh triangle */
438          OBJECT          mo
439   )
440   {
441 <        int32                   vid[3], t;
442 <        int                     pn[3], i;
441 >        int32           vid[3], t;
442 >        int             pn[3], i;
443          MESHPATCH       *pp;
444  
445          if (!(tv[0].fl & tv[1].fl & tv[2].fl & MT_V))
# Line 473 | Line 458 | addmeshtri(                    /* add a new mesh triangle */
458                          error(INTERNAL, "modifier range error in addmeshtri");
459          }
460                                  /* assign triangle */
461 <        if (pn[0] == pn[1] && pn[1] == pn[2]) { /* local case */
461 >        if ((pn[0] == pn[1]) & (pn[1] == pn[2])) {      /* local case */
462                  pp = &mp->patch[pn[0]];
463                  if (pp->tri == NULL) {
464                          pp->tri = (struct PTri *)malloc(
# Line 499 | Line 484 | addmeshtri(                    /* add a new mesh triangle */
484                                  pp->trimat[pp->ntris] = mo;
485                          return(pn[0] << 10 | pp->ntris++);
486                  }
487 <        }
503 <        if (pn[0] == pn[1]) {
487 >        } else if (pn[0] == pn[1]) {
488                  t = vid[2]; vid[2] = vid[1]; vid[1] = vid[0]; vid[0] = t;
489                  i = pn[2]; pn[2] = pn[1]; pn[1] = pn[0]; pn[0] = i;
490          } else if (pn[0] == pn[2]) {
# Line 524 | Line 508 | addmeshtri(                    /* add a new mesh triangle */
508                  }
509          }
510                                                  /* double link */
511 <        pp = &mp->patch[pn[2]];
511 >        pp = &mp->patch[pn[i=0]];
512 >        if (mp->patch[pn[1]].nj2tris < pp->nj2tris)
513 >                pp = &mp->patch[pn[i=1]];
514 >        if (mp->patch[pn[2]].nj2tris < pp->nj2tris)
515 >                pp = &mp->patch[pn[i=2]];
516 >        if (pp->nj2tris >= 256)
517 >                error(INTERNAL, "too many patch triangles in addmeshtri");
518          if (pp->j2tri == NULL) {
519                  pp->j2tri = (struct PJoin2 *)malloc(
520                                          256*sizeof(struct PJoin2));
521                  if (pp->j2tri == NULL)
522                          goto nomem;
523          }
534        if (pp->nj2tris >= 256)
535                error(INTERNAL, "too many patch triangles in addmeshtri");
536        pp->j2tri[pp->nj2tris].v1j = vid[0];
537        pp->j2tri[pp->nj2tris].v2j = vid[1];
538        pp->j2tri[pp->nj2tris].v3 = vid[2] & 0xff;
524          pp->j2tri[pp->nj2tris].mat = mo;
525 <        return(pn[2] << 10 | 0x300 | pp->nj2tris++);
525 >        switch (i) {
526 >        case 0:
527 >                pp->j2tri[pp->nj2tris].v3 = vid[0] & 0xff;
528 >                pp->j2tri[pp->nj2tris].v1j = vid[1];
529 >                pp->j2tri[pp->nj2tris].v2j = vid[2];
530 >                return(pn[0] << 10 | 0x300 | pp->nj2tris++);
531 >        case 1:
532 >                pp->j2tri[pp->nj2tris].v2j = vid[0];
533 >                pp->j2tri[pp->nj2tris].v3 = vid[1] & 0xff;
534 >                pp->j2tri[pp->nj2tris].v1j = vid[2];
535 >                return(pn[1] << 10 | 0x300 | pp->nj2tris++);
536 >        case 2:
537 >                pp->j2tri[pp->nj2tris].v1j = vid[0];
538 >                pp->j2tri[pp->nj2tris].v2j = vid[1];
539 >                pp->j2tri[pp->nj2tris].v3 = vid[2] & 0xff;
540 >                return(pn[2] << 10 | 0x300 | pp->nj2tris++);
541 >        }
542   nomem:
543          error(SYSTEM, "out of memory in addmeshtri");
544          return(OVOID);
# Line 549 | Line 550 | checkmesh(MESH *mp)                    /* validate mesh data */
550   {
551          static char     embuf[128];
552          int             nouvbounds = 1;
553 <        int     i;
553 >        int             i;
554                                          /* basic checks */
555          if (mp == NULL)
556                  return("NULL mesh pointer");
# Line 577 | Line 578 | checkmesh(MESH *mp)                    /* validate mesh data */
578                          return("unbounded scene in mesh");
579                  if (mp->mat0 < 0 || mp->mat0+mp->nmats > nobjects)
580                          return("bad mesh modifier range");
581 +                if (mp->nmats > 0)      /* allocate during preload_objs()! */
582 +                        getmeshpseudo(mp, mp->mat0);
583                  for (i = mp->mat0+mp->nmats; i-- > mp->mat0; ) {
584                          int     otyp = objptr(i)->otype;
585                          if (!ismodifier(otyp)) {
# Line 723 | Line 726 | freemesh(MESH *ms)             /* free mesh data */
726                  MESHPATCH       *pp = ms->patch + ms->npatches;
727                  while (pp-- > ms->patch) {
728                          if (pp->j2tri != NULL)
729 <                                free((void *)pp->j2tri);
729 >                                free(pp->j2tri);
730                          if (pp->j1tri != NULL)
731 <                                free((void *)pp->j1tri);
731 >                                free(pp->j1tri);
732                          if (pp->tri != NULL)
733 <                                free((void *)pp->tri);
733 >                                free(pp->tri);
734                          if (pp->uv != NULL)
735 <                                free((void *)pp->uv);
735 >                                free(pp->uv);
736                          if (pp->norm != NULL)
737 <                                free((void *)pp->norm);
737 >                                free(pp->norm);
738                          if (pp->xyz != NULL)
739 <                                free((void *)pp->xyz);
739 >                                free(pp->xyz);
740 >                        if (pp->trimat != NULL)
741 >                                free(pp->trimat);
742                  }
743 <                free((void *)ms->patch);
743 >                free(ms->patch);
744          }
745          if (ms->pseudo != NULL)
746 <                free((void *)ms->pseudo);
747 <        free((void *)ms);
746 >                free(ms->pseudo);
747 >        free(ms);
748   }
749  
750  
# Line 749 | Line 754 | freemeshinst(OBJREC *o)                /* free mesh instance */
754          if (o->os == NULL)
755                  return;
756          freemesh((*(MESHINST *)o->os).msh);
757 <        free((void *)o->os);
757 >        free(o->os);
758          o->os = NULL;
759   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines