X X/* copy texture vertices */ X Xif(verbflg>4) { X fprintf(stderr,"app_obj: copy %d texture vertices\n", X srcobj->size.notverts); X } X Xfor(tvcount=1;tvcountsize.notverts;tvcount++) { X if(verbflg>9) { X fprintf(stderr,"app_obj: otvindx=%d\n",otvindx); X } X dstobj->texver[otvindx]->u=srcobj->texver[tvcount]->u; X dstobj->texver[otvindx]->v=srcobj->texver[tvcount]->v; X dstobj->texver[otvindx]->w=srcobj->texver[tvcount]->w; X if((++otvindx)>=dstobj->alloc.notverts) { X fprintf(stderr, X "app_obj: too many texture vertices %d in object '%s'", X otvindx,dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for texture vertices */ X apalloc->notverts=apalloc->notverts*2; X dstobj=realc_obj(dstobj,apalloc); X } X } X X/* copy lines */ X Xif(verbflg>4) { X fprintf(stderr,"app_obj: copying %d lines\n",srcobj->size.nolines); X } X Xfor(lcount=0;lcountsize.nolines;lcount++) { X if(verbflg>10) { X fprintf(stderr,"app_obj: line %d: %d vertices\n",lcount, X srcobj->line[lcount]->vertc); X } X for(lvcnt=0;lvcntline[lcount]->vertc;lvcnt++) { X vindx=srcobj->line[lcount]->vertno[lvcnt]; X dstobj->line[olindx]->vertno[lvcnt]=vindx+ovoffset; X } X dstobj->line[olindx]->vertc=srcobj->line[lcount]->vertc; X if(lvcnt > dstobj->size.nolverts) { X dstobj->size.nolverts = lvcnt + 1; X } X /* copy material pointers */ X mtlindx=srcobj->line[lcount]->mtl; X if(verbflg>10) { X fprintf(stderr, X "app_obj: old mtl = %d, mtlptr[%d] = %d\n", X mtlindx,mtlindx,mtlptr[mtlindx]); X } X dstobj->line[olindx]->mtl=mtlptr[mtlindx]; X /* copy and re-index group pointers */ X if(appgrp > -1) { X gindx=appgrp; X glindx=dstobj->group[appgrp]->nolines; X } X else { X gindx=srcobj->line[lcount]->group; X if(verbflg>10) { X fprintf(stderr, X "app_obj: old group = %d, grpptr[%d] = %d\n", X gindx,gindx,grpptr[mtlindx]); X } X gindx=grpptr[gindx]; X glindx=dstobj->group[gindx]->nolines; X } X if(verbflg>10) { X fprintf(stderr,"app_obj: group %d, glindx = %d\n",gindx,glindx); X } X dstobj->line[olindx]->group=gindx; X dstobj->group[gindx]->lineno[glindx]=olindx; X if((++glindx)>=dstobj->alloc.noglines) { X fprintf(stderr, X "app_obj: too many lines %d, group '%s', object '%s'", X olindx,dstobj->group[gindx]->grpnam, X dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for group lines */ X apalloc->noglines=apalloc->noglines*2; X dstobj=realc_obj(dstobj,apalloc); X } X dstobj->group[gindx]->nolines=glindx; X if((++olindx)>=dstobj->alloc.nolines) { X fprintf(stderr, X "app_obj: too many lines %d in object '%s'", X olindx,dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for lines */ X apalloc->nolines=apalloc->nolines*2; X dstobj=realc_obj(dstobj,apalloc); X } X } X X X X X/* copy points */ X Xif(verbflg>4) { X fprintf(stderr,"app_obj: copying %d points\n",srcobj->size.nopoints); X } X Xfor(pcount=0;pcountsize.nopoints;pcount++) { X for(pvcnt=0;pvcntpoint[pcount]->vertc;pvcnt++) { X vindx=srcobj->point[pcount]->vertno[pvcnt]; X dstobj->point[opindx]->vertno[pvcnt]=vindx+ovoffset; X } X dstobj->point[opindx]->vertc=srcobj->point[pcount]->vertc; X if(pvcnt > dstobj->size.nopverts) { X dstobj->size.nopverts = pvcnt + 1; X } X /* copy group pointers */ X if(appgrp > -1) { X gindx=appgrp; X gpindx=dstobj->group[appgrp]->nopoints; X } X else { X gindx=srcobj->point[pcount]->group; X gindx=grpptr[gindx]; X gpindx=dstobj->group[gindx]->nopoints; X } X dstobj->point[opindx]->group=gindx; X dstobj->group[gindx]->pointno[gpindx]=opindx; X if((++gpindx)>=dstobj->alloc.nogpoints) { X fprintf(stderr, X "app_obj: too many points %d, group '%s', object '%s'", X opindx,dstobj->group[gindx]->grpnam, X dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for group pointses */ X apalloc->nogpoints=apalloc->nogpoints*2; X dstobj=realc_obj(dstobj,apalloc); X } X dstobj->group[gindx]->nopoints=gpindx; X if((++opindx)>=dstobj->alloc.nopoints) { X fprintf(stderr, X "app_obj: too many pointses %d in object '%s'", X opindx,dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for pointses */ X apalloc->nopoints=apalloc->nopoints*2; X dstobj=realc_obj(dstobj,apalloc); X } X } X X X/* copy faces */ X Xif(verbflg>9) { X fprintf(stderr,"app_obj: copy faces\n"); X } X Xfor(fcount=0;fcountsize.nofaces;fcount++) { X dstobj->face[ofindx]->smooth=srcobj->face[fcount]->smooth; X dstobj->face[ofindx]->bevel=srcobj->face[fcount]->bevel; X dstobj->face[ofindx]->mapflg=srcobj->face[fcount]->mapflg; X mapindx=srcobj->face[fcount]->map; X for(fvcnt=0;fvcntface[fcount]->vertc;fvcnt++) { X /* copy geometrical vertex pointers */ X vindx=srcobj->face[fcount]->vertno[fvcnt]; X dstobj->face[ofindx]->vertno[fvcnt]=vindx+ovoffset; X if(mapindx>(-1)) { X /* copy texture vertex pointers */ X tvindx=srcobj->face[fcount]->tvertno[fvcnt]; X dstobj->face[ofindx]->tvertno[fvcnt]=tvindx+otvofset; X } X } X dstobj->face[ofindx]->vertc=srcobj->face[fcount]->vertc; X if(fvcnt > dstobj->size.nofverts) { X dstobj->size.nofverts = fvcnt + 1; X } X /* copy material pointers */ X mtlindx=srcobj->face[fcount]->mtl; X dstobj->face[ofindx]->mtl=mtlptr[mtlindx]; X /* copy texture map pointers */ X if(mapindx>(-1)) { X dstobj->face[ofindx]->map=mapptr[mapindx]; X } X else { X dstobj->face[ofindx]->map=(-1); X } X /* copy group pointers */ X if(appgrp > -1) { X gindx=appgrp; X gfindx=dstobj->group[appgrp]->nofaces; X } X else { X gindx=srcobj->face[fcount]->group; X gindx=grpptr[gindx]; X gfindx=dstobj->group[gindx]->nofaces; X } X dstobj->face[ofindx]->group=gindx; X dstobj->group[gindx]->faceno[gfindx]=ofindx; X if((++gfindx)>=dstobj->alloc.nogfaces) { X fprintf(stderr, X "app_obj: too many faces %d, group '%s', object '%s'", X gfindx,dstobj->group[grpptr[gindx]]->grpnam, X dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for group faces */ X apalloc->nogfaces=apalloc->nogfaces*2; X dstobj=realc_obj(dstobj,apalloc); X } X dstobj->group[gindx]->nofaces=gfindx; X if((++ofindx)>=dstobj->alloc.nofaces) { X fprintf(stderr, X "app_obj: too many faces %d, object '%s'", X ofindx, dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for faces */ X apalloc->nofaces=apalloc->nofaces*2; X dstobj=realc_obj(dstobj,apalloc); X } X } X X/* copy bicubic patches */ Xfor(bicuct = 0; bicuct < srcobj->size.noptchs; bicuct++) { X X mapindx=srcobj->bicub[bicuct]->map; X /* copy vertex pointers */ X for(row = 0; row < 4; row++) { X for(col = 0; col < 4; col++) { X vindx = srcobj->bicub[bicuct]->vertno[row][col]; X dstobj->bicub[obpndx]->vertno[row][col] = vindx + ovoffset; X if(mapindx>(-1)) { X tvindx = srcobj->bicub[bicuct]->tvertno[row][col]; X dstobj->bicub[obpndx]->tvertno[row][col] = tvindx + otvofset; X } X } X } X /* copy element attributes */ X dstobj->bicub[obpndx]->type=srcobj->bicub[bicuct]->type; X dstobj->bicub[obpndx]->u_res=srcobj->bicub[bicuct]->u_res; X dstobj->bicub[obpndx]->v_res=srcobj->bicub[bicuct]->v_res; X dstobj->bicub[obpndx]->smooth=srcobj->bicub[bicuct]->smooth; X /* copy material pointers */ X mtlindx=srcobj->bicub[bicuct]->mtl; X dstobj->bicub[obpndx]->mtl=mtlptr[mtlindx]; X /* copy texture map pointers */ X if(mapindx>(-1)) { X dstobj->bicub[obpndx]->map=mapptr[mapindx]; X } X else { X dstobj->bicub[obpndx]->map=(-1); X } X /* copy group pointers */ X if(appgrp > -1) { X gindx=appgrp; X gbindx=dstobj->group[appgrp]->noptchs; X } X else { X gindx=srcobj->bicub[bicuct]->group; X gindx=grpptr[gindx]; X gbindx=dstobj->group[gindx]->noptchs; X } X dstobj->bicub[obpndx]->group=gindx; X dstobj->group[gindx]->ptchno[gbindx]=obpndx; X if((++gbindx) >= dstobj->alloc.nogptchs) { X fprintf(stderr, X "app_obj: too many patches %d, group '%s', object '%s'", X gbindx,dstobj->group[grpptr[gindx]]->grpnam, X dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for group patches */ X apalloc->nogptchs = apalloc->nogptchs * 2; X dstobj=realc_obj(dstobj,apalloc); X } X dstobj->group[gindx]->noptchs=gbindx; X if(++obpndx >= dstobj->alloc.noptchs) { X fprintf(stderr, X "app_obj: too many bicubic patches %d", X obpndx); X fprintf(stderr," in object '%s' - reallocating\n", X dstobj->size.objname); X /* double allocation for bicubic patches */ X apalloc->noptchs = apalloc->noptchs * 2; X dstobj=realc_obj(dstobj,apalloc); X } X } X X/* if flag is set, copy meta elements */ Xif(metaflg=='m') { X /* copy circles */ X for(circnt=0;circntsize.nocircs;circnt++) { X vindx = srcobj->circl[circnt]->vertno; X dstobj->circl[ocindx]->vertno = vindx + ovoffset; X dstobj->circl[ocindx]->rad=srcobj->circl[circnt]->rad; X dstobj->circl[ocindx]->res=srcobj->circl[circnt]->res; X if(++ocindx>=dstobj->alloc.nocircs) { X fprintf(stderr, X "app_obj: too many circles %d in object '%s'", X ocindx,dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for circles */ X apalloc->nocircs=apalloc->nocircs*2; X dstobj=realc_obj(dstobj,apalloc); X } X } X /* copy spheres */ X for(sphcnt=0;sphcntsize.nosphrs;sphcnt++) { X vindx = srcobj->spher[sphcnt]->vertno; X dstobj->spher[ospndx]->vertno = vindx + ovoffset; X dstobj->spher[ospndx]->rad=srcobj->spher[sphcnt]->rad; X dstobj->spher[ospndx]->res=srcobj->spher[sphcnt]->res; X dstobj->spher[ospndx]->smooth=srcobj->spher[sphcnt]->smooth; X /* copy material pointers */ X mtlindx=srcobj->spher[sphcnt]->mtl; X dstobj->spher[ospndx]->mtl=mtlptr[mtlindx]; X /* copy texture map pointers if defined */ X mapindx=srcobj->spher[sphcnt]->map; X if(mapindx>(-1)) { X dstobj->spher[ospndx]->map=mapptr[mapindx]; X } X else { X dstobj->spher[ospndx]->map=(-1); X } X if(++ospndx>=dstobj->alloc.nosphrs) { X fprintf(stderr, X "app_obj: too many spheres %d in object '%s'", X ospndx,dstobj->size.objname); X fprintf(stderr," -- reallocating\n"); X /* double allocation for spheres */ X apalloc->nosphrs=apalloc->nosphrs*2; X dstobj=realc_obj(dstobj,apalloc); X } X } X dstobj->size.nocircs=ocindx; X dstobj->size.nosphrs=ospndx; X } Xdstobj->size.noptchs=obpndx; Xdstobj->size.noverts=ovindx; Xdstobj->size.notverts=otvindx; Xdstobj->size.nosgrps=dstobj->size.nosgrps + srcobj->size.nosgrps; Xdstobj->size.nofaces=ofindx; Xdstobj->size.nopoints=opindx; Xdstobj->size.nolines=olindx; Xdstobj->size.nocalls=ocalindx; X X/* free memory allocated in this function */ Xfree(apalloc); Xapalloc = NULL; X Xif(verbflg>1) { X fprintf(stderr, X "app_obj: '%s', %d verts %d tverts %d lines %d faces %d patches\n", X dstobj->size.objname,ovindx,otvindx,olindx,ofindx,obpndx); X } X Xreturn(dstobj); X} X X X X X X X X X X/* function: add_group X X description: adds a group name to an object. Returns the index of the X group. If the group name already exists, the index of that X group is returned. X X author: Stewart Dickson X*/ X X Xint add_group(AG_dstobj,group_name) Xstruct topology *AG_dstobj; Xchar *group_name; X{ Xextern int verbflg; Xstruct topology *realc_obj(); Xstruct sizes *dstalloc; Xint gcount; Xdstalloc = NULL; X Xif(AG_dstobj == NULL) { X fprintf(stderr,"add_group: ERROR - NULL object pointer received\n"); X exit(-1); X } X Xif(group_name == NULL) { X fprintf(stderr,"add_group: ERROR - NULL group name string received\n"); X exit(-1); X } X Xif(verbflg > 1) { X fprintf(stderr,"entering add_group(%s,%s)\n", X AG_dstobj->size.objname,group_name); X } X Xfor(gcount = 0; gcount < AG_dstobj->size.nogroups; gcount++) { X /* determine if copied group is unique */ X if(!strcmp(group_name, AG_dstobj->group[gcount]->grpnam)) { X break; X } X } Xif(gcount >= AG_dstobj->size.nogroups) { X /* if it is unique */ X X if(verbflg>9) { X fprintf(stderr, X "add_group: adding group %d, '%s'\n", gcount, group_name); X } X X /* check allocation */ X if(gcount >= AG_dstobj->alloc.nogroups) { X /* allocate storage for object size parameter struct */ X dstalloc = copy_alc(AG_dstobj,dstalloc); X X fprintf(stderr, X "add_group: too many groups %d", gcount); X fprintf(stderr, X " in object '%s' -- reallocating\n", AG_dstobj->size.objname); X X /* double allocation for groups */ X dstalloc->nogroups = dstalloc->nogroups * 2; X AG_dstobj = realc_obj(AG_dstobj,dstalloc); X X /* free storage allocated in this module */ X free(dstalloc); X dstalloc = NULL; X } X /* add a new group name */ X strcpy(AG_dstobj->group[gcount]->grpnam, group_name); X AG_dstobj->size.nogroups = gcount + 1; X X } X X Xif(verbflg > 1) { X fprintf(stderr,"add_group: done\n"); X } X Xreturn(gcount); X} X X X X X X X X/* function: add_lib() X X description: Add a library name to the object. Returns the index to the X new library. If the library name already exists, that indes X is returned. X X author: Stewart Dickson X*/ X X Xint add_lib(AL_dstobj,lib_name) Xstruct topology *AL_dstobj; Xchar *lib_name; X{ Xextern int verbflg; Xstruct sizes *dstalloc = NULL, *copy_alc(); Xint libcount; X Xif(AL_dstobj == NULL) { X fprintf(stderr,"add_lib: ERROR - NULL object pointer received\n"); X exit(-1); X } X Xif(lib_name == NULL) { X fprintf(stderr,"add_lib: ERROR - NULL library name string received\n"); X exit(-1); X } X Xif(verbflg > 1) { X fprintf(stderr, X "entering add_lib(%s,%s)\n",AL_dstobj->size.objname,lib_name); X } X X/* there is always 1 library, if library 0 is set to a default */ Xif(!strcmp(AL_dstobj->lib[0]->libnam,"# no libraries used")) { X /* record new library name in dest object */ X strcpy(AL_dstobj->lib[0]->libnam,lib_name); X AL_dstobj->size.nolibs = 1; X return(0); X } X Xfor(libcount = 0; libcount < AL_dstobj->size.nolibs; libcount++) { X /* determine if copied library is unique */ X if(!strcmp(AL_dstobj->lib[libcount]->libnam,lib_name)) { X break; X } X } X Xif(libcount >= AL_dstobj->size.nolibs) { X /* if it is unique */ X X if(verbflg>9) { X fprintf(stderr, X "add_lib: adding library %d, '%s'\n", libcount, lib_name); X } X X /* check allocation and re-allocate if necessary */ X if(libcount >= AL_dstobj->alloc.nolibs) { X X /* allocate storage for object size parameter struct */ X dstalloc = copy_alc(AL_dstobj,dstalloc); X X fprintf(stderr, "add_lib: too many libraries %d", libcount); X fprintf(stderr, " in object '%s' -- reallocating\n", X AL_dstobj->size.objname); X X /* double allocation for libraries */ X dstalloc->nolibs = dstalloc->nolibs * 2; X AL_dstobj=realc_obj(AL_dstobj,dstalloc); X X /* free memory allocated in this module */ X free(dstalloc); X dstalloc = NULL; X } X /* record new library name in dest object */ X strcpy(AL_dstobj->lib[libcount]->libnam,lib_name); X AL_dstobj->size.nolibs = libcount + 1; X X } X Xif(verbflg > 1) { X fprintf(stderr,"add_lib: done\n"); X } X Xreturn(libcount); X} X X X X X X X X/* function: add_map X X description: Adds a texture map name to an object. Returns the index to X the new texture map. If the map name already exists, the X index to the existing map is returned. X X author: Stewart Dickson X*/ X Xint add_map(AM_dstobj,map_name) Xstruct topology *AM_dstobj; Xchar *map_name; X{ Xint mapcount; Xstruct sizes *dstalloc, *copy_alc(); X Xif(AM_dstobj == NULL) { X fprintf(stderr,"add_map: ERROR - NULL object pointer received\n"); X exit(-1); X } X Xif(map_name == NULL) { X fprintf(stderr,"add_map: ERROR - NULL texture map name string received\n"); X exit(-1); X } X Xif(verbflg > 1) { X fprintf(stderr, X "entering add_map(%s,%s)\n",AM_dstobj->size.objname,map_name); X } X X/* if map 0 is set to a default */ Xif(!strcmp(AM_dstobj->map[0]->mapnam,"# no mappings used")) { X strcpy(AM_dstobj->map[mapcount]->mapnam,map_name); X AM_dstobj->size.nomaps = 1; X return(0); X } X Xfor(mapcount=0; mapcount < AM_dstobj->size.nomaps; mapcount++) { X /* determine if copied mapping is unique */ X if(strcmp(AM_dstobj->map[mapcount]->mapnam,map_name)) { X break; X } X } X Xif(mapcount >= AM_dstobj->size.nomaps) { X /* if it is unique */ X X if(verbflg>9) { X fprintf(stderr,"add_map: adding texture map %d, %s\n",mapcount, X map_name); X } X X /* check allocation */ X if(mapcount >= AM_dstobj->alloc.nomaps) { X X /* allocate storage for object size parameter struct */ X dstalloc = copy_alc(AM_dstobj,dstalloc); X X fprintf(stderr, "add_map: too many mappings %d", mapcount); X fprintf(stderr, " in object '%s' -- reallocating\n", X AM_dstobj->size.objname); X X /* double allocation for texture names */ X dstalloc->nomaps = dstalloc->nomaps * 2; X AM_dstobj = realc_obj(AM_dstobj,dstalloc); X X /* free memory allocated in this module */ X free(dstalloc); X dstalloc = NULL; X } X X /* record new material in object */ X strcpy(AM_dstobj->map[mapcount]->mapnam,map_name); X AM_dstobj->size.nomaps = mapcount; X X } X Xif(verbflg > 1) { X fprintf(stderr,"add_map: done\n"); X } X Xreturn(mapcount); X} X X X X X X X X/* function: add_mtl X X description: Adds a material name to an object. Returns the index to X the new material. If the material name already exists, the X index to the existing material is returned. X X author: Stewart Dickson X*/ X Xint add_mtl(AM_dstobj,mtl_name) Xstruct topology *AM_dstobj; Xchar *mtl_name; X{ Xextern int verbflg; Xstruct sizes *dstalloc = NULL, *copy_alc(); Xint mtlcount; X Xif(AM_dstobj == NULL) { X fprintf(stderr,"add_mtl: ERROR - NULL object pointer received\n"); X exit(-1); X } X Xif(mtl_name == NULL) { X fprintf(stderr,"add_mtl: ERROR - NULL material name string received\n"); X exit(-1); X } X Xif(verbflg > 1) { X fprintf(stderr, X "entering add_mtl(%s,%s)\n",AM_dstobj->size.objname,mtl_name); X } X X/* there is always 1 material, if material 0 is set to a default */ Xif(!strcmp(AM_dstobj->mtl[0]->mtlnam,"# no materials used")) { X /* record new material name in dest object */ X strcpy(AM_dstobj->mtl[0]->mtlnam,mtl_name); X AM_dstobj->size.nomtls = 1; X return(0); X } X Xfor(mtlcount = 0; mtlcount < AM_dstobj->size.nomtls; mtlcount++) { X /* determine if copied material is unique */ X if(!strcmp(AM_dstobj->mtl[mtlcount]->mtlnam,mtl_name)) { X break; X } X } Xif(mtlcount >= AM_dstobj->size.nomtls) { X /* if it is unique */ X X if(verbflg>9) { X fprintf(stderr, X "add_mtl: adding material %d, '%s'\n",mtlcount, mtl_name); X } X X /* check allocation and re-allocate if necessary */ X if(mtlcount >= AM_dstobj->alloc.nomtls) { X /* allocate storage for object size parameter struct */ X dstalloc = copy_alc(AM_dstobj,dstalloc); X X fprintf(stderr, "add_mtl: too many materials %d", mtlcount); X fprintf(stderr, "in object '%s' -- reallocating\n", X AM_dstobj->size.objname); X X /* double allocation for materials */ X dstalloc->nomtls = dstalloc->nomtls * 2; X AM_dstobj = realc_obj(AM_dstobj,dstalloc); X X /* free memory allocated in this module */ X free(dstalloc); X dstalloc = NULL; X } X /* record new material name */ X strcpy(AM_dstobj->mtl[mtlcount]->mtlnam,mtl_name); X AM_dstobj->size.nomtls = mtlcount + 1; X X } X Xif(verbflg > 1) { X fprintf(stderr,"add_mtl: done\n"); X } X Xreturn(mtlcount); X} X X X X X X X X X/* function: copy_obj X X description: copies an object structure, destroying original contents X of destination structure. X X parameters: srcobj - object structure containing copy X elemflg - designation of type of information to copy X valid values are: X 'e' - copy simple elements only X 'm' - copy meta elements and simple elements X 'h' - copy material header information only X X return: dstobj - object structure to receive copy X X author: Stewart Dickson X*/ X X Xstruct topology *copy_obj(dstobj,srcobj,elemflg) Xstruct topology *dstobj, *srcobj; Xchar elemflg; X{ Xextern int verbflg; Xstruct topology *alloc_obj(),*realc_obj(); Xstruct sizes *CPalloc=NULL,*copy_alc(),*copy_siz(); Xint lcount=0,lvcnt=0; Xint fcount=0,fvcnt=0; Xint circnt=0,sphcnt=0,bicuct=0; Xint row,col; Xint tvcount=1,vcount=1,pcount=0,pvcnt=0; Xint sindx=(-1),mtlindx,mapindx,calindx,libindx,gindx,geindx; Xint vindx,tvindx; Xlcount=0;lvcnt=0; Xfcount=0;fvcnt=0; Xtvcount=1;vcount=1;pcount=0; X Xif(srcobj==NULL) { X fprintf(stderr,"copy_obj: ERROR - NULL source object received\n"); X exit(-1); X } X Xif(verbflg>1) { X fprintf(stderr,"entering copy_obj('%c')\n",elemflg); X } X Xif(dstobj==NULL) { X fprintf(stderr, X "copy_obj: NULL destination object received -- allocating\n"); X /* copy allocation parameters from source object */ X CPalloc=copy_alc(srcobj,CPalloc); X /* allocate an object of identical size to input object */ X dstobj=alloc_obj(CPalloc); X } Xelse { X /* copy size parameters from source object for internal use */ X if(elemflg == 'h') { /* only use header params form srcobj */ X CPalloc=copy_alc(dstobj,CPalloc); X /* copy header params if we're ony copying header */ X CPalloc->nocalls = srcobj->size.nocalls; X CPalloc->nolibs = srcobj->size.nolibs; X CPalloc->nomaps = srcobj->size.nomaps; X CPalloc->nomtls = srcobj->size.nomtls; X } X else { /* copy everything */ X CPalloc=copy_alc(srcobj,CPalloc); X } X /* reallocate to ensure we have at least the sizes of input object */ X dstobj=realc_obj(dstobj,CPalloc); X } X Xif(verbflg>0) { X fprintf(stderr,"copy_obj: copying object '%s' to '%s'\n", X srcobj->size.objname,dstobj->size.objname); X } X X/* copy 'call' directives */ Xfor(calindx=0;calindxsize.nocalls;calindx++) { X if(verbflg>9) { X fprintf(stderr,"%s\n",srcobj->call[calindx]->filnam); X } X strcpy(dstobj->call[calindx]->filnam,srcobj->call[calindx]->filnam); X } X X/* copy 'mtllib/maplib' directives */ Xfor(libindx=0;libindxsize.nolibs;libindx++) { X if(verbflg>9) { X fprintf(stderr,"%s\n",srcobj->lib[libindx]->libnam); X } X strcpy(dstobj->lib[libindx]->libnam,srcobj->lib[libindx]->libnam); X } X X/* copy materials */ Xif(verbflg>4) { X fprintf(stderr,"copy_obj: copying %d materials\n",srcobj->size.nomtls); X } Xfor(mtlindx=0;mtlindxsize.nomtls;mtlindx++) { X if(verbflg>9) { X fprintf(stderr,"%s\n",srcobj->mtl[mtlindx]->mtlnam); X } X strcpy(dstobj->mtl[mtlindx]->mtlnam,srcobj->mtl[mtlindx]->mtlnam); X } X X/* copy texture maps */ Xif(verbflg>4) { X fprintf(stderr,"copy_obj: copying %d texture maps\n", X srcobj->size.nomaps); X } X Xfor(mapindx=0;mapindxsize.nomaps;mapindx++) { X if(verbflg>9) { X fprintf(stderr,"%s\n",srcobj->map[mapindx]->mapnam); X } X strcpy(dstobj->map[mapindx]->mapnam,srcobj->map[mapindx]->mapnam); X } X X/* copy groups */ Xif(verbflg>4) { X fprintf(stderr,"copy_obj: copying %d groups\n", X srcobj->size.nogroups); X } Xfor(gindx=0;gindxsize.nogroups;gindx++) { X if(verbflg>9) { X fprintf(stderr,"copy_obj: %s ",srcobj->group[gindx]->grpnam); X } X /* copy group name */ X strcpy(dstobj->group[gindx]->grpnam,srcobj->group[gindx]->grpnam); X /* copy group vertices */ X for(geindx=0;geindxgroup[gindx]->noverts;geindx++) { X dstobj->group[gindx]->vertno[geindx] = X srcobj->group[gindx]->vertno[geindx]; X } X dstobj->group[gindx]->noverts = X srcobj->group[gindx]->noverts; X /* copy group elements */ X if(verbflg > 9) { X fprintf(stderr,"%d pointses ",srcobj->group[gindx]->nopoints); X } X for(geindx=0;geindxgroup[gindx]->nopoints;geindx++) { X dstobj->group[gindx]->pointno[geindx] = X srcobj->group[gindx]->pointno[geindx]; X } X dstobj->group[gindx]->nopoints = X srcobj->group[gindx]->nopoints; X if(verbflg > 9) { X fprintf(stderr,"%d lines ",srcobj->group[gindx]->nolines); X } X for(geindx=0;geindxgroup[gindx]->nolines;geindx++) { X dstobj->group[gindx]->lineno[geindx] = X srcobj->group[gindx]->lineno[geindx]; X } X dstobj->group[gindx]->nolines = X srcobj->group[gindx]->nolines; X if(verbflg > 9) { X fprintf(stderr,"%d faces ",srcobj->group[gindx]->nofaces); X } X for(geindx=0;geindxgroup[gindx]->nofaces;geindx++) { X dstobj->group[gindx]->faceno[geindx] = X srcobj->group[gindx]->faceno[geindx]; X } X dstobj->group[gindx]->nofaces = X srcobj->group[gindx]->nofaces; X if(verbflg > 9) { X fprintf(stderr,"%d circles ",srcobj->group[gindx]->nocircs); X } X for(geindx=0;geindxgroup[gindx]->nocircs;geindx++) { X dstobj->group[gindx]->circno[geindx] = X srcobj->group[gindx]->circno[geindx]; X } X dstobj->group[gindx]->nocircs = X srcobj->group[gindx]->nocircs; X if(verbflg > 9) { X fprintf(stderr,"%d spheres ",srcobj->group[gindx]->nosphrs); X } X for(geindx=0;geindxgroup[gindx]->nosphrs;geindx++) { X dstobj->group[gindx]->sphrno[geindx] = X srcobj->group[gindx]->sphrno[geindx]; X } X dstobj->group[gindx]->nosphrs = X srcobj->group[gindx]->nosphrs; X if(verbflg > 9) { X fprintf(stderr,"%d patches\n",srcobj->group[gindx]->noptchs); X } X for(geindx=0;geindxgroup[gindx]->noptchs;geindx++) { X dstobj->group[gindx]->ptchno[geindx] = X srcobj->group[gindx]->ptchno[geindx]; X } X dstobj->group[gindx]->noptchs = X srcobj->group[gindx]->noptchs; X } X Xif(elemflg=='e' || elemflg=='m') { X if(verbflg > 9) { X fprintf(stderr,"copy_obj: %d vertices ", X srcobj->size.noverts); X } X /* copy vertices */ X for(vcount=1;vcountsize.noverts;vcount++) { X dstobj->vertex[vcount]->mtl=srcobj->vertex[vcount]->mtl; X dstobj->vertex[vcount]->x=srcobj->vertex[vcount]->x; X dstobj->vertex[vcount]->y=srcobj->vertex[vcount]->y; X dstobj->vertex[vcount]->z=srcobj->vertex[vcount]->z; X } X X if(verbflg > 9) { X fprintf(stderr,"%d texture vertices ",srcobj->size.notverts); X } X /* copy texture vertices */ X for(tvcount=1;tvcountsize.notverts;tvcount++) { X dstobj->texver[tvcount]->u=srcobj->texver[tvcount]->u; X dstobj->texver[tvcount]->v=srcobj->texver[tvcount]->v; X dstobj->texver[tvcount]->w=srcobj->texver[tvcount]->w; X } X X if(verbflg > 9) { X fprintf(stderr,"%d lines ",srcobj->size.nolines); X } X /* copy lines */ X for(lcount=0;lcountsize.nolines;lcount++) { X for(lvcnt=0;lvcntline[lcount]->vertc;lvcnt++) { X vindx=srcobj->line[lcount]->vertno[lvcnt]; X dstobj->line[lcount]->vertno[lvcnt]=vindx; X } X if(lvcnt > dstobj->size.nolverts) { X dstobj->size.nolverts = lvcnt + 1; X } X dstobj->line[lcount]->vertc=srcobj->line[lcount]->vertc; X dstobj->line[lcount]->mtl=srcobj->line[lcount]->mtl; X dstobj->line[lcount]->group=srcobj->line[lcount]->group; X } X X if(verbflg > 9) { X fprintf(stderr,"%d pointses ",srcobj->size.nopoints); X } X /* copy points */ X for(pcount=0;pcountsize.nopoints;pcount++) { X for(pvcnt=0;pvcntpoint[pcount]->vertc;pvcnt++) { X vindx=srcobj->point[pcount]->vertno[pvcnt]; X dstobj->point[pcount]->vertno[pvcnt]=vindx; X } X if(pvcnt > dstobj->size.nopverts) { X dstobj->size.nopverts = pvcnt + 1; X } X dstobj->point[pcount]->vertc=srcobj->point[pcount]->vertc; X dstobj->point[pcount]->group=srcobj->point[pcount]->group; X } X X if(verbflg > 9) { X fprintf(stderr,"%d faces\n",srcobj->size.nofaces); X } X /* copy faces */ X for(fcount=0;fcountsize.nofaces;fcount++) { X dstobj->face[fcount]->smooth=srcobj->face[fcount]->smooth; X dstobj->face[fcount]->bevel=srcobj->face[fcount]->bevel; X dstobj->face[fcount]->mapflg=srcobj->face[fcount]->mapflg; X for(fvcnt=0;fvcntface[fcount]->vertc;fvcnt++) { X vindx=srcobj->face[fcount]->vertno[fvcnt]; X dstobj->face[fcount]->vertno[fvcnt]=vindx; X if(srcobj->face[fcount]->map>(-1)) { X tvindx=srcobj->face[fcount]->tvertno[fvcnt]; X dstobj->face[fcount]->vertno[fvcnt]=tvindx; X } X } X if(fvcnt > dstobj->size.nofverts) { X dstobj->size.nofverts = fvcnt + 1; X } X dstobj->face[fcount]->vertc=srcobj->face[fcount]->vertc; X dstobj->face[fcount]->mtl=srcobj->face[fcount]->mtl; X dstobj->face[fcount]->map=srcobj->face[fcount]->map; X dstobj->face[fcount]->group=srcobj->face[fcount]->group; X } X X if(verbflg > 9) { X fprintf(stderr,"%d patches\n",srcobj->size.noptchs); X } X /* copy bicubic patches */ X for(bicuct=0;bicuctsize.noptchs;bicuct++) { X for(row=0;row<4;row++) { X for(col=0;col<4;col++) { X dstobj->bicub[bicuct]->vertno[row][col] = X srcobj->bicub[bicuct]->vertno[row][col]; X dstobj->bicub[bicuct]->tvertno[row][col] = X srcobj->bicub[bicuct]->tvertno[row][col]; X } X } X dstobj->bicub[bicuct]->type=srcobj->bicub[bicuct]->type; X dstobj->bicub[bicuct]->v_res=srcobj->bicub[bicuct]->v_res; X dstobj->bicub[bicuct]->u_res=srcobj->bicub[bicuct]->u_res; X dstobj->bicub[bicuct]->mtl=srcobj->bicub[bicuct]->mtl; X dstobj->bicub[bicuct]->map=srcobj->bicub[bicuct]->map; X dstobj->bicub[bicuct]->smooth=srcobj->bicub[bicuct]->smooth; X dstobj->bicub[bicuct]->group=srcobj->bicub[bicuct]->group; X } X X dstobj->size.noverts=vcount; X dstobj->size.notverts=tvcount; X dstobj->size.nosgrps=srcobj->size.nosgrps; X dstobj->size.nofaces=fcount; X dstobj->size.nopoints=pcount; X dstobj->size.nolines=lcount; X dstobj->size.noptchs=bicuct; X } X X/* if flag is set, copy meta elements */ Xif(elemflg=='m') { X if(verbflg > 9) { X fprintf(stderr,"copy_obj: %d circles ", X srcobj->size.nocircs); X } X /* copy circles */ X for(circnt=0;circntsize.nocircs;circnt++) { X dstobj->circl[circnt]->vertno=srcobj->circl[circnt]->vertno; X dstobj->circl[circnt]->rad=srcobj->circl[circnt]->rad; X dstobj->circl[circnt]->res=srcobj->circl[circnt]->res; X dstobj->circl[circnt]->group=srcobj->circl[circnt]->group; X } X if(verbflg > 9) { X fprintf(stderr,"%d spheres ",srcobj->size.nosphrs); X } X /* copy spheres */ X for(sphcnt=0;sphcntsize.nosphrs;sphcnt++) { X dstobj->spher[sphcnt]->vertno=srcobj->spher[sphcnt]->vertno; X dstobj->spher[sphcnt]->rad=srcobj->spher[sphcnt]->rad; X dstobj->spher[sphcnt]->res=srcobj->spher[sphcnt]->res; X dstobj->spher[sphcnt]->mtl=srcobj->spher[sphcnt]->mtl; X dstobj->spher[sphcnt]->map=srcobj->spher[sphcnt]->map; X dstobj->spher[sphcnt]->smooth=srcobj->spher[sphcnt]->smooth; X dstobj->spher[sphcnt]->group=srcobj->spher[sphcnt]->group; X } X X dstobj->size.nocircs=circnt; X dstobj->size.nosphrs=sphcnt; X } Xdstobj->size.nomtls=mtlindx; Xdstobj->size.nomaps=mapindx; Xdstobj->size.nolibs=libindx; Xdstobj->size.nocalls=calindx; Xdstobj->size.nogroups=gindx; X X/* free memory allocated in this function */ Xfree(CPalloc); XCPalloc = NULL; X Xif(verbflg > 1) { X fprintf(stderr,"copy_obj: done\n"); X } X Xreturn(dstobj); X} !EOR! echo extracting src/obj_lib/rd_poly.c echo mkdir ./src mkdir ./src echo mkdir ./src/obj_lib mkdir ./src/obj_lib sed 's/^X//' > src/obj_lib/rd_poly.c << '!EOR!' X/* file: rd_poly.c X X description: Reads an ASCII geometrical object description of the type X used in Andrew Humes database of regular polyhedra. X See poly(5). X X author: Stewart Dickson X*/ X X#include X#include X X#define NUMBER 0 X#define NAME 1 X#define SYMBOL 2 X#define DUAL 3 X#define VERTICES 4 X#define SVERTICES 5 X#define NET 6 X#define SFACES 7 X#define HINGES 8 X#define SOLID 9 X#define DIHEDRAL 10 X#define END_OF_FILE 11 X#define NO_LABELS 12 X Xchar header[NO_LABELS][80] = { X "number", "name", "symbol", "dual", "vertices", "svertices", "net", X "sfaces", "hinges", "solid", "dihedral", "EOF" X }; X Xstruct topology *rd_poly(dst_obj, src_file) Xstruct topology *dst_obj; XFILE *src_file; X{ Xextern int verbflg; Xstruct sizes *alloc = NULL, *null_parms(); Xstruct topology *alloc_hdr(), *alloc_verts(), *alloc_faces(), *alloc_edges(); Xstruct topology *realc_obj(); Xint lchar, lcount, lindx, nolines; Xint add_group(), grp_index, net_group, solid_group; Xint tot_verts, net_verts, net_faces, solid_faces; Xint vindx, eindx, findx, fvindx, ofindx, noverts, nofverts, noedges; Xfloat vert_x, vert_y, vert_z, dihedral; Xchar key_word[128], line[128], new_string[128]; X Xif(verbflg > 0) { X fprintf(stderr,"entering rd_poly\n"); X } X X/* allocate local object parameter struct - set to all zeroes */ Xalloc = null_parms(alloc); Xalloc->nomtls = 1; Xalloc->nomaps = 1; Xalloc->nogroups = 3; X Xofindx = 0; Xlcount = 1; Xwhile(fscanf(src_file,":%s",key_word) != EOF) { X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X switch(parse(key_word)) { X case NUMBER: { /* plug into object name */ X fscanf(src_file,"%[^\n]",line); X sprintf(new_string,"Hume's number: %s, ",line); X if(strlen(alloc->objname) + strlen(new_string) < 128) { X strcat(alloc->objname,new_string); X } X if(verbflg > 0) { X fprintf(stderr, X "rd_poly: line %d, NUMBER '%s'\n",lcount,line); X } X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X break; X } X case NAME: { /* plug into object name */ X fscanf(src_file,"%[^\n]",line); X sprintf(new_string,"Polyhedron name: %s, ",line); X if(strlen(alloc->objname) + strlen(new_string) < 128) { X strcat(alloc->objname,new_string); X } X if(verbflg > 0) { X fprintf(stderr, X "rd_poly: line %d, NAME '%s'\n",lcount,line); X } X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X break; X } X case SYMBOL: { /* plug into object name */ X fscanf(src_file,"%[^\n]",line); X sprintf(new_string,"Symbol: %s, ",line); X if(strlen(alloc->objname) + strlen(new_string) < 128) { X strcat(alloc->objname,new_string); X } X if(verbflg > 0) { X fprintf(stderr, X "rd_poly: line %d, SYMBOL '%s'\n",lcount,line); X } X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X break; X } X case DUAL: { /* plug into object name */ X fscanf(src_file,"%[^\n]",line); X sprintf(new_string,"Dual: %s, ",line); X if(strlen(alloc->objname) + strlen(new_string) < 128) { X strcat(alloc->objname,new_string); X } X if(verbflg > 0) { X fprintf(stderr, X "rd_poly: line %d, DUAL '%s'\n",lcount, line); X } X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X break; X } X case VERTICES: { X /* first line following header is number of vertices */ X fscanf(src_file,"%d", &tot_verts); X /* there is an optional number of vertices X depicting the planar net */ X if((lchar = fgetc(src_file)) == ' ') { X fscanf(src_file,"%d", &net_verts); X } X else { /* newline */ X net_verts = 0; X ungetc(lchar,src_file); X } X if(tot_verts < 5) { /* bad # vertices */ X fprintf(stderr, X "rd_poly: line %d: bad number of vertices: %d\n", X lcount, tot_verts); X exit(-1); X } X if(verbflg > 1) { X fprintf(stderr, X "rd_poly: line %d, reading %d vertices\n", X lcount, tot_verts); X } X alloc->noverts = tot_verts + 1; X alloc->nogverts = alloc->noverts; X if(dst_obj == NULL) { /* We're going to allocate as we go */ X dst_obj = alloc_hdr(alloc); X } X else if(dst_obj->vertex == NULL) { /* allocate vertices */ X dst_obj = alloc_verts(dst_obj,alloc); X } X else { /* we already have an object and vertices, reallocate */ X dst_obj = realc_obj(dst_obj,alloc); X } X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X /* read vertices */ X for(vindx = 1; vindx < alloc->noverts; vindx++) { X if(verbflg > 1) { X fprintf(stderr, X "rd_poly: line %d, reading vertex %d\n", X lcount, vindx); X } X if(vindx <= net_verts) { X grp_index = add_group(dst_obj,"net"); X } X else { X grp_index = add_group(dst_obj,"solid"); X } X fscanf(src_file,"%f",&vert_x); X /* if next char is '[', expect expression form of vertex X coordinate */ X if((lchar = fgetc(src_file)) == '[') { X /* skip this for now */ X while((lchar = fgetc(src_file)) != ']'); X } X else if(lchar != ' ') { X ungetc(lchar,src_file); X } X /* assign value to vertex coordinate */ X dst_obj->vertex[vindx]->x = vert_x; X /* read next coordinate */ X fscanf(src_file,"%f",&vert_y); X /* if next char is '[', expect expression form of vertex X coordinate */ X if((lchar = fgetc(src_file)) == '[') { X /* skip this for now */ X while((lchar = fgetc(src_file)) != ']'); X } X else if(lchar != ' ') { X ungetc(lchar,src_file); X } X /* assign value to vertex coordinate */ X dst_obj->vertex[vindx]->y = vert_y; X /* read next coordinate */ X fscanf(src_file,"%f",&vert_z); X /* if next char is '[', expect expression form of vertex X coordinate */ X if((lchar = fgetc(src_file)) == '[') { X /* skip this for now */ X while((lchar = fgetc(src_file)) != ']'); X } X else if(lchar != ' ') { X ungetc(lchar,src_file); X } X /* assign value to vertex coordinate */ X dst_obj->vertex[vindx]->z = vert_z; X /* set material */ X dst_obj->vertex[vindx]->mtl = 0; X dst_obj->vertex[vindx]->group = grp_index; X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X } X /* set vertex population of object */ X dst_obj->size.noverts = alloc->noverts; X break; X } X case SVERTICES: { /* ??? */ X /* don't know what this is - throw away */ X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X /* read up to next newline */ X while((lchar = fgetc(src_file)) != '\n'); X ungetc(lchar,src_file); X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X break; X } X case NET: { /* planar net - stereographic projection */ X /* first line is number of faces and max. vertices in a face */ X if(fscanf(src_file,"%d ",&net_faces) < 1) { /* missing # faces */ X fprintf(stderr, "rd_poly: line %d: missing number of faces\n", X lcount); X exit(-1); X } X if(fscanf(src_file,"%d",&nofverts) < 1) { X /* missing # vertices/face */ X fprintf(stderr, X "rd_poly: line %d: missing number of vertices per face\n", X lcount); X exit(-1); X } X if(alloc->nofaces == 0) { /* no faces have been read */ X alloc->nofaces = net_faces; X alloc->nofverts = nofverts; X if(dst_obj == NULL) { /* We're going to allocate as we go */ X dst_obj = alloc_hdr(alloc); X } X if(dst_obj->face == NULL) { /* allocate faces */ X dst_obj = alloc_faces(dst_obj,alloc); X } X } X else { /* some faces have been read, reallocate */ X alloc->nofaces = alloc->nofaces + net_faces; X if(alloc->nofverts < nofverts) { X alloc->nofverts = nofverts; X } X dst_obj = realc_obj(dst_obj,alloc); X } X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X /* add an object element group 'net' */ X grp_index = add_group(dst_obj,"net"); X net_group = grp_index; X /* remaining lines consist of vertex count and vertex indices */ X for(findx = 0; findx < net_faces; findx++) { X if(verbflg > 1) { X fprintf(stderr, X "rd_poly: line %d, reading net face %d, abs. face %d\n", X lcount, findx, ofindx); X } X /* first field is number of vertices */ X if(fscanf(src_file,"%d",&noverts) < 1) { /* missing # verts */ X fprintf(stderr, X "rd_poly: line %d: polygon %d, missing # of verts\n", X lcount, findx); X exit(-1); X } X dst_obj->face[ofindx]->vertc = noverts; X dst_obj->face[ofindx]->mtl = 0; X dst_obj->face[ofindx]->map = -1; X dst_obj->face[ofindx]->mapflg = 0; X dst_obj->face[ofindx]->group = grp_index; X dst_obj->face[ofindx]->bevel = 0; X dst_obj->face[ofindx]->smooth = -1; X for(fvindx = 0; fvindx < noverts; fvindx++) { X /* remaining fields are vertex indices */ X if(fscanf(src_file, " %d", &vindx) < 1) { X fprintf(stderr, X "rd_poly: line %d: polygon %d, missing vertex %d\n", X lcount, ofindx, fvindx); X exit(-1); X } X dst_obj->face[ofindx]->vertno[fvindx] = vindx + 1; X } X ofindx++; X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X } X dst_obj->size.nofaces = alloc->nofaces; X dst_obj->size.nofverts = alloc->nofverts; X break; X } X case SFACES: { X /* know what this is, but don't know what to do with it - X throw away */ X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X /* read up to next newline */ X while((lchar = fgetc(src_file)) != '\n'); X ungetc(lchar,src_file); X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X break; X } X case HINGES: { X /* first line is number of edges */ X if(fscanf(src_file,"%d",&noedges) < 1) { /* missing # edges */ X fprintf(stderr, "rd_poly: line %d: missing number of edges\n", X lcount); X exit(-1); X } X alloc->noedges = noedges; X X if(dst_obj == NULL) { /* We're going to allocate as we go */ X dst_obj = alloc_hdr(alloc); X } X else if(dst_obj->edge == NULL) { /* allocate edges */ X dst_obj = alloc_edges(dst_obj,alloc); X } X else { /* reallocate */ X dst_obj = realc_obj(dst_obj,alloc); X } X X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X X /* remaining lines consist of face-edge pairs */ X for(eindx = 0; eindx < noedges; eindx++) { X if(verbflg > 1) { X fprintf(stderr,"rd_poly: line %d, reading edge %d\n", X lcount, eindx); X } X /* first field is face 0 */ X if(fscanf(src_file,"%d ",&findx) < 1) { /* missing face # */ X fprintf(stderr, X "rd_poly: line %d: edge %d, missing face #\n", X lcount, eindx); X exit(-1); X } X dst_obj->edge[eindx]->faceno[0] = findx; X X /* second field is side of face 0 */ X if(fscanf(src_file,"%d ",&fvindx) < 1) { X /* missing face side */ X fprintf(stderr, X "rd_poly: line %d: edge %d, missing face side #\n", X lcount, eindx); X exit(-1); X } X X /* assign vertices to edge from face vertex list */ X vindx = dst_obj->face[findx]->vertno[fvindx]; X dst_obj->edge[eindx]->vertno[0] = vindx; X vindx = dst_obj->face[findx]->vertno[fvindx + 1]; X dst_obj->edge[eindx]->vertno[1] = vindx; X X /* third field is face 1 */ X if(fscanf(src_file,"%d ",&findx) < 1) { /* missing face # */ X fprintf(stderr, X "rd_poly: line %d: edge %d, missing face #\n", X lcount, eindx); X exit(-1); X } X dst_obj->edge[eindx]->faceno[1] = findx; X X /* fourth field is side of face 1 */ X if(fscanf(src_file,"%d ",&fvindx) < 1) { /* missing face side */ X fprintf(stderr, X "rd_poly: line %d: edge %d, missing face side #\n", X lcount, eindx); X exit(-1); X } X X /* verify vertices from face vertex list with edge */ X vindx = dst_obj->face[findx]->vertno[fvindx]; X if(dst_obj->edge[eindx]->vertno[1] != vindx) { X /* flag inconsistencies */ X fprintf(stderr, X "rd_poly: WARNING: edge %d vertex mismatch\n",eindx); X fprintf(stderr, X "\tedge vertex %d, face vertex %d\n", X dst_obj->edge[eindx]->vertno[1], vindx); X } X vindx = dst_obj->face[findx]->vertno[fvindx + 1]; X if(dst_obj->edge[eindx]->vertno[0] != vindx) { X /* flag inconsistencies */ X fprintf(stderr, X "rd_poly: WARNING: edge %d vertex mismatch\n",eindx); X fprintf(stderr, X "\tedge vertex %d, face vertex %d\n", X dst_obj->edge[eindx]->vertno[0], vindx); X } X X /* fifth field is angle */ X fscanf(src_file,"%f",&dihedral); X /* if next char is '[', expect expression form of vertex X coordinate */ X if((lchar = fgetc(src_file)) == '[') { X /* skip this for now */ X while((lchar = fgetc(src_file)) != ']'); X } X else if(lchar != ' ') { X ungetc(lchar,src_file); X } X /* assign angle to object */ X dst_obj->edge[eindx]->theta = dihedral; X X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X } X dst_obj->size.noedges = alloc->noedges; X break; X } X case SOLID: { /* polyhedron */ X /* first line is number of faces and max. vertices in a face */ X if(fscanf(src_file,"%d ",&solid_faces) < 1) { /* missing # faces */ X fprintf(stderr, "rd_poly: line %d: missing number of faces\n", X lcount); X exit(-1); X } X if(fscanf(src_file,"%d",&nofverts) < 1) { X /* missing # vertices/face */ X fprintf(stderr, X "rd_poly: line %d: missing number of vertices per face\n", X lcount); X exit(-1); X } X if(alloc->nofaces == 0) { /* no faces have been read */ X alloc->nofaces = solid_faces; X alloc->nofverts = nofverts; X if(dst_obj == NULL) { /* We're going to allocate as we go */ X dst_obj = alloc_hdr(alloc); X } X if(dst_obj->face == NULL) { /* allocate faces */ X dst_obj = alloc_faces(dst_obj,alloc); X } X } X else { /* faces have been read - reallocate */ X alloc->nofaces = alloc->nofaces + solid_faces; X if(alloc->nofverts < nofverts) { X alloc->nofverts = nofverts; X } X dst_obj = realc_obj(dst_obj,alloc); X } X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X /* add an object element group 'net' */ X grp_index = add_group(dst_obj,"solid"); X solid_group = grp_index; X /* remaining lines consist of vertex count and vertex indices */ X for(findx = 0; findx < solid_faces; findx++) { X if(verbflg > 1) { X fprintf(stderr, X "rd_poly: line %d, reading solid face %d abs. face %d\n", X lcount, findx, ofindx); X } X /* first field is number of vertices */ X if(fscanf(src_file,"%d",&noverts) < 1) { /* missing # verts */ X fprintf(stderr, X "rd_poly: line %d: polygon %d, missing # of verts\n", X lcount, findx); X exit(-1); X } X dst_obj->face[ofindx]->vertc = noverts; X dst_obj->face[ofindx]->mtl = 0; X dst_obj->face[ofindx]->map = -1; X dst_obj->face[ofindx]->mapflg = 0; X dst_obj->face[ofindx]->group = grp_index; X dst_obj->face[ofindx]->bevel = 0; X dst_obj->face[ofindx]->smooth = -1; X for(fvindx = 0; fvindx < noverts; fvindx++) { X /* remaining fields are vertex indices */ X if(fscanf(src_file, " %d", &vindx) < 1) { X fprintf(stderr, X "rd_poly: line %d: polygon %d, missing vertex %d\n", X lcount, ofindx, fvindx); X exit(-1); X } X dst_obj->face[ofindx]->vertno[fvindx] = vindx + 1; X } X ofindx++; X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X } X dst_obj->size.nofaces = alloc->nofaces; X dst_obj->size.nofverts = alloc->nofverts; X break; X } X case DIHEDRAL: { X /* know what this is, but don't know what to do with it - X throw away */ X /* first line contains number of distinct dihedrals */ X fscanf(src_file,"%[^\n]",line); X lcount++; X if((nolines = atoi(line)) < 0) { /* bad # dihedrals */ X fprintf(stderr, X "rd_poly: line %d, bad number of dihedral angles '%s'\n", X lcount, line); X exit(-1); X } X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X /* remaining lines contain dihedral angles */ X for(lindx = 0; lindx < nolines; lindx++) { X /* read lines */ X fscanf(src_file,"%[^\n]",line); X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X } X break; X } X case END_OF_FILE: { X /* read newline(s) */ X while((lchar = fgetc(src_file)) == '\n') lcount++; X ungetc(lchar,src_file); X break; X } X X } X } X X/* free memory allocated in this module */ Xfree(alloc); X Xif(verbflg > 0) { X fprintf(stderr,"rd_poly: done\n"); X } X Xreturn(dst_obj); X X} X X X X X/* function: parse X X description: Returns the index to a #define'd label matching the input X string. X X author: Stewart Dickson X*/ X Xint parse(string) Xchar *string; X{ Xextern int verbflg; Xint index; X Xfor(index = 0; index < NO_LABELS; index++) { X if(!strncmp(string,header[index],3)) { X break; X } X } X Xif(verbflg > 1) { X fprintf(stderr,"parse: reading '%s'\n",header[index]); X } X X/* re-set string to a NULL */ Xstrcat(string,"\0"); X Xreturn(index); X} !EOR! echo extracting src/obj_lib/wt_obj.c echo mkdir ./src mkdir ./src echo mkdir ./src/obj_lib mkdir ./src/obj_lib sed 's/^X//' > src/obj_lib/wt_obj.c << '!EOR!' X/* X Xfunction: wt_obj() X Xdescription: writes a Wavefront ".obj" ASCII object description file from X a data structure in core. X Has been modified to include graphical 'meta-elements' circle, X sphere and user-defined object meta-elements. X Xinputs: outfildes -- file descriptor of file opened for writing. X wtobj -- pointer to structure containing object description. X Xreturns: none X Xauthor: Stewart Dickson X*/ X X#include X#include X#include X X X Xvoid wt_obj(outfildes,wtobj) XFILE *outfildes; Xstruct topology *wtobj; X{ Xextern int verbflg; X Xchar date[30]; Xint lcount=0; Xshort lvcnt=0; Xint fcount=0; Xshort fvcnt=0; Xint vcount=1,tvcount=1,pcount=0; Xshort pvcnt=0; Xint circnt=0,sphcnt=0,bicuct=0; Xshort libcnt,calcnt; Xint row,col,u_res = 4,v_res = 4; Xshort grpindx=0,bindx=0,sindx=(-1),mtlindx=(-1),mapindx=(-1); Xlong secs,time(); X Xif(outfildes==NULL) { X fprintf(stderr,"wt_obj: ERROR - NULL file pointer received\n"); X exit(); X } X Xif(wtobj==NULL) { X fprintf(stderr,"wt_obj: ERROR - NULL object pointer received\n"); X exit(); X } X Xfprintf(stderr,"wt_obj: writing object '%s'\n",wtobj->size.objname); X Xif(verbflg>1) { X fprintf(stderr,"wt_obj: writing identification message\n"); X } X X/* output object identification message */ X Xsecs=time((long *)0); Xstrcpy(date,asctime(localtime(&secs))); X Xfprintf(outfildes, X "\# %s %s\n",wtobj->size.objname,date); Xfprintf(outfildes, X "\# This is a Stewart Dickson object description file\n"); Xfprintf(outfildes, X "\# made from a Stewart Dickson object-generating program.\n"); Xfprintf(outfildes, X "\# It may contain 'meta-elements' which must be expanded\n"); Xfprintf(outfildes, X "\# to be compatible with Wavefront Technologies software.\n\#\n\#\n"); X X/* output "mtllib/maplib" directives */ X Xif(verbflg>1) { X fprintf(stderr,"wt_obj: writing %d 'mtllib/maplib' directives\n", X wtobj->size.nolibs); X } X Xfor(libcnt=0;libcntsize.nolibs;libcnt++) { X if(verbflg>10) { X fprintf(stderr,"%s\n",wtobj->lib[libcnt]->libnam); X } X X fprintf(outfildes,"%s\n",wtobj->lib[libcnt]->libnam); X } X X/* output "call" directives */ X Xif(verbflg>1) { X fprintf(stderr,"wt_obj: writing %d 'call' directives\n", X wtobj->size.nocalls); X } X Xfor(calcnt=0;calcntsize.nocalls;calcnt++) { X if(verbflg>10) { X fprintf(stderr,"%s\n",wtobj->call[calcnt]->filnam); X } X X fprintf(outfildes,"%s\n\n",wtobj->call[calcnt]->filnam); X } X X/* output vertices */ X Xif(verbflg>1) { X fprintf(stderr,"wt_obj: writing %d vertices\n",wtobj->size.noverts - 1); X } X Xfprintf(outfildes,"\n! vertices %d\n",wtobj->size.noverts); Xfor(vcount=1;vcountsize.noverts;vcount++) { X if(verbflg>10) { X fprintf(stderr,"wt_obj: vertex mtl = %d, current mtl = %d\n", X wtobj->vertex[vcount]->mtl,mtlindx); X fprintf(stderr,"v %3.6f %3.6f %3.6f # vertex %d\n", X wtobj->vertex[vcount]->x, X wtobj->vertex[vcount]->y, X wtobj->vertex[vcount]->z,vcount); X } X /* see if vertex material is current material */ X if(wtobj->vertex[vcount]->mtl!=mtlindx) { X /* if not, change current mtl and ouput new "usemtl" */ X mtlindx=wtobj->vertex[vcount]->mtl; X if(!strcmp(wtobj->mtl[mtlindx]->mtlnam,"# no materials used")) { X if(verbflg>10) { X fprintf(stderr,"%s\n",wtobj->mtl[mtlindx]->mtlnam); X } X fprintf(outfildes,"%s\n",wtobj->mtl[mtlindx]->mtlnam); X } X else { X if(verbflg>10) { X fprintf(stderr,"usemtl %s\n",wtobj->mtl[mtlindx]->mtlnam); X } X fprintf(outfildes,"usemtl %s\n",wtobj->mtl[mtlindx]->mtlnam); X } X } X fprintf(outfildes,"v %3.6f %3.6f %3.6f\n", X wtobj->vertex[vcount]->x, X wtobj->vertex[vcount]->y, X wtobj->vertex[vcount]->z); X } Xfprintf(outfildes,"\n\# %d vertices\n\n",wtobj->size.noverts - 1); X X/* output texture vertices */ X Xif(verbflg>1) { X fprintf(stderr,"wt_obj: writing %d texture vertices\n", X wtobj->size.notverts - 1); X } X Xfprintf(outfildes,"\n! tverts %d\n",wtobj->size.notverts); Xfor(tvcount=1;tvcountsize.notverts;tvcount++) { X fprintf(outfildes,"vt %3.6f %3.6f %3.6f\n", X wtobj->texver[tvcount]->u, X wtobj->texver[tvcount]->v, X wtobj->texver[tvcount]->w); X } Xfprintf(outfildes,"\n\# %d texture vertices\n\n",wtobj->size.notverts - 1); X X X X/* output lines */ X Xif(verbflg>1) { X fprintf(stderr,"wt_obj: writing %d lines\n",wtobj->size.nolines); X } X Xfprintf(outfildes,"\n! lverts %d\n",wtobj->size.nolverts); Xfprintf(outfildes,"\n! lines %d\n",wtobj->size.nolines); Xfor(lcount=0;lcountsize.nolines;lcount++) { X /* don't output a line with less than two vertices */ X if(wtobj->line[lcount]->vertc>1) { X /* see if line group is current group */ X if(wtobj->line[lcount]->group!=grpindx) { X /* if not, change current group and ouput new group */ X grpindx=wtobj->line[lcount]->group; X if(verbflg>9) { X fprintf(stderr, "g %s\n",wtobj->group[grpindx]->grpnam); X } X fprintf(outfildes, "g %s\n",wtobj->group[grpindx]->grpnam); X } X /* see if line material is current material */ X if(wtobj->line[lcount]->mtl!=mtlindx) { X /* if not, change current mtl and ouput new "usemtl" */ X mtlindx=wtobj->line[lcount]->mtl; X if(!strcmp(wtobj->mtl[mtlindx]->mtlnam,"# no materials used")) { X if(verbflg>9) { X fprintf(stderr, "%s\n",wtobj->mtl[mtlindx]->mtlnam); X } X fprintf(outfildes,"%s\n",wtobj->mtl[mtlindx]->mtlnam); X } X else { X if(verbflg>9) { X fprintf(stderr, X "usemtl %s\n",wtobj->mtl[mtlindx]->mtlnam); X } X fprintf(outfildes,"usemtl %s\n",wtobj->mtl[mtlindx]->mtlnam); X } X } X fprintf(outfildes,"l"); X for(lvcnt=0;lvcntline[lcount]->vertc;lvcnt++) { X fprintf(outfildes," %d", wtobj->line[lcount]->vertno[lvcnt]); X } X fprintf(outfildes,"\n"); X } X } X X/* output meta-elements of type 'circle' */ X Xif(verbflg>1) { X fprintf(stderr,"wt_obj: writing %d meta-elements of type 'circle'\n", X wtobj->size.nocircs); X } X Xfprintf(outfildes,"\n! circles %d\n",wtobj->size.nocircs); Xfor(circnt=0;circntsize.nocircs;circnt++) { X /* see if circle group is current group */ X if(wtobj->circl[circnt]->group!=grpindx) { X /* if not, change current group and ouput new group */ X grpindx=wtobj->circl[circnt]->group; X if(verbflg>9) { X fprintf(stderr, X "g %s\n",wtobj->group[grpindx]->grpnam); X } X fprintf(outfildes, X "g %s\n",wtobj->group[grpindx]->grpnam); X } X fprintf(outfildes,"*c %d %3.6f %d\n", X wtobj->circl[circnt]->vertno, X wtobj->circl[circnt]->rad, X wtobj->circl[circnt]->res); X } X Xfprintf(outfildes,"\n\# %d circles\n",wtobj->size.nocircs); X X/* output points */ X Xif(verbflg>1) { X fprintf(stderr,"wt_obj: writing %d points\n",wtobj->size.nopoints); X } X Xfprintf(outfildes,"\n! pverts %d\n",wtobj->size.nopverts); Xfprintf(outfildes,"\n! points %d\n",wtobj->size.nopoints); Xfor(pcount=0;pcountsize.nopoints;pcount++) { X /* don't output a point with less than one vertex */ X if(wtobj->point[pcount]->vertc>0) { X /* see if point group is current group */ X if(wtobj->point[pcount]->group!=grpindx) { X /* if not, change current group and ouput new group */ X grpindx=wtobj->point[pcount]->group; X if(verbflg>9) { X fprintf(stderr, "g %s\n",wtobj->group[grpindx]->grpnam); X } X fprintf(outfildes, "g %s\n",wtobj->group[grpindx]->grpnam); X } X if(verbflg>9) { X fprintf(stderr,"point %d: p",pcount); X } X fprintf(outfildes,"p"); X for(pvcnt=0;pvcntpoint[pcount]->vertc;pvcnt++) { X if(verbflg>9) { X fprintf(stderr," %d", X wtobj->point[pcount]->vertno[pvcnt]); X } X fprintf(outfildes," %d", X wtobj->point[pcount]->vertno[pvcnt]); X } X if(verbflg>9) { X fprintf(stderr,"\n"); X } X fprintf(outfildes,"\n"); X } X } X Xfprintf(outfildes,"\n\# %d points\n",wtobj->size.nopoints); X X/* output faces */ X Xif(verbflg>1) { X fprintf(stderr,"wt_obj: writing %d faces\n",wtobj->size.nofaces); X } X Xfprintf(outfildes,"\n! fverts %d\n",wtobj->size.nofverts); Xfprintf(outfildes,"\n! faces %d\n",wtobj->size.nofaces); Xfor(fcount=0;fcountsize.nofaces;fcount++) { X if(verbflg>9) { X fprintf(stderr, X "wt_obj: face %d, %d vertices\n", X fcount,wtobj->face[fcount]->vertc); X } X /* don't output a face with less than three vertices */ X if(wtobj->face[fcount]->vertc>2) { X /* see if face group is current group */ X if(wtobj->face[fcount]->group!=grpindx) { X /* if not, change current group and ouput new group */ X grpindx=wtobj->face[fcount]->group; X if(verbflg>9) { X fprintf(stderr, "g %s\n",wtobj->group[grpindx]->grpnam); X } X fprintf(outfildes, "g %s\n",wtobj->group[grpindx]->grpnam); X } X /* see if face smoothing group is current smoothing group */ X if(wtobj->face[fcount]->smooth!=sindx) { X /* if not, change current smoothing group */ X sindx=wtobj->face[fcount]->smooth; X /* and output smoothing directive */ X if(sindx<=(-1)) { X if(verbflg>9) { X fprintf(stderr,"s off\n"); X } X fprintf(outfildes,"s off\n"); X } X else { X if(verbflg>9) { X fprintf(stderr,"s %d\n", X wtobj->face[fcount]->smooth); X } X fprintf(outfildes,"s %d\n", X wtobj->face[fcount]->smooth); X } X } X /* see if face bevel interp state is same as current state */