00001
00002 #include <setjmp.h>
00003 #include "render.h"
00004
00005 #define UC unsigned short
00006 #define US unsigned long
00007
00008 typedef long ivector2[2];
00009
00016 typedef struct traceNODE {
00017 long n,
00018 mi[3],ma[3];
00019 UC *vxi;
00020 UC *oid;
00021 US *fid;
00022 struct traceNODE *octree[8];
00023 long id; struct traceNODE *last; long level;
00024 } node;
00025
00026 static void WriteVertices(void);
00027 static void WriteEdges(void);
00028 static void WriteFaces(void);
00029 static void createVoxelData(node *n);
00030
00031 static HANDLE fq;
00032 static FILE *fo;
00033 static long newface,newedge,newvert,newglue,minX,minY,minZ,maxX,maxY,maxZ,voxelvid,voxelc,voxeleid,vertbias;
00034 static char str[10];
00035 static long FaceBase,EdgeBase,VertexBase;
00036
00037 static int Nvert=0,Nedge=0,Nface=0,Oid=0;
00038 static ivector *voxelv=NULL;
00039 static ivector2 *voxele=NULL;
00040 static ivector *voxelf=NULL;
00041
00042
00043 static void outsht(short sht){
00044 fputc((char)(sht >> 8),fo);
00045 fputc((char)(sht ),fo);
00046 }
00047
00048 static void outusht(unsigned short sht){
00049 fputc((char)(sht >> 8),fo);
00050 fputc((char)(sht ),fo);
00051 }
00052
00053 static void outlng(long lng){
00054 fputc((char)(lng >> 24),fo);
00055 fputc((char)(lng >> 16),fo);
00056 fputc((char)(lng >> 8),fo);
00057 fputc((char)(lng ),fo);
00058 }
00059
00060 void SaveDivided(long nvoxels, node *np, int o, char *Filename){
00061 long pos1,pos2,pos3,pos4,pose;
00062 long lrulerx=1024, lrulery=1024, lrulerz=1024,
00063 rulerx=1024, rulery=1024, rulerz=1024;
00064 long i,FORMsize;
00065 HCURSOR hSave;
00066 char ruler_name[8]="CMS";
00067 short id;
00068 FORMsize=0; newvert=0; newface=0; newedge=0; newglue=0;
00069 if(nvoxels > 0){
00070 voxelvid=0; voxelc=0; voxeleid=0;
00071 voxelv=(ivector *)malloc(nvoxels*8*sizeof(ivector));
00072 if(voxelv == NULL)return;
00073 voxele=(ivector2 *)malloc(nvoxels*12*sizeof(ivector2));
00074 if(voxele == NULL)return;
00075 createVoxelData(np);
00076 }
00077 if(debug != NULL)fprintf(debug,"Saving [%s], expect %d voxels got %d voxels with %d extra vertices\n",
00078 Filename, nvoxels,voxelc,voxelvid);
00079 if(debug != NULL)fprintf(debug,"got %d voxel edges\n",voxeleid);
00080 Oid=o;
00081 Nvert=Object[o].NoTraceVertices;
00082 Nface=Object[o].NoTraceFaces;
00083 Nedge=Nface*3;
00084 if( (fo=fopen(Filename,"wb")) == NULL){
00085 return;
00086 }
00087 fprintf(fo,"FORM");
00088 pos1=ftell(fo); outlng(FORMsize);
00089 fprintf(fo,"OFXM");
00090 fprintf(fo,"AXIS"); outlng(48L);
00091 outlng(0); outlng(0); outlng(0);
00092 for(i=0;i<9;i++)outlng(0);
00093 fprintf(fo,"OFFS"); outlng(16L);
00094 outlng(3L);
00095 outlng(0);
00096 outlng(0);
00097 outlng(0);
00098 pos2 = -1; if(Nvert > 0){
00099 fprintf(fo,"VERT"); pos2=ftell(fo); outlng(0L);
00100 WriteVertices();
00101 if(newvert == 0){
00102 fseek(fo,pos2-4,0);
00103 }
00104 }
00105 pos3 = -1; if(Nedge > 0 && newvert > 1){
00106 fprintf(fo,"EDGE"); pos3=ftell(fo); outlng(0L); WriteEdges();
00107 }
00108 pos4 = -1; if(Nface > 0 && newvert > 2){
00109 fprintf(fo,"NFCE"); pos4=ftell(fo); outlng(0L); WriteFaces();
00110 if(newface == 0)fseek(fo,pos4-4,0);
00111 }
00112 fprintf(fo,"UNIT"); outlng((long)(7*sizeof(long)+8));
00113 outlng((long)1024);
00114 fwrite(ruler_name,1,8,fo);
00115 outlng(lrulerx); outlng(lrulery); outlng(lrulerz);
00116 outlng(rulerx); outlng(rulery); outlng(rulerz);
00117 fprintf(fo,"GRID"); outlng((long)(2*sizeof(long)));
00118 outlng(4096); outlng(4096);
00119 pose=ftell(fo);
00120
00121 if(pos2 > 0){fseek(fo,pos2,0); outlng(12*newvert); }
00122 if(pos3 > 0){fseek(fo,pos3,0);
00123 outlng(8*newedge);
00124 }
00125 if(pos4 > 0){fseek(fo,pos4,0); outlng(20*newface);}
00126 fseek(fo,pos1,0); outlng(pose-8);
00127 fclose(fo);
00128 if(voxelv != NULL)free(voxelv);
00129 if(voxele != NULL)free(voxele);
00130 if(voxelf != NULL)free(voxelf);
00131 if(debug != NULL)fprintf(debug,"Model with %d verts %d edges %d faces\n",newvert,newedge,newface);
00132 return;
00133 }
00134
00135 static void WriteVertices(void){
00136 long i,j;
00137 long x,y,z;
00138 for(j=0;j<Nvert;j++){
00139 x=Object[Oid].Vtracebase[j].ip[0];
00140 y=Object[Oid].Vtracebase[j].ip[1];
00141 z=Object[Oid].Vtracebase[j].ip[2];
00142 outlng(x); outlng(y); outlng(z);
00143 newvert++;
00144 }
00145 if(voxelvid > 0){
00146 vertbias=newvert;
00147 for(j=0;j<voxelvid;j++){
00148 outlng(voxelv[j][0]); outlng(voxelv[j][1]); outlng(voxelv[j][2]);
00149 newvert++;
00150 }
00151 }
00152 }
00153
00154 static void WriteEdges(){
00155 long i,id1,id2,id3;
00156 char color[3]={255,255,255};
00157 char bSmooth=0;
00158 for(i=0;i<Nface;i++){
00159 id1=Object[Oid].Ftracebase[i].V[0];
00160 id2=Object[Oid].Ftracebase[i].V[1];
00161 id3=Object[Oid].Ftracebase[i].V[2];
00162 outlng(id1); outlng(id2);
00163 newedge++;
00164 outlng(id2); outlng(id3);
00165 newedge++;
00166 outlng(id3); outlng(id1);
00167 newedge++;
00168 }
00169 if(voxeleid > 0){
00170 for(i=0;i<voxeleid;i++){
00171 outlng(voxele[i][0]+vertbias); outlng(voxele[i][1]+vertbias);
00172 newedge++;
00173 }
00174 }
00175
00176 }
00177
00178 static void WriteFaces(void){
00179 long i,id1,id2,id3,vx,vx1;
00180 unsigned char color[3]={255,255,255};
00181 char bSmooth=0;
00182 for(i=0;i<Nface;i++){
00183 id1=Object[Oid].Ftracebase[i].V[0];
00184 id2=Object[Oid].Ftracebase[i].V[1];
00185 id3=Object[Oid].Ftracebase[i].V[2];
00186 vx=Object[Oid].Ftracebase[i].x;
00187 vx1=vx%512;
00188 color[0] = vx1/2;
00189 vx1=vx%64;
00190 color[1] = vx1*4;
00191 vx=vx*8;
00192 color[2] = vx1*32;
00193 outlng(id1);
00194 outlng(id2);
00195 outlng(id3);
00196 fwrite(color,1,3,fo);
00197 fwrite(&bSmooth,1,1,fo);
00198 outsht(-1);
00199 outsht(-1);
00200 newface++;
00201 }
00202 }
00203
00204 static void createVoxelData(node *n){
00205 voxele[voxeleid][0]=voxelvid; voxele[voxeleid][1]=voxelvid+1; voxeleid++;
00206 voxele[voxeleid][0]=voxelvid+1; voxele[voxeleid][1]=voxelvid+2; voxeleid++;
00207 voxele[voxeleid][0]=voxelvid+2; voxele[voxeleid][1]=voxelvid+3; voxeleid++;
00208 voxele[voxeleid][0]=voxelvid+3; voxele[voxeleid][1]=voxelvid; voxeleid++;
00209 voxele[voxeleid][0]=voxelvid+4; voxele[voxeleid][1]=voxelvid+5; voxeleid++;
00210 voxele[voxeleid][0]=voxelvid+5; voxele[voxeleid][1]=voxelvid+6; voxeleid++;
00211 voxele[voxeleid][0]=voxelvid+6; voxele[voxeleid][1]=voxelvid+7; voxeleid++;
00212 voxele[voxeleid][0]=voxelvid+7; voxele[voxeleid][1]=voxelvid+4; voxeleid++;
00213 voxele[voxeleid][0]=voxelvid; voxele[voxeleid][1]=voxelvid+4; voxeleid++;
00214 voxele[voxeleid][0]=voxelvid+1; voxele[voxeleid][1]=voxelvid+5; voxeleid++;
00215 voxele[voxeleid][0]=voxelvid+2; voxele[voxeleid][1]=voxelvid+6; voxeleid++;
00216 voxele[voxeleid][0]=voxelvid+3; voxele[voxeleid][1]=voxelvid+7; voxeleid++;
00217
00218 voxelv[voxelvid][0]=n->mi[0]; voxelv[voxelvid][1]=n->mi[1]; voxelv[voxelvid][2]=n->mi[2]; voxelvid++;
00219 voxelv[voxelvid][0]=n->ma[0]; voxelv[voxelvid][1]=n->mi[1]; voxelv[voxelvid][2]=n->mi[2]; voxelvid++;
00220 voxelv[voxelvid][0]=n->ma[0]; voxelv[voxelvid][1]=n->ma[1]; voxelv[voxelvid][2]=n->mi[2]; voxelvid++;
00221 voxelv[voxelvid][0]=n->mi[0]; voxelv[voxelvid][1]=n->ma[1]; voxelv[voxelvid][2]=n->mi[2]; voxelvid++;
00222 voxelv[voxelvid][0]=n->mi[0]; voxelv[voxelvid][1]=n->mi[1]; voxelv[voxelvid][2]=n->ma[2]; voxelvid++;
00223 voxelv[voxelvid][0]=n->ma[0]; voxelv[voxelvid][1]=n->mi[1]; voxelv[voxelvid][2]=n->ma[2]; voxelvid++;
00224 voxelv[voxelvid][0]=n->ma[0]; voxelv[voxelvid][1]=n->ma[1]; voxelv[voxelvid][2]=n->ma[2]; voxelvid++;
00225 voxelv[voxelvid][0]=n->mi[0]; voxelv[voxelvid][1]=n->ma[1]; voxelv[voxelvid][2]=n->ma[2]; voxelvid++;
00226 voxelc++;
00227 if(n->octree[0] != NULL)createVoxelData(n->octree[0]);
00228 if(n->octree[1] != NULL)createVoxelData(n->octree[1]);
00229 if(n->octree[2] != NULL)createVoxelData(n->octree[2]);
00230 if(n->octree[3] != NULL)createVoxelData(n->octree[3]);
00231 if(n->octree[4] != NULL)createVoxelData(n->octree[4]);
00232 if(n->octree[5] != NULL)createVoxelData(n->octree[5]);
00233 if(n->octree[6] != NULL)createVoxelData(n->octree[6]);
00234 if(n->octree[7] != NULL)createVoxelData(n->octree[7]);
00235 return;
00236 }