3DSOUT.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 - 2007 OpenFX Development Team
00004 -- */
00005 
00006 /* File 3dSOUT.C DLL to create a 3DS from EVI  */
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 /* definition of flags and identifiers*/
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 //       f->pad=(unsigned char)i;
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 // f->pad=(unsigned char)map3DScount;
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  /* sixbytes is 0x11 and size of 3 chars giving colours */
00159  /* sixbytes1 is 0x30 and size of 2 bytes for attr      */
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,   /* name     */
00166                 magic_a010=0xa010,   /* ambient  */
00167                 magic_a020=0xa020,   /* diffuse  */
00168                 magic_a030=0xa030,   /* specular */
00169                 magic_a040=0xa040,
00170                 magic_a050=0xa050,
00171                 magic_a052=0xa052,
00172                 magic_a053=0xa053,
00173                 magic_a100=0xa100,
00174                 magic_a081=0xa081,   /* 2 sided  */
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); /* ambient */
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); /* diffuse */
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); /* specular colour */
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); /* shinyness  0 - 100 */
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);  /* a_100 */
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);  /* 2 sided */
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(;;){ /* sp will be null for vertices not on any node */
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){ /* only write if there are any faces */
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 //              Fp->pad == (unsigned char)i){
00361              if(j == 0){
00362                fwrite(&magic_4130,sizeof(short),1,fi); /* material assign */
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); /* smoothing */
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){ /* reset status */
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  }  /* end of for(;;) */
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 }

Generated on Sun Apr 27 14:20:10 2014 for OpenFX by  doxygen 1.5.6