| 460 |
|
++nfound; |
| 461 |
|
} |
| 462 |
|
} |
| 463 |
+ |
if (verbose) |
| 464 |
+ |
fprintf(stderr, "Found %d duplicate faces\n", nfound); |
| 465 |
|
return(nfound); |
| 466 |
|
} |
| 467 |
|
|
| 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) |
| 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; |
| 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) + |
| 775 |
|
sc->flist = f; |
| 776 |
|
sc->nfaces++; |
| 777 |
|
} |
| 778 |
+ |
deleteUnreferenced(sc); /* jetsam */ |
| 779 |
|
return(sc); |
| 780 |
|
} |
| 781 |
|
|
| 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 |