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

Comparing ray/src/common/objutil.c (file contents):
Revision 2.7 by greg, Sun Jun 14 17:44:27 2020 UTC vs.
Revision 2.11 by greg, Fri Feb 12 01:57:49 2021 UTC

# Line 460 | Line 460 | findDuplicateFaces(Scene *sc)
460                          ++nfound;
461                  }
462          }
463 +        if (verbose)
464 +                fprintf(stderr, "Found %d duplicate faces\n", nfound);
465          return(nfound);
466   }
467  
# Line 547 | Line 549 | addComment(Scene *sc, const char *comment)
549          sc->descr[sc->ndescr++] = savqstr((char *)comment);
550   }
551  
552 + /* Find index for comment containing the given string (starting from n) */
553 + int
554 + findComment(Scene *sc, const char *match, int n)
555 + {
556 +        if (n >= sc->ndescr)
557 +                return(-1);
558 +        n *= (n > 0);
559 +        while (n < sc->ndescr)
560 +                if (strstr(sc->descr[n], match) != NULL)
561 +                        return(n);
562 +        return(-1);
563 + }
564 +
565   /* Clear comments */
566   void
567   clearComments(Scene *sc)
# Line 695 | Line 710 | addFace(Scene *sc, VNDX vid[], int nv)
710          return(f);
711   }
712  
713 < /* Duplicate a scene */
713 > /* Duplicate a scene, optionally selecting faces */
714   Scene *
715 < dupScene(const Scene *osc)
715 > dupScene(const Scene *osc, int flreq, int flexc)
716   {
717 +        int             fltest = flreq | flexc;
718          Scene           *sc;
719          const Face      *fo;
720          Face            *f;
# Line 747 | Line 763 | dupScene(const Scene *osc)
763                  sc->nnorms = osc->nnorms;
764          }
765          for (fo = osc->flist; fo != NULL; fo = fo->next) {
766 +                if ((fo->flags & fltest) != flreq)
767 +                        continue;
768                  f = (Face *)emalloc(sizeof(Face) +
769                                  sizeof(VertEnt)*(fo->nv-3));
770                  memcpy((void *)f, (const void *)fo, sizeof(Face) +
# Line 757 | Line 775 | dupScene(const Scene *osc)
775                  sc->flist = f;
776                  sc->nfaces++;
777          }
778 +        deleteUnreferenced(sc);         /* jetsam */
779          return(sc);
780   }
781  
# Line 838 | Line 857 | xfmScene(Scene *sc, const char *xfm)
857          return(i);
858   }
859   #undef MAXAC
860 +
861 + /* Delete unreferenced vertices, normals, texture coords */
862 + void
863 + deleteUnreferenced(Scene *sc)
864 + {
865 +        int     *vmap;
866 +        Face    *f;
867 +        int     nused, i;
868 +                                                /* allocate index map */
869 +        if (!sc->nverts)
870 +                return;
871 +        i = sc->nverts;
872 +        if (sc->ntex > i)
873 +                i = sc->ntex;
874 +        if (sc->nnorms > i)
875 +                i = sc->nnorms;
876 +        vmap = (int *)emalloc(sizeof(int)*i);
877 +                                                /* remap positions */
878 +        for (i = nused = 0; i < sc->nverts; i++) {
879 +                if (sc->vert[i].vflist == NULL) {
880 +                        vmap[i] = -1;
881 +                        continue;
882 +                }
883 +                if (nused != i)
884 +                        sc->vert[nused] = sc->vert[i];
885 +                vmap[i] = nused++;
886 +        }
887 +        if (nused == sc->nverts)
888 +                goto skip_pos;
889 +        sc->vert = (Vertex *)erealloc((char *)sc->vert,
890 +                                sizeof(Vertex)*(nused+(CHUNKSIZ-1)));
891 +        sc->nverts = nused;
892 +        for (f = sc->flist; f != NULL; f = f->next)
893 +                for (i = f->nv; i--; )
894 +                        if ((f->v[i].vid = vmap[f->v[i].vid]) < 0)
895 +                                error(CONSISTENCY,
896 +                                        "Link error in del_unref_verts()");
897 + skip_pos:
898 +                                                /* remap texture coord's */
899 +        if (!sc->ntex)
900 +                goto skip_tex;
901 +        memset((void *)vmap, 0, sizeof(int)*sc->ntex);
902 +        for (f = sc->flist; f != NULL; f = f->next)
903 +                for (i = f->nv; i--; )
904 +                        if (f->v[i].tid >= 0)
905 +                                vmap[f->v[i].tid] = 1;
906 +        for (i = nused = 0; i < sc->ntex; i++) {
907 +                if (!vmap[i])
908 +                        continue;
909 +                if (nused != i)
910 +                        sc->tex[nused] = sc->tex[i];
911 +                vmap[i] = nused++;
912 +        }
913 +        if (nused == sc->ntex)
914 +                goto skip_tex;
915 +        sc->tex = (TexCoord *)erealloc((char *)sc->tex,
916 +                                sizeof(TexCoord)*(nused+(CHUNKSIZ-1)));
917 +        sc->ntex = nused;
918 +        for (f = sc->flist; f != NULL; f = f->next)
919 +                for (i = f->nv; i--; )
920 +                        if (f->v[i].tid >= 0)
921 +                                f->v[i].tid = vmap[f->v[i].tid];
922 + skip_tex:
923 +                                                /* remap normals */
924 +        if (!sc->nnorms)
925 +                goto skip_norms;
926 +        memset((void *)vmap, 0, sizeof(int)*sc->nnorms);
927 +        for (f = sc->flist; f != NULL; f = f->next)
928 +                for (i = f->nv; i--; )
929 +                        if (f->v[i].nid >= 0)
930 +                                vmap[f->v[i].nid] = 1;
931 +        for (i = nused = 0; i < sc->nnorms; i++) {
932 +                if (!vmap[i])
933 +                        continue;
934 +                if (nused != i)
935 +                        memcpy((void *)sc->norm[nused],
936 +                                        (void *)sc->norm[i],
937 +                                        sizeof(Normal));
938 +                vmap[i] = nused++;
939 +        }
940 +        if (nused == sc->nnorms)
941 +                goto skip_norms;
942 +        sc->norm = (Normal *)erealloc((char *)sc->norm,
943 +                                sizeof(Normal)*(nused+(CHUNKSIZ-1)));
944 +        sc->nnorms = nused;
945 +        for (f = sc->flist; f != NULL; f = f->next)
946 +                for (i = f->nv; i--; )
947 +                        if (f->v[i].nid >= 0)
948 +                                f->v[i].nid = vmap[f->v[i].nid];
949 + skip_norms:
950 +                                                /* clean up */
951 +        efree((char *)vmap);
952 + }
953  
954   /* Free a scene */
955   void

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines