#include #include #include #include "gut.h" /* #include "io.h" */ #define MAX_SOLIDS 128 #define LINSIZ 64 void GenColor(int numids, GutSolidType sol[]) { int numcol, colgap; int i, j, k; numcol = ceil (pow((double)(numids+1), 1.0/3.0) ); colgap = floor( (double)200/(numcol-1) ) ; printf("%d Ids, %d col/channel, %d col gap\n", numids, numcol, colgap); for(i=0; ibptr; pptr--) { *pptr = pptr[-1]; } *pptr = ptmp; /* for(i=RealSolIdx+1; i<=CurSolIdx; i++) */ while(++RealSolIdx <= CurSolIdx) solid[RealSolIdx].polys.I++; } int MkNormalsI(GutPolyTypeI *poly, GutVec3 *verts) { GutReal d1[3], d2[3]; GutReal length; d1[0] = verts[poly->vid[1]][0] - verts[poly->vid[0]][0]; d1[1] = verts[poly->vid[1]][1] - verts[poly->vid[0]][1]; d1[2] = verts[poly->vid[1]][2] - verts[poly->vid[0]][2]; d2[0] = verts[poly->vid[2]][0] - verts[poly->vid[1]][0]; d2[1] = verts[poly->vid[2]][1] - verts[poly->vid[1]][1]; d2[2] = verts[poly->vid[2]][2] - verts[poly->vid[1]][2]; poly->n[0] = d1[1]*d2[2] - d1[2]*d2[1]; poly->n[1] = d1[2]*d2[0] - d1[0]*d2[2]; poly->n[2] = d1[0]*d2[1] - d1[1]*d2[0]; length = poly->n[0]*poly->n[0] + poly->n[1]*poly->n[1] + poly->n[2]*poly->n[2]; length = sqrt((double)length); if(length != 0.0) length = 1.0/length; else return 0; poly->n[0]*= length; poly->n[1]*= length; poly->n[2]*= length; return 1; } int ReadOffTri(FILE *ifp, GutPolyTypeI *polys, GutVec3 *verts) { int i, *p; fscanf(ifp, "%d", &polys->numpts); #ifdef FAST_TRIANGLES_ONLY_MK if(polys->numpts != 3) { printf("Input has non-triangles. Re-compile with -UFAST_TRIANGLES_ONLY_MK\n"); exit(0); } #endif if(polys->numpts > GUT_MAX_PVERTS) { printf("Sanity Check: Wrong polysize -- %d\n", polys->numpts); for(i=GUT_MAX_PVERTS; inumpts; i++) fscanf(ifp, "%*d"); polys->numpts = GUT_MAX_PVERTS; } p = (int *) polys->vid; if(polys->numpts) fscanf(ifp, "%d", p); for(i=1; inumpts; i++) { fscanf(ifp, "%d", p+i); addEdge(p[i-1], p[i], polys); } addEdge(p[polys->numpts-1], p[0], polys); return MkNormalsI(polys, verts); } int ReadOffTris(FILE *ifp, GutModelType *model) { int nv, np, i; char line[LINSIZ]; /* char format[LINSIZ]; */ GutReal *v; /* int *p; */ int CurSolIdx; static int maxsolids = 0; GutPolyTypeI *polys; int ret, badpolys; model->nsolids = 0; model->npolys = 0; model->nverts = 0; Getline(ifp, line, LINSIZ); if(line[0] == 'O') /* We will assume it is OFF */ sscanf(line, "%*s%d%d%d", &nv, &np, &i); else { printf("Magic: Is this an OFF file?\n"); fclose(ifp); return 0; } printf("%d Vertices, %d polygons\n", nv, np); model->npolys = np; model->nverts = nv; model->verts = (GutVec3 *) malloc(nv * sizeof(GutVec3)); if(model->verts == NULL) { perror("ReadOffTris"); return 0; } polys = (GutPolyTypeI *) malloc(np * GUT_MAX_PVERTS*sizeof(GutPolyTypeI)); if(polys == NULL) { perror("ReadOffTris"); return 0; } if(model->verts == NULL || polys == NULL) { perror("ReadOffTris"); return 0; } v = model->verts[0]; while(nv--) { /* Getline(ifp, line, LINSIZ); We will live with it */ SkipEmpty(ifp, line, LINSIZ); fscanf(ifp, REAL3, v, v+1, v+2); /* printf("V is %f %f %f\n", v[0], v[1], v[3]); */ GutUpdateBox((GutVec3 *) (v), 1); v += 3; } printf("Vertices read. Reading Polygons now\n"); if(gutFormat.Colors) { model->solids = (GutSolidType *) malloc(MAX_SOLIDS*sizeof(GutSolidType)); if(model->solids == NULL) { perror("ReadOffTris"); return 0; } model->solids[0].npolys = 0; } else { model->solids = (GutSolidType *) malloc(sizeof(GutSolidType)); if(model->solids == NULL) { perror("ReadOffTris"); return 0; } model->nsolids = 1; model->solids[0].npolys = np; } model->solids[0].polys.I = polys; model->polys = polys; CurSolIdx = 0; badpolys = 0; while(np--) { /* Getline(ifp, line, LINSIZ); We will live with kludge for now. */ /* sscanf(line, "%d", &polys->numpts); */ SkipEmpty(ifp, line, LINSIZ); ret = ReadOffTri(ifp, polys, model->verts); if(gutFormat.Colors == 1) { fscanf(ifp, "%d", &polys->sol_id); if(polys->sol_id == CurSolIdx) /* Just add at the end */ model->solids[CurSolIdx].npolys++; else if(polys->sol_id < CurSolIdx) /* Insert */ { model->solids[CurSolIdx].npolys++; /* Insert assumes this (why?) */ InsertPoly(model->solids, polys->sol_id, CurSolIdx); } else /* New Solid */ { while(++CurSolIdx < polys->sol_id) { model->solids[CurSolIdx].polys.I = polys; model->solids[CurSolIdx].npolys = 0; } model->solids[CurSolIdx].npolys = 1; model->solids[CurSolIdx].polys.I = polys; } if(maxsolids < polys->sol_id) maxsolids = polys->sol_id; if(maxsolids >= MAX_SOLIDS) { printf("Need more solid space (%d)..\n", maxsolids); return 0; } } if(ret) polys++; else badpolys++; } if(gutFormat.Colors) { GenColor(++maxsolids, model->solids); model->nsolids = CurSolIdx+1; } printf("%d Bad polygons\n", badpolys); model->solids[0].npolys -= badpolys; model->npolys -= badpolys; printf("Read %d Solids\n", model->nsolids); printf("Read %d Polys\n", model->solids[0].npolys); fclose(ifp); return model->npolys; }