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.29 by greg, Tue Nov 27 00:42:26 2018 UTC vs.
Revision 2.37 by greg, Thu Dec 12 23:04:31 2024 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 74 | Line 72 | cvcmp(const char *vv1, const char *vv2)                /* compare en
72  
73  
74   MESH *
75 < getmesh(                                /* get new mesh data reference */
75 > getmesh(                                /* get mesh data reference */
76          char    *mname,
77          int     flags
78   )
# Line 84 | Line 82 | getmesh(                               /* get new mesh data reference */
82  
83          flags &= IO_LEGAL;
84          for (ms = mlist; ms != NULL; ms = ms->next)
85 <                if (!strcmp(mname, ms->name)) {
88 <                        ms->nref++;     /* increase reference count */
85 >                if (!strcmp(mname, ms->name))
86                          break;
87 <                }
91 <        if (ms == NULL) {               /* load first time */
87 >        if (ms == NULL) {               /* new mesh entry? */
88                  ms = (MESH *)calloc(1, sizeof(MESH));
89                  if (ms == NULL)
90                          error(SYSTEM, "out of memory in getmesh");
91                  ms->name = savestr(mname);
96                ms->nref = 1;
92                  ms->mcube.cutree = EMPTY;
93                  ms->next = mlist;
94                  mlist = ms;
95          }
96 +        ms->nref++;                     /* bump reference count */
97 +        if (!(flags &= ~ms->ldflags))   /* nothing to load? */
98 +                return(ms);
99          if ((pathname = getpath(mname, getrlibpath(), R_OK)) == NULL) {
100                  sprintf(errmsg, "cannot find mesh file \"%s\"", mname);
101                  error(SYSTEM, errmsg);
102          }
103 <        flags &= ~ms->ldflags;
106 <        if (flags)
107 <                readmesh(ms, pathname, flags);
103 >        readmesh(ms, pathname, flags);
104          return(ms);
105   }
106  
# Line 287 | Line 283 | getmeshpseudo(                 /* get mesh pseudo object for materia
283          OBJECT  mo
284   )
285   {
286 <        if (mo < mp->mat0 || mo >= mp->mat0 + mp->nmats)
286 >        if ((mo < mp->mat0) | (mo >= mp->mat0 + mp->nmats))
287                  error(INTERNAL, "modifier out of range in getmeshpseudo");
288          if (mp->pseudo == NULL) {
289                  int     i;
# Line 374 | Line 370 | addmeshvert(                   /* find/add a mesh vertex */
370                  goto nomem;
371          if (lvp->key == NULL) {
372                  lvp->key = (char *)malloc(sizeof(MCVERT)+sizeof(int32));
373 <                memcpy((void *)lvp->key, (void *)&cv, sizeof(MCVERT));
373 >                memcpy(lvp->key, &cv, sizeof(MCVERT));
374          }
375          if (lvp->data == NULL) {        /* new vertex */
376                  MESHPATCH       *pp;
# Line 385 | Line 381 | addmeshvert(                   /* find/add a mesh vertex */
381                                  goto nomem;
382                          mp->npatches = 1;
383                  } else if (mp->patch[mp->npatches-1].nverts >= 256) {
384 +                        if (mp->npatches >= 1L<<22)
385 +                                error(INTERNAL, "too many mesh patches");
386                          if (mp->npatches % MPATCHBLKSIZ == 0) {
387 <                                mp->patch = (MESHPATCH *)realloc(
388 <                                                (void *)mp->patch,
389 <                                        (mp->npatches + MPATCHBLKSIZ)*
390 <                                                sizeof(MESHPATCH));
393 <                                memset((void *)(mp->patch + mp->npatches), '\0',
387 >                                mp->patch = (MESHPATCH *)realloc(mp->patch,
388 >                                                (mp->npatches + MPATCHBLKSIZ)*
389 >                                                        sizeof(MESHPATCH));
390 >                                memset((mp->patch + mp->npatches), '\0',
391                                          MPATCHBLKSIZ*sizeof(MESHPATCH));
392                          }
393 <                        if (mp->npatches++ >= 1L<<22)
397 <                                error(INTERNAL, "too many mesh patches");
393 >                        mp->npatches++;
394                  }
395                  pp = &mp->patch[mp->npatches-1];
396                  if (pp->xyz == NULL) {
# Line 552 | Line 548 | checkmesh(MESH *mp)                    /* validate mesh data */
548   {
549          static char     embuf[128];
550          int             nouvbounds = 1;
551 <        int             i;
551 >        int             i, j;
552                                          /* basic checks */
553          if (mp == NULL)
554                  return("NULL mesh pointer");
# Line 574 | Line 570 | checkmesh(MESH *mp)                    /* validate mesh data */
570                  if (isempty(mp->mcube.cutree))
571                          error(WARNING, "empty mesh octree");
572          }
573 <                                        /* check scene data */
573 >                                        /* check patch data */
574          if (mp->ldflags & IO_SCENE) {
575 +                MESHVERT        mv;
576                  if (!(mp->ldflags & IO_BOUNDS))
577                          return("unbounded scene in mesh");
578                  if (mp->mat0 < 0 || mp->mat0+mp->nmats > nobjects)
579                          return("bad mesh modifier range");
580 +                if (mp->nmats > 0)      /* allocate during preload_objs()! */
581 +                        getmeshpseudo(mp, mp->mat0);
582                  for (i = mp->mat0+mp->nmats; i-- > mp->mat0; ) {
583                          int     otyp = objptr(i)->otype;
584                          if (!ismodifier(otyp)) {
# Line 601 | Line 600 | checkmesh(MESH *mp)                    /* validate mesh data */
600                                  if (nouvbounds && pp->uv != NULL)
601                                          return("unreferenced uv coordinates");
602                          }
603 <                        if (pp->ntris > 0 && pp->tri == NULL)
604 <                                return("missing patch triangle list");
605 <                        if (pp->nj1tris > 0 && pp->j1tri == NULL)
606 <                                return("missing patch joiner triangle list");
607 <                        if (pp->nj2tris > 0 && pp->j2tri == NULL)
608 <                                return("missing patch double-joiner list");
603 >                        if (pp->ntris > 0) {
604 >                                struct PTri     *tp = pp->tri;
605 >                                if (tp == NULL)
606 >                                        return("missing patch triangle list");
607 >                                if (mp->nmats <= 0)
608 >                                        j = -1;
609 >                                else if (pp->trimat == NULL)
610 >                                        j = ((pp->solemat < 0) | (pp->solemat >= mp->nmats)) - 1;
611 >                                else
612 >                                        for (j = pp->ntris; j--; )
613 >                                                if ((pp->trimat[j] < 0) |
614 >                                                                (pp->trimat[j] >= mp->nmats))
615 >                                                        break;
616 >                                if (j >= 0)
617 >                                        return("bad local triangle material");
618 >                                for (j = pp->ntris; j--; tp++)
619 >                                        if ((tp->v1 >= pp->nverts) | (tp->v2 >= pp->nverts) |
620 >                                                        (tp->v3 >= pp->nverts))
621 >                                                return("bad local triangle index");
622 >                        }
623 >                        if (pp->nj1tris > 0) {
624 >                                struct PJoin1   *j1p = pp->j1tri;
625 >                                if (j1p == NULL)
626 >                                        return("missing patch joiner triangle list");
627 >                                for (j = pp->nj1tris; j--; j1p++) {
628 >                                        if (mp->nmats > 0 &&
629 >                                                        (j1p->mat < 0) | (j1p->mat >= mp->nmats))
630 >                                                return("bad j1 triangle material");
631 >                                        if (!getmeshvert(&mv, mp, j1p->v1j, MT_V))
632 >                                                return("bad j1 triangle joiner");
633 >                                        if ((j1p->v2 >= pp->nverts) | (j1p->v3 >= pp->nverts))
634 >                                                return("bad j1 triangle local index");
635 >                                }
636 >                        }
637 >                        if (pp->nj2tris > 0) {
638 >                                struct PJoin2   *j2p = pp->j2tri;
639 >                                if (j2p == NULL)
640 >                                        return("missing patch double-joiner list");
641 >                                for (j = pp->nj2tris; j--; j2p++) {
642 >                                        if (mp->nmats > 0 &&
643 >                                                        (j2p->mat < 0) | (j2p->mat >= mp->nmats))
644 >                                                return("bad j2 triangle material");
645 >                                        if (!getmeshvert(&mv, mp, j2p->v1j, MT_V) |
646 >                                                        !getmeshvert(&mv, mp, j2p->v2j, MT_V))
647 >                                                return("bad j2 triangle joiner");
648 >                                        if (j2p->v3 >= pp->nverts)
649 >                                                return("bad j2 triangle local index");
650 >                                }
651 >                        }
652                  }
653          }
654 <        return(NULL);                   /* seems OK */
654 >        return(NULL);                   /* seems to be self-consistent */
655   }
656  
657  
# Line 726 | Line 768 | freemesh(MESH *ms)             /* free mesh data */
768                  MESHPATCH       *pp = ms->patch + ms->npatches;
769                  while (pp-- > ms->patch) {
770                          if (pp->j2tri != NULL)
771 <                                free((void *)pp->j2tri);
771 >                                free(pp->j2tri);
772                          if (pp->j1tri != NULL)
773 <                                free((void *)pp->j1tri);
773 >                                free(pp->j1tri);
774                          if (pp->tri != NULL)
775 <                                free((void *)pp->tri);
775 >                                free(pp->tri);
776                          if (pp->uv != NULL)
777 <                                free((void *)pp->uv);
777 >                                free(pp->uv);
778                          if (pp->norm != NULL)
779 <                                free((void *)pp->norm);
779 >                                free(pp->norm);
780                          if (pp->xyz != NULL)
781 <                                free((void *)pp->xyz);
781 >                                free(pp->xyz);
782 >                        if (pp->trimat != NULL)
783 >                                free(pp->trimat);
784                  }
785 <                free((void *)ms->patch);
785 >                free(ms->patch);
786          }
787          if (ms->pseudo != NULL)
788 <                free((void *)ms->pseudo);
789 <        free((void *)ms);
788 >                free(ms->pseudo);
789 >        free(ms);
790   }
791  
792  
# Line 752 | Line 796 | freemeshinst(OBJREC *o)                /* free mesh instance */
796          if (o->os == NULL)
797                  return;
798          freemesh((*(MESHINST *)o->os).msh);
799 <        free((void *)o->os);
799 >        free(o->os);
800          o->os = NULL;
801   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines