00001
00002
00003
00004
00005
00006
00007
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <math.h>
00011 #include <setjmp.h>
00012 #include <windows.h>
00013
00014 #include "struct.h"
00015 #include "dstruct.h"
00016
00017 #if __X__MIPS__
00018 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00019 #endif
00020
00021 static HWND hParent;
00022 static HINSTANCE hThisInstance;
00023
00024 #define DOS386
00025 #define _X__FAR
00026 #define PI 3.1415926
00027
00028 #ifndef min
00029 #define min(a,b) ( ((a) < (b)) ? (a) : (b) )
00030 #endif
00031 #ifndef max
00032 #define max(a,b) ( ((a) > (b)) ? (a) : (b) )
00033 #endif
00034
00035 #define MINUNIT 2048L // was 1024 trying larger to prevent error
00036 #define MAXUNIT 4194304L //1073741824L
00037 #define PI2 PI/2
00038
00039 #define DESELECTED 0
00040 #define SELECTED 1
00041 #define HIDDEN 2
00042 #define INEDITOR 6
00043
00044 typedef struct tagMap3DS {
00045 char name[15];
00046 unsigned char dr,dg,db;
00047 } Map3DS;
00048
00049 static Map3DS *map3DSlist=NULL;
00050 static long map3DScount;
00051 static face **faces=NULL;
00052 static long fcc;
00053 static unsigned short *faceid=NULL;
00054 static long lrulerx,lrulery,lrulerz;
00055 static double ruler;
00056
00057 static void mes3ds(char *s){
00058 return;
00059 }
00060
00061 static long AdjacentTo(face *f, face *F){
00062 long F0,F1,F2,f0,f1,f2;
00063 F0=F->V[0]; F1=F->V[1]; F2=F->V[2];
00064 f0=f->V[0]; f1=f->V[1]; f2=f->V[2];
00065 if(f0 == F0 && f2 == F1)return 1;
00066 if(f2 == F0 && f0 == F1){f->V[2]=f0; f->V[0]=f2; return 1;}
00067 if(f2 == F0 && f1 == F1)return 1;
00068 if(f1 == F0 && f2 == F1){f->V[1]=f2; f->V[2]=f1; return 1;}
00069 if(f1 == F0 && f0 == F1)return 1;
00070 if(f0 == F0 && f1 == F1){f->V[0]=f1; f->V[1]=f0; return 1;}
00071 if(f0 == F1 && f2 == F2)return 1;
00072 if(f2 == F1 && f0 == F2){f->V[2]=f0; f->V[0]=f2; return 1;}
00073 if(f2 == F1 && f1 == F2)return 1;
00074 if(f1 == F1 && f2 == F2){f->V[1]=f2; f->V[2]=f1; return 1;}
00075 if(f1 == F1 && f0 == F2)return 1;
00076 if(f0 == F1 && f1 == F2){f->V[0]=f1; f->V[1]=f0; return 1;}
00077 if(f0 == F2 && f2 == F0)return 1;
00078 if(f2 == F2 && f0 == F0){f->V[2]=f0; f->V[0]=f2; return 1;}
00079 if(f2 == F2 && f1 == F0)return 1;
00080 if(f1 == F2 && f2 == F0){f->V[1]=f2; f->V[2]=f1; return 1;}
00081 if(f1 == F2 && f0 == F0)return 1;
00082 if(f0 == F2 && f1 == F0){f->V[0]=f1; f->V[1]=f0; return 1;}
00083 return 0;
00084 }
00085
00086 static void NormaliseAdjacentFaces(face *F){
00087 long i;
00088 face *f;
00089 if(fcc > 0)for(i=0;i<fcc;i++){
00090 if((f=faces[i]) != NULL && AdjacentTo(f,F)){
00091 faces[i]=NULL;
00092 NormaliseAdjacentFaces(f);
00093 }
00094 }
00095 }
00096
00097 static void MakeNormalsPointOut(unsigned short nf, char *name){
00098 long i;
00099 long fp;
00100 face *Fp;
00101 char str[80];
00102 if((faces = (face **)X__Malloc((long)nf*(long)sizeof(face *))) == NULL){
00103 mes3ds("out of memory");
00104 return;
00105 }
00106 fcc=0;
00107 fp=0; while(fp < Nface){
00108 Fp=(MainFp+fp);
00109 if((MainVp+Fp->V[0])->status == INEDITOR &&
00110 (MainVp+Fp->V[1])->status == INEDITOR &&
00111 (MainVp+Fp->V[2])->status == INEDITOR)faces[fcc++]=Fp;
00112 fp++;
00113 }
00114 sprintf(str,"%6ld polygons in object %s",fcc,name);
00115 mes3ds(str);
00116 if(fcc > 0)for(i=0;i<fcc;i++){
00117 if((Fp=faces[i]) != NULL){
00118 faces[i]=NULL;
00119 NormaliseAdjacentFaces(Fp);
00120 }
00121 }
00122 X__Free(faces);
00123 }
00124
00125 static void Add3dsMaterial(face *f, unsigned char *color){
00126 long i;
00127 if(map3DScount > 0){
00128 return;
00129 for(i=0;i<map3DScount;i++){
00130 if(map3DSlist[i].dr == color[0] &&
00131 map3DSlist[i].dg == color[1] &&
00132 map3DSlist[i].db == color[2]){
00133
00134 return;
00135 }
00136 }
00137 }
00138 if(map3DScount == 0)
00139 map3DSlist = (Map3DS *)X__Malloc((map3DScount+1)*sizeof(Map3DS));
00140 else
00141 map3DSlist = (Map3DS *)X__Realloc(map3DSlist,(map3DScount+1)*sizeof(Map3DS));
00142 if(map3DSlist == NULL){
00143 mes3ds("out of memory");
00144 return;
00145 }
00146 map3DSlist[map3DScount].dr=color[0];
00147 map3DSlist[map3DScount].dg=color[1];
00148 map3DSlist[map3DScount].db=color[2];
00149
00150 map3DScount++;
00151 }
00152
00153 void WriteMapChunk(FILE *fi){
00154 long i,pos_map,
00155 len_map,len_name,len14=14,len15=15,len8=8,len6=6,
00156 cpos;
00157 char name[16];
00158
00159
00160 char onebyte=0,sixbytes[6]={17,0,9,0,0,0},zero=0,
00161 sixbytes1[6]={48,0,8,0,0,0};
00162 unsigned char white[3]={255,255,255},grey[3]={64,64,64};
00163 char shinyness=50,transparency=0;
00164 unsigned short magic_afff=0xafff,
00165 magic_a000=0xa000,
00166 magic_a010=0xa010,
00167 magic_a020=0xa020,
00168 magic_a030=0xa030,
00169 magic_a040=0xa040,
00170 magic_a050=0xa050,
00171 magic_a052=0xa052,
00172 magic_a053=0xa053,
00173 magic_a100=0xa100,
00174 magic_a081=0xa081,
00175 oneshort;
00176 for(i=0;i<map3DScount;i++){
00177 fwrite(&magic_afff,sizeof(short),1,fi);
00178 len_map=0;
00179 pos_map=ftell(fi); fwrite(&len_map,sizeof(long),1,fi);
00180 sprintf(name,"MATERIAL%ld",i);
00181 strcpy(map3DSlist[i].name,name);
00182 fwrite(&magic_a000,sizeof(short),1,fi);
00183 len_name=strlen(name)+1+6;
00184 fwrite(&len_name,sizeof(long),1,fi);
00185 len_name -= 6;
00186 fwrite(name,1,len_name,fi);
00187 fwrite(&magic_a010,sizeof(short),1,fi);
00188 fwrite(&len15,sizeof(long),1,fi);
00189 fwrite(sixbytes,1,6,fi);
00190 fwrite(grey,1,3,fi);
00191 fwrite(&magic_a020,sizeof(short),1,fi);
00192 fwrite(&len15,sizeof(long),1,fi);
00193 fwrite(sixbytes,1,6,fi);
00194 fwrite(&(map3DSlist[i].dr),1,1,fi);
00195 fwrite(&(map3DSlist[i].dg),1,1,fi);
00196 fwrite(&(map3DSlist[i].db),1,1,fi);
00197 fwrite(&magic_a030,sizeof(short),1,fi);
00198 fwrite(&len15,sizeof(long),1,fi);
00199 fwrite(sixbytes,1,6,fi);
00200 fwrite(white,1,3,fi);
00201 fwrite(&magic_a040,sizeof(short),1,fi);
00202 fwrite(&len14,sizeof(long),1,fi);
00203 fwrite(sixbytes1,1,6,fi);
00204 fwrite(&shinyness,1,1,fi);
00205 fwrite(&onebyte,1,1,fi);
00206 fwrite(&magic_a050,sizeof(short),1,fi);
00207 fwrite(&len14,sizeof(long),1,fi);
00208 fwrite(sixbytes1,1,6,fi);
00209 fwrite(&transparency,1,1,fi);
00210 fwrite(&onebyte,1,1,fi);
00211 fwrite(&magic_a052,sizeof(short),1,fi);
00212 fwrite(&len14,sizeof(long),1,fi);
00213 fwrite(sixbytes1,1,6,fi);
00214 fwrite(&zero,1,1,fi);
00215 fwrite(&onebyte,1,1,fi);
00216 fwrite(&magic_a053,sizeof(short),1,fi);
00217 fwrite(&len14,sizeof(long),1,fi);
00218 fwrite(sixbytes1,1,6,fi);
00219 fwrite(&zero,1,1,fi);
00220 fwrite(&onebyte,1,1,fi);
00221 fwrite(&magic_a100,sizeof(short),1,fi);
00222 fwrite(&len8,sizeof(long),1,fi);
00223 oneshort=3;
00224 fwrite(&oneshort,sizeof(short),1,fi);
00225 fwrite(&magic_a081,sizeof(short),1,fi);
00226 fwrite(&len6,sizeof(long),1,fi);
00227 cpos=ftell(fi);
00228 fseek(fi,pos_map,SEEK_SET);
00229 pos_map = cpos-pos_map+2;
00230 fwrite(&pos_map,sizeof(long),1,fi);
00231 fseek(fi,0L,SEEK_END);
00232 }
00233 }
00234
00235 void Create3DSfile(FILE *fi){
00236 char layer[]={"MODEL"},cl[64];
00237 long fp,vp;
00238 vertex *Vp;
00239 face *Fp;
00240 skel *sp;
00241 long i;
00242 unsigned short nv,nf,j,k;
00243 float x,y,z,scale3ds=0.0001;
00244 long xmax = -MAXUNIT, ymax = -MAXUNIT, zmax = -MAXUNIT,
00245 xmin = MAXUNIT, ymin = MAXUNIT, zmin = MAXUNIT;
00246 unsigned short magic_4d4d=0x4d4d,
00247 magic_3d3d=0x3d3d,
00248 magic_4000=0x4000,
00249 magic_4100=0x4100,
00250 magic_4110=0x4110,
00251 magic_4120=0x4120,
00252 magic_4130=0x4130,
00253 magic_4150=0x4150,
00254 attribs=7;
00255 long pos_file,pos_sect,pos_obj,pos_mesh,pos_vert,pos_face,pos_mat,
00256 pos_num,pos_smo,
00257 len_file,len_sect,len_obj,len_mesh,len_vert,len_face,len_mat,
00258 len_smo,
00259 cpos,group;
00260 map3DSlist=NULL;
00261 map3DScount=0;
00262 len_file=len_sect=len_mesh=0;
00263 vp=0; while(vp <Nvert){
00264 Vp=(MainVp+vp);
00265 if(Vp->status == SELECTED){
00266 if(Vp->xyz[0] > xmax)xmax=Vp->xyz[0];
00267 if(Vp->xyz[1] > ymax)ymax=Vp->xyz[1];
00268 if(Vp->xyz[2] > zmax)zmax=Vp->xyz[2];
00269 if(Vp->xyz[0] < xmin)xmin=Vp->xyz[0];
00270 if(Vp->xyz[1] < ymin)ymin=Vp->xyz[1];
00271 if(Vp->xyz[2] < zmin)zmin=Vp->xyz[2];
00272 }
00273 vp++;
00274 }
00275 fwrite(&magic_4d4d,sizeof(short),1,fi);
00276 pos_file=ftell(fi); fwrite(&len_file,sizeof(long),1,fi);
00277 fwrite(&magic_3d3d,sizeof(short),1,fi);
00278 pos_sect=ftell(fi); fwrite(&len_sect,sizeof(long),1,fi);
00279 fp=0; while(fp < Nface){
00280 Fp=(MainFp+fp);
00281 if((MainVp+Fp->V[0])->status == SELECTED &&
00282 (MainVp+Fp->V[1])->status == SELECTED &&
00283 (MainVp+Fp->V[2])->status == SELECTED)
00284 Add3dsMaterial(Fp,Fp->color);
00285 fp++;
00286 }
00287 if(map3DScount > 0)WriteMapChunk(fi);
00288 sp=MainSp; for(;;){
00289 if(sp != NULL)strcpy(cl,sp->name);
00290 else strcpy(cl,layer);
00291 vp=0; nv=0; while(vp < Nvert){
00292 Vp=(MainVp+vp);
00293 if(Vp->status == SELECTED && Vp->sp == sp){
00294 Vp->status=INEDITOR;
00295 nv++;
00296 }
00297 vp++;
00298 }
00299 nf=0; fp=0; while(fp < Nface){
00300 Fp=(MainFp+fp);
00301 if((MainVp+Fp->V[0])->status == INEDITOR &&
00302 (MainVp+Fp->V[1])->status == INEDITOR &&
00303 (MainVp+Fp->V[2])->status == INEDITOR)nf++;
00304 fp++;
00305 }
00306 if(nf > 0){
00307 unsigned short id;
00308 MakeNormalsPointOut(nf,cl);
00309 len_obj=len_mesh=len_vert=len_face=0;
00310 fwrite(&magic_4000,sizeof(short),1,fi);
00311 pos_obj=ftell(fi); fwrite(&len_obj,sizeof(long),1,fi);
00312 fwrite(cl,1,strlen(cl)+1,fi);
00313 fwrite(&magic_4100,sizeof(short),1,fi);
00314 pos_mesh=ftell(fi); fwrite(&len_mesh,sizeof(long),1,fi);
00315 fwrite(&magic_4110,sizeof(short),1,fi);
00316 len_vert=6L+2L+3L*sizeof(float)*(long)nv;
00317 pos_vert=ftell(fi); fwrite(&len_vert,sizeof(long),1,fi);
00318 fwrite(&nv,sizeof(short),1,fi);
00319 i=0; vp=0; while(vp < Nvert){
00320 Vp=(MainVp+vp);
00321 if(Vp->status == INEDITOR){
00322 x=(float)(Vp->xyz[0]-lrulerx)/(float)ruler;
00323 y=(float)(Vp->xyz[1]-lrulery)/(float)ruler;
00324 z=(float)(Vp->xyz[2]-lrulerz)/(float)ruler;
00325 fwrite(&x,sizeof(float),1,fi);
00326 fwrite(&y,sizeof(float),1,fi);
00327 fwrite(&z,sizeof(float),1,fi);
00328 Vp->id = i++;
00329 }
00330 else Vp->id = 65535;
00331 vp++;
00332 }
00333 fwrite(&magic_4120,sizeof(short),1,fi);
00334 pos_face=ftell(fi); len_face=0; fwrite(&len_face,sizeof(long),1,fi);
00335 fwrite(&nf,sizeof(short),1,fi);
00336 fp=0; j=0; while(fp < Nface){
00337 Fp=(MainFp+fp);
00338 if((MainVp+Fp->V[0])->status == INEDITOR &&
00339 (MainVp+Fp->V[1])->status == INEDITOR &&
00340 (MainVp+Fp->V[2])->status == INEDITOR){
00341 id=(unsigned short)((MainVp+Fp->V[0])->id);
00342 fwrite(&id,sizeof(unsigned short),1,fi);
00343 id=(unsigned short)((MainVp+Fp->V[1])->id);
00344 fwrite(&id,sizeof(unsigned short),1,fi);
00345 id=(unsigned short)((MainVp+Fp->V[2])->id);
00346 fwrite(&id,sizeof(unsigned short),1,fi);
00347 fwrite(&attribs,sizeof(short),1,fi);
00348 faceid[fp] = (unsigned short)(j++);
00349 }
00350 fp++;
00351 }
00352 if(map3DScount > 0){
00353 for(i=0;i<map3DScount;i++){
00354 j=0;
00355 fp=0; while(fp < Nface){
00356 Fp=(MainFp+fp);
00357 if((MainVp+Fp->V[0])->status == INEDITOR &&
00358 (MainVp+Fp->V[1])->status == INEDITOR &&
00359 (MainVp+Fp->V[2])->status == INEDITOR ){
00360
00361 if(j == 0){
00362 fwrite(&magic_4130,sizeof(short),1,fi);
00363 pos_mat=ftell(fi); len_mat=0;
00364 fwrite(&len_mat,sizeof(long),1,fi);
00365 j=strlen(map3DSlist[i].name)+1;
00366 fwrite(map3DSlist[i].name,1,j,fi);
00367 pos_num=ftell(fi); j=0;
00368 fwrite(&j,sizeof(short),1,fi);
00369 }
00370 k=faceid[fp];
00371 fwrite(&k,sizeof(short),1,fi);
00372 j++;
00373 }
00374 fp++;
00375 }
00376 if(j > 0){
00377 cpos=ftell(fi);
00378 fseek(fi,pos_mat,SEEK_SET);
00379 pos_mat = cpos-pos_mat+2;
00380 fwrite(&pos_mat,sizeof(long),1,fi);
00381 fseek(fi,pos_num,SEEK_SET);
00382 fwrite(&j,sizeof(short),1,fi);
00383 fseek(fi,0L,SEEK_END);
00384 }
00385 }
00386 }
00387 fwrite(&magic_4150,sizeof(short),1,fi);
00388 pos_smo=ftell(fi); len_smo=6+nf*sizeof(long);
00389 fwrite(&len_smo,sizeof(long),1,fi);
00390 fp=0; while(fp < Nface){
00391 Fp=(MainFp+fp);
00392 if((MainVp+Fp->V[0])->status == INEDITOR &&
00393 (MainVp+Fp->V[1])->status == INEDITOR &&
00394 (MainVp+Fp->V[2])->status == INEDITOR){
00395 group=0;
00396 fwrite(&group,sizeof(long),1,fi);
00397 }
00398 fp++;
00399 }
00400 cpos=ftell(fi);
00401 fseek(fi,pos_face,SEEK_SET);
00402 len_face = cpos-pos_face+2;
00403 fwrite(&len_face,sizeof(long),1,fi);
00404 fseek(fi,pos_obj,SEEK_SET);
00405 pos_obj = cpos-pos_obj+2;
00406 fwrite(&pos_obj,sizeof(long),1,fi);
00407 fseek(fi,pos_mesh,SEEK_SET);
00408 pos_mesh = cpos-pos_mesh+2;
00409 fwrite(&pos_mesh,sizeof(long),1,fi);
00410 fseek(fi,0L,SEEK_END);
00411 }
00412 vp=0; while(vp < Nvert){
00413 Vp=(MainVp+vp);
00414 if(Vp->status == INEDITOR)Vp->status=SELECTED;
00415 vp++;
00416 }
00417 if(sp == NULL)break;
00418 sp=sp->last;
00419 }
00420 cpos=ftell(fi);
00421 fseek(fi,pos_sect,SEEK_SET);
00422 pos_sect = cpos-pos_sect+2;
00423 fwrite(&pos_sect,sizeof(long),1,fi);
00424 fseek(fi,pos_file,SEEK_SET);
00425 pos_file = cpos-pos_file+2;
00426 fwrite(&pos_file,sizeof(long),1,fi);
00427 fseek(fi,0L,SEEK_END);
00428 }
00429
00430 #if __WATCOMC__
00431 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00432 #else
00433 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00434 #endif
00435 switch (dwReason) {
00436 case DLL_PROCESS_ATTACH: {
00437 #if __X__MIPS__
00438 if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00439 #endif
00440 hThisInstance=hDLL;
00441 break;
00442 }
00443 case DLL_PROCESS_DETACH:
00444 #if __X__MIPS__
00445 if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00446 #endif
00447 break;
00448 }
00449 return TRUE;
00450 }
00451
00452 long _Export
00453 (HWND parent_window, char *filename,X__STRUCTURE *lpevi){
00454 char layer[8]={"MODEL"},cl[16];
00455 FILE *dxfp;
00456 vertex *Vp,*V0,*V1,*V2;
00457 face *Fp;
00458 skel *sp;
00459 long vp,fp;
00460 long i,nf,colour=7;
00461 long xmax = -MAXUNIT, ymax = -MAXUNIT, zmax = -MAXUNIT,
00462 xmin = MAXUNIT, ymin = MAXUNIT, zmin = MAXUNIT;
00463 lpEVI=lpevi;
00464 if(filename == NULL)return 0;
00465 if(NvertSelect == 0 || Nface == 0){
00466 MessageBox(parent_window,"Too few vertices or faces selected",NULL,MB_OK);
00467 return 0;
00468 }
00469 lrulerx= (*(lpEVI->orulerx));
00470 lrulery= (*(lpEVI->orulery));
00471 lrulerz= (*(lpEVI->orulerz));
00472 ruler = (*(lpEVI->ruler));
00473 if((dxfp=fopen(filename,"wb")) != NULL){
00474 if((faceid=(unsigned short *)X__Malloc(Nface*sizeof(unsigned short))) != NULL){
00475 Create3DSfile(dxfp);
00476 X__Free(faceid);
00477 }
00478 else MessageBox(NULL,"No memory",NULL,MB_OK);
00479 fclose(dxfp);
00480 }
00481 else{
00482 MessageBox(parent_window,"File open Error",NULL,MB_OK);
00483 }
00484 if(map3DSlist != NULL)X__Free(map3DSlist);
00485 return 1;
00486 }