ATM2.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 1.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 OpenFX Development Team
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019 You may contact the OpenFX development team via elecronic mail
00020 at core@openfx.org, or visit our website at http://openfx.org for
00021 further information and support details.
00022 -- */
00023 
00024 /* file ATM2.C  build Characters */
00025 
00026 #define SELECTED   1
00027 #define DESELECTED 0
00028 
00029 static long VP,VF;
00030 
00031 static void GetATMholdPoint(long *x, long *y, long cx, long cy, short pt);
00032 static void process_type1_routine(character_program Cp);
00033 static long CurveUpto(long vp, point *p, double d, long n);
00034 
00035 static void DeselectVertexSet(long vs, long vf){
00036  vertex *Vs;
00037  while(vs < vf){
00038    Vs=(MainVp+vs);
00039    if(Vs->status == SELECTED){
00040       Vs->status = DESELECTED; NvertSelect--; NvertDeselect++;
00041    }
00042    vs++;
00043  }
00044 }
00045 
00046 static void SelectVertexSet(long vs, long vf){
00047  vertex *Vs;
00048  while(vs < vf){
00049    Vs=(MainVp+vs);
00050    if(Vs->status == DESELECTED){
00051       Vs->status = SELECTED; NvertSelect++; NvertDeselect--;
00052    }
00053    vs++;
00054  }
00055 }
00056 
00057 static void MakeNewPSletter(HWND hwnd){
00058  long i,j,char_id,Depth,Opx,Opy,Opz;
00059  int ifail,capped=0;
00060  long Vstart,Vstop,BackStart,BackStop,fBevelStart,fBevelStop,Vfirst;
00061  long ep,Estart=-1;
00062  long fp,LastFace;
00063  skel *sp;
00064  Vfirst=Nvert;
00065  char_id=0;
00066  Opx=NpointerX; Opy=NpointerY; Opz=NpointerZ;
00067  DeselectVertexSet(0,Nvert);
00068  while ((j=(long)lpAtm->ATM_Letters[char_id++]) > 0){
00069    n_Subroutines = 0; C_Subs=NULL; Cprogram.n=0; Cprogram.p=NULL;
00070    if((type1_stack=(int *)X__Malloc(512*sizeof(int))) == NULL){
00071      MessageBox(hwnd,"Out of memory","ATM",MB_OK);
00072      return;
00073    }
00074    if((ifail=decode_build_type1((int)j,lpAtm->last_ATM_font)) != OK){
00075      if(ifail == FAIL){
00076        MessageBox(hwnd,"Font corrupt","ATM",MB_OK);
00077      }
00078      else if(ifail == MEMFAIL){
00079        MessageBox(hwnd,"Out of memory","ATM",MB_OK);
00080      }
00081      goto FREEALL;
00082    }
00083    SP=0; XX=NpointerY; YY=NpointerZ;
00084    Cwidthx=0; Cwidthy=0; Vstart=Nvert; Estart=Nedge; VF=VP= -1;
00085    process_type1_routine(Cprogram);
00086    if(lpAtm->ATM_chara_width > 0){
00087      Depth=MaxScale*(double)lpAtm->ATM_chara_width/100.0*Scale;
00088    }
00089    else Depth=0;
00090    if(j == 32){
00091      UpdateVertexHeap(Nvert+2);
00092      CreateVertex();
00093      (MainVp+Nvert-1)->xyz[0]=NpointerX-Depth/2;
00094      (MainVp+Nvert-1)->xyz[1]=NpointerY;
00095      (MainVp+Nvert-1)->xyz[2]=NpointerZ;
00096      CreateVertex();
00097      (MainVp+Nvert-1)->xyz[0]=NpointerX-Depth/2;
00098      (MainVp+Nvert-1)->xyz[1]=NpointerY+Cwidthx*lpAtm->FORB;
00099      (MainVp+Nvert-1)->xyz[2]=NpointerZ+Cwidthy;
00100      UpdateEdgeHeap(Nedge+1);
00101      CreateEdge(Nvert-1,Nvert-2);
00102    }
00103    NpointerY += Cwidthx*lpAtm->FORB; NpointerZ += Cwidthy;
00104    FREEALL:
00105    X__Free(type1_stack);
00106    if(Cprogram.p != NULL)X__Free(Cprogram.p);
00107    if(C_Subs != NULL && n_Subroutines > 0){
00108      for(i=0;i<n_Subroutines;i++){
00109        if(C_Subs[i].p != NULL)X__Free(C_Subs[i].p);
00110      }
00111      X__Free(C_Subs);
00112    }
00113    C_Subs=NULL; Cprogram.p=NULL;
00114    Vstop=Nvert; VP=Vstart; while(VP < Nvert){
00115      (MainVp+VP)->xyz[1] += rand()%4-2;  /* NB this helps fools the filling */
00116                                 /* which can fail on some cases    */
00117      VP++;
00118    }
00119    if(Vstop == Vstart)ifail=FAIL;
00120    if(ifail == FAIL)break;
00121    CreateSkeleton(FirstSp);  sp=MainSp;
00122    if(j == 32){
00123      strcpy(MainSp->name,"Space");
00124    }
00125    else{
00126      if(j > 64 && j < 91)sprintf(MainSp->name,"%c%ld-C",j,char_id);
00127      else                sprintf(MainSp->name,"%c%ld",j,char_id);
00128    }
00129    MainSp->xyz[0]=NpointerX-Depth/2;
00130    GetATMholdPoint(&MainSp->xyz[1],&MainSp->xyz[2],Cwidthx,Cwidthy,0);
00131 //   ZeroSkeletonBoundingBox(MainSp);
00132    CreateSkeleton(MainSp);
00133    strcpy(MainSp->name,"F.Pt.");
00134    MainSp->xyz[0]=NpointerX-Depth/2;
00135    GetATMholdPoint(&MainSp->xyz[1],&MainSp->xyz[2],Cwidthx,Cwidthy,1);
00136 //   ZeroSkeletonBoundingBox(MainSp);
00137    DeselectVertexSet(Vstart,Vstop);
00138    Estart=Nedge;
00139    LastFace=Nface;
00140    if(j == 32)goto SPACEBREAK;
00141    if(lpAtm->ATM_cap && !lpAtm->ATM_bevel_front && !lpAtm->ATM_bevel_back){
00142      capped=1;
00143      SelectVertexSet(Vstart,Vstop);
00144      LastFace=Nface;
00145      if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00146      DeselectVertexSet(Vstart,Vstop);
00147      fp=LastFace; while(fp < Nface){
00148        for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00149        fp++;
00150      }
00151      LastFace=Nface;
00152    }
00153    if(lpAtm->ATM_chara_width > 0){
00154      SelectVertexSet(Vstart,Vstop);
00155      BackStart=Nvert; LastFace=Nface;
00156      if(!CreateAttachedCopy(1))break; /* copy failed */
00157      BackStop=Nvert;
00158      DeselectVertexSet(BackStart,BackStop);
00159      VP=BackStart; while(VP < BackStop){
00160        (MainVp+VP)->xyz[0] -= Depth;
00161        VP++;
00162      }
00163      fp=LastFace; while(fp < Nface){
00164        for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_side_colour[i];
00165 //       (MainFp+fp)->attrib |= 0x80;
00166        fp++;
00167      }
00168      LastFace=Nface;
00169    }
00170    else{BackStart=Vstart; BackStop=Vstop;}
00171    if((lpAtm->FORB > 0 && lpAtm->ATM_bevel_front) ||
00172       (lpAtm->FORB < 0 && lpAtm->ATM_bevel_back)){
00173      SelectVertexSet(Vstart,Vstop);
00174      fBevelStart=Nvert; LastFace=Nface;
00175      if(AutoFacetCurveWithHoles(3,0,1,(double)lpAtm->ATM_bevel_angle,
00176        (double)lpAtm->ATM_bevel_width/2000.0*MaxScale*Scale) == FAIL)break;
00177      fBevelStop=Nvert;
00178      fp=LastFace; while(fp < Nface){
00179        for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_beve_colour[i];
00180 //       (MainFp+fp)->attrib |= 0x80;
00181        fp++;
00182      }
00183      LastFace=Nface;
00184      if(lpAtm->ATM_cap){
00185        if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00186        fp=LastFace; while(fp < Nface){
00187          for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00188          fp++;
00189        }
00190        LastFace=Nface;
00191      }
00192      DeselectVertexSet(fBevelStart,fBevelStop);
00193    }
00194    else if(lpAtm->ATM_cap && !capped){
00195      SelectVertexSet(Vstart,Vstop);
00196      LastFace=Nface;
00197      if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00198      DeselectVertexSet(Vstart,Vstop);
00199      fp=LastFace; while(fp < Nface){
00200        for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00201        fp++;
00202      }
00203      LastFace=Nface;
00204    }
00205    if((lpAtm->FORB > 0 && lpAtm->ATM_bevel_back) ||
00206       (lpAtm->FORB < 0 && lpAtm->ATM_bevel_front)){
00207      SelectVertexSet(BackStart,BackStop);
00208      fBevelStart=Nvert; LastFace=Nface;
00209      if(AutoFacetCurveWithHoles(3,0,1,(double)(lpAtm->ATM_bevel_angle * -1),
00210        (double)lpAtm->ATM_bevel_width/2000.0*MaxScale*Scale) == FAIL)break;
00211      fBevelStop=Nvert;
00212      fp=LastFace; while(fp < Nface){
00213        for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_beve_colour[i];
00214 //       (MainFp+fp)->attrib |= 0x80;
00215        fp++;
00216      }
00217      LastFace=Nface;
00218      if(lpAtm->ATM_cap){
00219        if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00220        fp=LastFace; while(fp < Nface){
00221          for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00222          fp++;
00223        }
00224        LastFace=Nface;
00225      }
00226      DeselectVertexSet(fBevelStart,fBevelStop);
00227    }
00228    else if(lpAtm->ATM_cap && !capped){
00229      SelectVertexSet(BackStart,BackStop);
00230      LastFace=Nface;
00231      if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00232      DeselectVertexSet(BackStart,BackStop);
00233      fp=LastFace; while(fp < Nface){
00234        for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00235        fp++;
00236      }
00237      LastFace=Nface;
00238    }
00239    SPACEBREAK:
00240    VP=Vstart; while(VP < Nvert){
00241      (MainVp+VP)->sp=sp;
00242      VP++;
00243    }
00244    DrawModel();
00245  }
00246  SelectVertexSet(Vfirst,Nvert);
00247  NpointerX=Opx; NpointerY=Opy; NpointerZ=Opz;
00248 //DrawModel();
00249  return;
00250 }
00251 
00252 static void GetATMholdPoint(long *x, long *y, long cx, long cy, short pt){
00253   long x0,y0;
00254   double offx[]={0.0,0.5,1.0,  0.5,  0.0  ,0.5,  1.0};
00255   double offy[]={0.0,0.0,0.0,300.0,600.0,600.0,600.0};
00256   x0=NpointerY-cx*lpAtm->FORB;
00257   y0=NpointerZ-cy;
00258   if(pt == 0){
00259    *x=x0+(long)(offx[lpAtm->ATM_offset]*(double)cx)*lpAtm->FORB;
00260    *y=y0+(long)(offy[lpAtm->ATM_offset]*Scale);
00261   }
00262   else{ /* follow point */
00263    *x=x0+(long)((offx[lpAtm->ATM_offset]+1.0)*(double)cx)*lpAtm->FORB;
00264    *y=y0+(long)(offy[lpAtm->ATM_offset]*Scale+(double)cy);
00265   }
00266 }
00267 
00268 
00269 static void process_type1_routine(character_program Cp){
00270   int i,com,sid,last_line=0;
00271   long u,v,w,x,y,z;
00272   for(i=0;i<Cp.n;i++){
00273     com=(int)Cp.p[i].i;
00274     if(Cp.p[i].com == 0)type1_stack[SP++] = com;
00275     else{
00276       switch(com){
00277         case 1:  /* hstem */          SP=0; break;     /* ignored */
00278         case 3:  /* vstem */          SP=0; break;     /* ignored */
00279         case 4:  /* vmoveto */
00280           x = 0; y = (long)type1_stack[SP-1];
00281           goto MOVEJUMP;
00282         case 5:  /* rlineto */
00283           x = (long)type1_stack[SP-2];
00284           y = (long)type1_stack[SP-1];
00285           LINEJUMP:
00286           last_line=1;
00287           if(VP < 0){
00288             UpdateVertexHeap(Nvert+1);
00289             CreateVertex();
00290             (MainVp+Nvert-1)->xyz[1]=XX;
00291             (MainVp+Nvert-1)->xyz[2]=YY;
00292             (MainVp+Nvert-1)->xyz[0]=NpointerX;
00293             VP=VF=Nvert-1;
00294           }
00295           UpdateVertexHeap(Nvert+1);
00296           CreateVertex(); /* add midpoint vertex to prevent 3 sided holes! */
00297           UpdateEdgeHeap(Nedge+1);
00298           CreateEdge(VP,Nvert-1);
00299           (MainVp+Nvert-1)->xyz[1]=XX+x*Scale/2*lpAtm->FORB;
00300           (MainVp+Nvert-1)->xyz[2]=YY+y*Scale/2;
00301           (MainVp+Nvert-1)->xyz[0]=NpointerX;
00302           VP=Nvert-1;
00303           XX += x*Scale*lpAtm->FORB;  YY += y*Scale;
00304           if(VF >= 0 && (MainVp+VF)->xyz[1] == XX
00305                      && (MainVp+VF)->xyz[2] == YY){
00306             UpdateEdgeHeap(Nedge+1);
00307             CreateEdge(VP,VF);
00308             VP=VF;
00309           }
00310           else{
00311             UpdateVertexHeap(Nvert+1);
00312             CreateVertex(); /* vertex at end of straight edge segment */
00313             UpdateEdgeHeap(Nedge+1);
00314             CreateEdge(VP,Nvert-1);
00315             (MainVp+Nvert-1)->xyz[1]=XX;
00316             (MainVp+Nvert-1)->xyz[2]=YY;
00317             (MainVp+Nvert-1)->xyz[0]=NpointerX;
00318             VP=Nvert-1;
00319           }
00320           SP=0; break;
00321         case 6:  /* hlineto */
00322           y = 0; x = (long)type1_stack[SP-1];
00323           goto LINEJUMP;
00324         case 7:  /* vlineto */
00325           x = 0; y = (long)type1_stack[SP-1];
00326           goto LINEJUMP;
00327         case 8:  /* rrcurveto */
00328           u = (long)type1_stack[SP-6];
00329           v = (long)type1_stack[SP-5];
00330           w = (long)type1_stack[SP-4];
00331           x = (long)type1_stack[SP-3];
00332           y = (long)type1_stack[SP-2];
00333           z = (long)type1_stack[SP-1];
00334           CURVEJUMP:
00335           last_line=0;
00336           if(VP < 0){
00337             UpdateVertexHeap(Nvert+1);
00338             CreateVertex();
00339             (MainVp+Nvert-1)->xyz[1]=XX;
00340             (MainVp+Nvert-1)->xyz[2]=YY;
00341             (MainVp+Nvert-1)->xyz[0]=NpointerX;
00342             VP=VF=Nvert-1;
00343           }
00344           PP[0][0]=XX; PP[0][1]=YY; PP[0][2]=0;
00345           XX += u*Scale*lpAtm->FORB; YY += v*Scale;
00346           PP[1][0]=XX; PP[1][1]=YY; PP[1][2]=0;
00347           XX += w*Scale*lpAtm->FORB; YY += x*Scale;
00348           PP[2][0]=XX; PP[2][1]=YY; PP[2][2]=0;
00349           XX += y*Scale*lpAtm->FORB; YY += z*Scale;
00350           PP[3][0]=XX; PP[3][1]=YY; PP[3][2]=0;
00351           VP=CurveUpto(VP,PP,MaxScale*Scale,Nmax);
00352           SP=0; break;
00353         case 9:  /* closepath */
00354           if(VF == VP){ /* path already closed */
00355             VF=VP=-1;
00356             break;
00357           }
00358           if(VF >= 0 && VP >= 0){
00359             if(last_line){/* if last segment was a line add a mid point */
00360               UpdateVertexHeap(Nvert+1);
00361               CreateVertex();
00362               (MainVp+Nvert-1)->xyz[1]=((MainVp+VP)->xyz[1]+(MainVp+VF)->xyz[1])/2;
00363               (MainVp+Nvert-1)->xyz[2]=((MainVp+VP)->xyz[2]+(MainVp+VF)->xyz[2])/2;
00364               (MainVp+Nvert-1)->xyz[0]=NpointerX;
00365               UpdateEdgeHeap(Nedge+1);
00366               CreateEdge(VP,Nvert-1);
00367               VP=Nvert-1;
00368             }
00369             UpdateEdgeHeap(Nedge+1);
00370             CreateEdge(VP,VF);
00371           }
00372           VF=VP= -1;
00373           SP=0; break;
00374         case 10: /* callsubr */
00375           /* if other subs return -1 then sub is invalid and not called */
00376           sid=type1_stack[SP-1];
00377           SP=0;
00378           if(sid >= 0 && sid < n_Subroutines)
00379              process_type1_routine(C_Subs[sid]);
00380           break;
00381         case 11: /* return */
00382           SP=0; return;
00383         case 13: /* hsbw */
00384           XX = NpointerY+(long)type1_stack[SP-2]*Scale*lpAtm->FORB;
00385           Cwidthx=(long)type1_stack[SP-1]*Scale;
00386           SP=0; break;
00387         case 14: /* endchar */
00388           SP=0; break;  /* this should be the last command anyway */
00389         case 21: /* rmoveto */
00390           x = (long)type1_stack[SP-2];
00391           y = (long)type1_stack[SP-1];
00392           MOVEJUMP:
00393           last_line=0;
00394           XX += x*Scale*lpAtm->FORB; YY += y*Scale;
00395           SP=0; break;
00396         case 22: /* hmoveto */
00397           y = 0; x = (long)type1_stack[SP-1];
00398           goto MOVEJUMP;
00399         case 30: /* vhcurveto */
00400           u = 0;
00401           v = (long)type1_stack[SP-4];
00402           w = (long)type1_stack[SP-3];
00403           x = (long)type1_stack[SP-2];
00404           y = (long)type1_stack[SP-1];
00405           z = 0;
00406           goto CURVEJUMP;
00407         case 31: /* hvcurveto */
00408           u = (long)type1_stack[SP-4];
00409           v = 0;
00410           w = (long)type1_stack[SP-3];
00411           x = (long)type1_stack[SP-2];
00412           y = 0;
00413           z = (long)type1_stack[SP-1];
00414           goto CURVEJUMP;
00415         case 12:
00416           i++; com=Cp.p[i].i; /* assume that it is a command */
00417           switch (com) {
00418             case 0:  /* dotsection */   SP=0; break;
00419             case 1:  /* vstem3 */       SP=0; break;
00420             case 2:  /* hstem3 */       SP=0; break;
00421             case 6:  /* seac */
00422               SP=0; break;      /* not implemented */
00423             case 7:  /* sbw */
00424               XX = NpointerX+(long)type1_stack[SP-4]*Scale*lpAtm->FORB;
00425               YY = NpointerY+(long)type1_stack[SP-3]*Scale;
00426               Cwidthx=(long)type1_stack[SP-2]*Scale;
00427               Cwidthy=(long)type1_stack[SP-1]*Scale;
00428               SP=0; break;
00429             case 12: /* div */
00430               x = (long)type1_stack[SP-2];
00431               y = (long)type1_stack[SP-1];
00432               SP -= 1;
00433               type1_stack[SP-1] = (int)((double)x/(double)y);
00434               break;
00435             case 16: /* callothersubr */
00436               SP=0; break;  /* ignore other sub calls for 3D work; */
00437             case 17: /* pop  is only used for other subs which we ignore  */
00438               type1_stack[SP++] = -1; /* push a dummy variable onto stack */
00439               break;
00440             case 33: /* setcurrentpoint */
00441               SP=0; break; /* ignore this it is used with Other subs      */
00442             default:  SP=0; break;
00443           }
00444           break;
00445         default: SP=0; break;
00446       }
00447     }
00448   }
00449 }
00450 
00451 static long CurveUpto(long vp, point *p, double d, long n){
00452  long i,j,N;
00453  double l=0,mu;
00454  point po;
00455  for(i=0;i<3;i++)for(j=0;j<2;j++){
00456    l += ((double)(p[i+1][j] - p[i][j]))*(double)((p[i+1][j] - p[i][j]));
00457  }
00458  N=(long)((sqrt(l)/d)*(double)n);
00459  N=max(N,4);
00460  UpdateVertexHeap(Nvert+N+1);
00461  UpdateEdgeHeap(Nedge+N+1);
00462  for(i=1;i<=N;i++){
00463    mu=(double)i/(double)N;
00464    Casteljau2(po,p,0,3,mu);
00465    if(i == N && VF >= 0 && po[0] == (MainVp+VF)->xyz[1]
00466                         && po[1] == (MainVp+VF)->xyz[2]){
00467      ; /* do nothing clospath will fill it */
00468    }
00469    else{ /* last vertex not coincident with start of path */
00470      CreateVertex();
00471      CreateEdge(vp,Nvert-1);
00472      vp=Nvert-1;
00473      (MainVp+Nvert-1)->xyz[1]=po[0];
00474      (MainVp+Nvert-1)->xyz[2]=po[1];
00475      (MainVp+Nvert-1)->xyz[0]=NpointerX;
00476    }
00477  }
00478  UpdateVertexHeap(Nvert);
00479  UpdateEdgeHeap(Nedge);
00480  return Nvert-1;
00481 }

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