Back to index

radiance  4R0+20100331
writemesh.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char RCSid[] = "$Id: writemesh.c,v 2.6 2004/04/29 14:36:49 greg Exp $";
00003 #endif
00004 /*
00005  *  Routines for writing compiled mesh to a file stream
00006  */
00007 
00008 #include  "standard.h"
00009 #include  "octree.h"
00010 #include  "object.h"
00011 #include  "mesh.h"
00012 
00013 #ifdef putc_unlocked        /* avoid horrendous overhead of flockfile */
00014 #define putc    putc_unlocked
00015 #endif
00016 
00017 static void putfullnode(OCTREE fn, FILE *fp);
00018 static void puttree(OCTREE ot, FILE *fp);
00019 static void putpatch(MESHPATCH *pp, FILE *fp);
00020 
00021 
00022 static void
00023 putfullnode(         /* write out a full node */
00024        OCTREE fn,
00025        FILE   *fp
00026 )
00027 {
00028        OBJECT  oset[MAXSET+1];
00029        register int  i;
00030 
00031        objset(oset, fn);
00032        for (i = 0; i <= oset[0]; i++)
00033               putint((long)oset[i], sizeof(OBJECT), fp);
00034 }
00035 
00036 
00037 static void
00038 puttree(                    /* write octree to fp in pre-order form */
00039        register OCTREE      ot,
00040        FILE          *fp
00041 )
00042 {
00043        
00044        if (istree(ot)) {
00045               register int  i;
00046               putc(OT_TREE, fp);          /* indicate tree */
00047               for (i = 0; i < 8; i++)            /* write tree */
00048                      puttree(octkid(ot, i), fp);
00049               return;
00050        }
00051        if (isfull(ot)) {
00052               putc(OT_FULL, fp);          /* indicate fullnode */
00053               putfullnode(ot, fp);        /* write fullnode */
00054               return;
00055        }
00056        putc(OT_EMPTY, fp);                /* indicate empty */
00057 }
00058 
00059 
00060 static void
00061 putpatch(                   /* write out a mesh patch */
00062        register MESHPATCH   *pp,
00063        FILE                 *fp
00064 )
00065 {
00066        int    flags = MT_V;
00067        int    i, j;
00068                                    /* vertex flags */
00069        if (pp->norm != NULL)
00070               flags |= MT_N;
00071        if (pp->uv != NULL)
00072               flags |= MT_UV;
00073        putint((long)flags, 1, fp);
00074                                    /* number of vertices */
00075        putint((long)pp->nverts, 2, fp);
00076                                    /* vertex xyz locations */
00077        for (i = 0; i < pp->nverts; i++)
00078               for (j = 0; j < 3; j++)
00079                      putint((long)pp->xyz[i][j], 4, fp);
00080                                    /* vertex normals */
00081        if (flags & MT_N)
00082               for (i = 0; i < pp->nverts; i++)
00083                      putint((long)pp->norm[i], 4, fp);
00084                                    /* uv coordinates */
00085        if (flags & MT_UV)
00086               for (i = 0; i < pp->nverts; i++)
00087                      for (j = 0; j < 2; j++)
00088                             putint((long)pp->uv[i][j], 4, fp);
00089                                    /* local triangles */
00090        putint((long)pp->ntris, 2, fp);
00091        for (i = 0; i < pp->ntris; i++) {
00092               putint((long)pp->tri[i].v1, 1, fp);
00093               putint((long)pp->tri[i].v2, 1, fp);
00094               putint((long)pp->tri[i].v3, 1, fp);
00095        }
00096                                    /* local triangle material(s) */
00097        if (pp->trimat == NULL) {
00098               putint(1L, 2, fp);
00099               putint((long)pp->solemat, 2, fp);
00100        } else {
00101               putint((long)pp->ntris, 2, fp);
00102               for (i = 0; i < pp->ntris; i++)
00103                      putint((long)pp->trimat[i], 2, fp);
00104        }
00105                                    /* joiner triangles */
00106        putint((long)pp->nj1tris, 2, fp);
00107        for (i = 0; i < pp->nj1tris; i++) {
00108               putint((long)pp->j1tri[i].v1j, 4, fp);
00109               putint((long)pp->j1tri[i].v2, 1, fp);
00110               putint((long)pp->j1tri[i].v3, 1, fp);
00111               putint((long)pp->j1tri[i].mat, 2, fp);
00112        }
00113                                    /* double joiner triangles */
00114        putint((long)pp->nj2tris, 2, fp);
00115        for (i = 0; i < pp->nj2tris; i++) {
00116               putint((long)pp->j2tri[i].v1j, 4, fp);
00117               putint((long)pp->j2tri[i].v2j, 4, fp);
00118               putint((long)pp->j2tri[i].v3, 1, fp);
00119               putint((long)pp->j2tri[i].mat, 2, fp);
00120        }
00121 }
00122 
00123 
00124 void
00125 writemesh(mp, fp)                  /* write mesh structures to fp */
00126 MESH   *mp;
00127 FILE   *fp;
00128 {
00129        char   *err;
00130        char   sbuf[64];
00131        int    i;
00132                                    /* do we have everything? */
00133        if ((mp->ldflags & (IO_SCENE|IO_TREE|IO_BOUNDS)) !=
00134                      (IO_SCENE|IO_TREE|IO_BOUNDS))
00135               error(INTERNAL, "missing data in writemesh");
00136                                    /* validate mesh data */
00137        if ((err = checkmesh(mp)) != NULL)
00138               error(USER, err);
00139                                    /* write format number */
00140        putint((long)(MESHMAGIC+sizeof(OBJECT)), 2, fp);
00141                                    /* write boundaries */
00142        for (i = 0; i < 3; i++) {
00143               sprintf(sbuf, "%.12g", mp->mcube.cuorg[i]);
00144               putstr(sbuf, fp);
00145        }
00146        sprintf(sbuf, "%.12g", mp->mcube.cusize);
00147        putstr(sbuf, fp);
00148        for (i = 0; i < 2; i++) {
00149               putflt(mp->uvlim[0][i], fp);
00150               putflt(mp->uvlim[1][i], fp);
00151        }
00152                                    /* write the octree */
00153        puttree(mp->mcube.cutree, fp);
00154                                    /* write the materials */
00155        writescene(mp->mat0, mp->nmats, fp);
00156                                    /* write the patches */
00157        putint((long)mp->npatches, 4, fp);
00158        for (i = 0; i < mp->npatches; i++)
00159               putpatch(&mp->patch[i], fp);
00160        if (ferror(fp))
00161               error(SYSTEM, "write error in writemesh");
00162 }