LIBRARY.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX - Modelling, Animation and Rendering Package
00003 -- */
00004 
00005 
00006 /* file LIBRARY.C     library of functions that may be helpful */
00007 
00008 // include some simple dialogs and drawing functions
00009 
00010 #define MODULE_LIBS 1
00011 
00012 #include "design.h"
00013 #include "..\animate\spin_dll.h"
00014 
00015 extern long LastToolVertex;
00016 
00017 static long local_grid_size=UNIT;
00018 
00019 typedef struct tagNUMENTRY {
00020   short low,high,val;
00021   char *title;
00022   char *message;
00023 } NUMENTRY;
00024 
00025 static BOOL CALLBACK NumEntryDlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ){
00026  NUMENTRY *dp;
00027  BOOL err;
00028  int i;
00029  switch( msg ) {
00030    case WM_PAINT:
00031      PaintDialogBackground(hwnd,ghinst_main);
00032      break;
00033    case WM_INITDIALOG:{
00034        dp=(NUMENTRY *)lparam;
00035        SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)dp->title);
00036        SendDlgItemMessage(hwnd,DLG_NUMENTRY_TEXT,WM_SETTEXT,0,
00037                           (LPARAM)dp->message);
00038        SetDlgItemInt(hwnd,DLG_NUMENTRY_EDIT,dp->val,FALSE);
00039        SendDlgItemMessage(hwnd,DLG_NUMENTRY_SPIN,SPNM_SETRANGE,0,
00040                           MAKELPARAM(dp->low,dp->high));
00041        SendDlgItemMessage(hwnd,DLG_NUMENTRY_SPIN,SPNM_SETCRNTVALUE,
00042                           (WPARAM)dp->val,0);
00043        SendDlgItemMessage(hwnd,DLG_NUMENTRY_SPIN,SPNM_SETEDITCTRL,0,
00044                           (LPARAM)GetDlgItem(hwnd,DLG_NUMENTRY_EDIT));
00045        SetWindowLong(hwnd,GWL_USERDATA,lparam);
00046        CentreDialogOnCursor(hwnd);
00047      }
00048      return (TRUE);
00049    case WM_COMMAND:
00050       dp=(NUMENTRY *)GetWindowLong(hwnd,GWL_USERDATA);
00051       switch(LOWORD(wparam)){
00052         case DLG_NUMENTRY_SPIN:
00053           switch(HIWORD(wparam)){
00054             case SPNN_VALUECHANGE:
00055             break;
00056             default: break;
00057           }
00058           break;
00059         case IDCANCEL:
00060         case DLG_NUMENTRY_CANCEL:
00061           EndDialog(hwnd, -1);
00062           return(TRUE);
00063         case IDOK:
00064         case DLG_NUMENTRY_OK:
00065           i=GetDlgItemInt(hwnd,DLG_NUMENTRY_EDIT,&err,FALSE);
00066           if(!err)EndDialog(hwnd, -1);
00067           if(i > dp->high)i=dp->high; if(i < dp->low)i=dp->low;
00068           EndDialog(hwnd,i);
00069           return(TRUE);
00070         default:
00071           break;
00072       }
00073       break;
00074     default: break;
00075  }
00076  return(FALSE);
00077 }
00078 
00079 short RequestNumEntry(short val, short minval, short maxval,
00080                       char *title, char *message){
00081  int i;
00082  NUMENTRY Numentry;
00083  Numentry.low=minval;
00084  Numentry.high=maxval;
00085  Numentry.val=val;
00086  Numentry.title=title;
00087  Numentry.message=message;
00088  EnableToolPannels(ALL_PANNELS,FALSE);
00089  i=DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_NUMENTRY),ghwnd_main,
00090             (DLGPROC)NumEntryDlgProc,(LPARAM)&Numentry);
00091  EnableToolPannels(ALL_PANNELS,TRUE);
00092  return (short)i;
00093 }
00094 
00095 typedef struct tagSTRINGDLGLIST {
00096   int  len;
00097   char *title;
00098   char *string;
00099 } STRINGDLGLIST;
00100 
00101 static BOOL CALLBACK StringDlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ){
00102  HWND hctl;
00103  STRINGDLGLIST *dp;
00104  switch( msg ) {
00105    case WM_PAINT:
00106      PaintDialogBackground(hwnd,ghinst_main);
00107      break;
00108    case WM_INITDIALOG:{
00109        dp=(STRINGDLGLIST *)lparam;
00110        hctl=GetDlgItem(hwnd,DLG_STRING_EDIT);
00111        SendMessage(hctl,WM_SETTEXT,0,(LPARAM)dp->string);
00112        SendMessage(hctl,EM_LIMITTEXT,(WPARAM)dp->len,0);
00113        SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)dp->title);
00114        SetWindowLong(hwnd,GWL_USERDATA,lparam);
00115        CentreDialogOnCursor(hwnd);
00116      }
00117      return (TRUE);
00118    case WM_COMMAND:
00119       switch(LOWORD(wparam)){
00120         case IDCANCEL:
00121           EndDialog(hwnd,FALSE);
00122           return(TRUE);
00123         case IDOK:
00124         case DLG_STRING_OK:
00125           dp=(STRINGDLGLIST *)GetWindowLong(hwnd,GWL_USERDATA);
00126           hctl=GetDlgItem(hwnd,DLG_STRING_EDIT);
00127           SendMessage(hctl,WM_GETTEXT,(WPARAM)dp->len,(LPARAM)dp->string);
00128           EndDialog(hwnd,TRUE);
00129           return(TRUE);
00130         default:
00131           break;
00132       }
00133       break;
00134     default: break;
00135  }
00136  return(FALSE);
00137 }
00138 
00139 int RequestCharString(int len, char *string, char *title, HWND parent){
00140  char tempstr[255];
00141  STRINGDLGLIST StringDlgList;
00142  strcpy(tempstr,string);
00143  StringDlgList.len=len;
00144  StringDlgList.string=tempstr;
00145  StringDlgList.title=title;
00146  if(DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_STRING),parent,
00147             (DLGPROC)StringDlgProc,(LPARAM)&StringDlgList)){
00148     strcpy(string,tempstr);
00149     return 1;
00150  }
00151  return 0;
00152 }
00153 
00154 void EnableToolPannels(int what_one,BOOL status){
00155   if(what_one & MAIN_WINDOW   )EnableWindow(ghwnd_main,status);
00156 //  if(what_one & TOOL_PANNEL   )EnableTools(status);
00157   if(what_one & COORD_PANNEL  )EnableWindow(ghwndCoord1,status);
00158 }
00159 
00160 typedef struct tagSELECTDLGLIST {
00161   int n;
00162   char *title;
00163   char **list;
00164 } SELECTDLGLIST;
00165 
00166 BOOL CALLBACK ItemSelectDlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ){
00167  int i;
00168  SELECTDLGLIST *dp;
00169  HWND hctl;
00170  switch( msg ) {
00171    case WM_PAINT:
00172      PaintDialogBackground(hwnd,ghinst_main);
00173      break;
00174    case WM_INITDIALOG:{
00175        dp=(SELECTDLGLIST *)lparam;
00176        hctl=GetDlgItem(hwnd,DLG_CHOOSE_LIST);
00177        for(i=0;i<dp->n;i++)SendMessage(hctl,LB_ADDSTRING,0,(LPARAM)dp->list[i]);
00178        SendMessage(hctl,LB_SETCURSEL,0,0);
00179        SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)dp->title);
00180        CentreDialogOnCursor(hwnd);
00181      }
00182      return (TRUE);
00183    case WM_COMMAND:
00184       switch(LOWORD(wparam)){
00185         case DLG_CHOOSE_LIST:
00186           switch(HIWORD(wparam)){
00187             case LBN_DBLCLK:
00188             SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(DLG_CHOOSE_OK,0),0);
00189               break;
00190             default:
00191               break;
00192           }
00193           break;
00194         case IDCANCEL:
00195         case DLG_CHOOSE_CANCEL:
00196           EndDialog(hwnd, -1);
00197           return (TRUE);
00198         case IDOK:
00199         case DLG_CHOOSE_OK:
00200           hctl=GetDlgItem(hwnd,DLG_CHOOSE_LIST);
00201           i=SendMessage(hctl,LB_GETCURSEL,0,0);
00202           EndDialog(hwnd,i);
00203           return(TRUE);
00204         default:
00205           break;
00206       }
00207       break;
00208  }
00209  return(FALSE);
00210 }
00211 
00212 
00213 int SelectScrolledItemList(int n, char **list, char *title, HWND parent){
00214  int i;
00215  SELECTDLGLIST SelectDlgList;
00216  SelectDlgList.n=n;
00217  SelectDlgList.list=list;
00218  SelectDlgList.title=title;
00219  EnableToolPannels(ALL_PANNELS,FALSE);
00220  i=DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_CHOOSE),parent,
00221             (DLGPROC)ItemSelectDlgProc,(LPARAM)&SelectDlgList);
00222  EnableToolPannels(ALL_PANNELS,TRUE);
00223  return i;
00224 }
00225 
00226 void  ActivateAllMenus(HWND hwnd, UINT fuFlags){
00227  static WORD enable_state[256];  /* must be >= number of menu commands */
00228  int id,i,j,k,n,m,o,c=0;
00229  HMENU hmenu,hsubmenu,hsubsubmenu;
00230  hmenu=GetMenu(hwnd);
00231  n=GetMenuItemCount(hmenu);
00232  if(n < 1)return;
00233  for(i=0;i<n;i++){
00234   if(i > 1)continue; /* don't fiddle with these menus */
00235   if((hsubmenu=GetSubMenu(hmenu,i)) == NULL){
00236     if((id=GetMenuItemID(hmenu,i)) < 0xffffffff){
00237       if(fuFlags == MF_GRAYED){
00238         enable_state[c] = GetMenuState(hmenu,id,MF_BYCOMMAND);
00239         EnableMenuItem(hmenu,id,fuFlags);
00240       }
00241       else EnableMenuItem(hmenu,id,enable_state[c]);
00242       c++;
00243     }
00244   }
00245   else{
00246     m=GetMenuItemCount(hsubmenu);
00247     for(j=0;j<m;j++){
00248       if(i == 0 && j >= 0)continue;
00249       if(i == 1 && (j ==  0 || j ==  4 || j == 5  ||
00250                     j ==  7 || j ==  9 || j == 10 ||
00251                     j == 11 || j == 12))continue;
00252       if((hsubsubmenu=GetSubMenu(hsubmenu,j)) == NULL){
00253         if((id=GetMenuItemID(hsubmenu,j)) < 0xffffffff){
00254           if(fuFlags == MF_GRAYED){
00255             enable_state[c] = GetMenuState(hsubmenu,id,MF_BYCOMMAND);
00256             EnableMenuItem(hsubmenu,id,fuFlags);
00257           }
00258           else EnableMenuItem(hsubmenu,id,enable_state[c]);
00259           c++;
00260         }
00261       }
00262       else{
00263         o=GetMenuItemCount(hsubsubmenu);
00264         for(k=0;k<o;k++){
00265           if((id=GetMenuItemID(hsubsubmenu,k)) < 0xffffffff){
00266             if(fuFlags == MF_GRAYED){
00267               enable_state[c] = GetMenuState(hsubsubmenu,id,MF_BYCOMMAND);
00268               EnableMenuItem(hsubsubmenu,id,fuFlags);
00269             }
00270             else EnableMenuItem(hsubsubmenu,id,enable_state[c]);
00271             c++;
00272           }
00273         }
00274       }
00275     }
00276   }
00277  }
00278 }
00279 
00280 PSTR FileInPath(PSTR pstrPath){
00281  PSTR pstr;
00282  pstr = pstrPath + strlen(pstrPath);
00283  while (pstr > pstrPath) {
00284      pstr = (AnsiPrev(pstrPath, pstr));
00285      if (*pstr == '\\' || *pstr == ':' || *pstr == '/') {
00286          pstr = (AnsiNext(pstr));
00287          break;
00288      }
00289  }
00290  return pstr;
00291 }
00292 
00293 #define ATOL 0.5
00294 
00295 void GetWorldCoords0(int W, long *x, long *y, long *z,
00296                      int hpos, int vpos);
00297 void GetWindowCoords0(int W, long x, long y, long z,
00298                      int *hpos, int *vpos);
00299 void GetWorldCoords1(int W, long *x, long *y, long *z,
00300                     int hpos, int vpos);
00301 void GetWindowCoords1(int W, long x, long y, long z,
00302                      int *hpos, int *vpos);
00303 
00304 
00305 void GetWorldCoords0(int W, long *x, long *y, long *z,
00306                     int hpos, int vpos){
00307   if(W == TRITOP){
00308     *x=(long)((double)(hpos-WindowCentreX[0])*WindowPixelSize)+TVcentreX;
00309     *y=(long)((double)(WindowCentreY[0]-vpos)*WindowPixelSize)+TVcentreY;
00310     *z=NpointerZ;
00311   }
00312   else if(W == TRIFRONT){
00313     *x=(long)((double)(hpos-WindowCentreX[1])*WindowPixelSize)+TVcentreX;
00314     *y=NpointerY;
00315     *z=(long)((double)(WindowCentreY[1]-vpos)*WindowPixelSize)+TVcentreZ;
00316   }
00317   else if(W == TRIRIGHT){
00318     *x=NpointerX;
00319     *y=(long)((double)(hpos-WindowCentreX[2])*WindowPixelSize)+TVcentreY;
00320     *z=(long)((double)(WindowCentreY[2]-vpos)*WindowPixelSize)+TVcentreZ;
00321   }
00322 }
00323 
00324 void GetWindowCoords0(int W, long x, long y, long z, int *hpos, int *vpos){
00325   if(W == TRITOP){
00326    *hpos=(int)((double)WindowCentreX[0]+(double)(x-TVcentreX)/WindowPixelSize+ATOL);
00327    *vpos=(int)((double)WindowCentreY[0]-(double)(y-TVcentreY)/WindowPixelSize+ATOL);
00328   }
00329   else if(W == TRIFRONT){
00330    *hpos=(int)((double)WindowCentreX[1]+(double)(x-TVcentreX)/WindowPixelSize+ATOL);
00331    *vpos=(int)((double)WindowCentreY[1]-(double)(z-TVcentreZ)/WindowPixelSize+ATOL);
00332   }
00333   else if(W == TRIRIGHT){
00334    *hpos=(int)((double)WindowCentreX[2]+(double)(y-TVcentreY)/WindowPixelSize+ATOL);
00335    *vpos=(int)((double)WindowCentreY[2]-(double)(z-TVcentreZ)/WindowPixelSize+ATOL);
00336   }
00337 }
00338 
00339 void GetWorldCoords1(int W, long *x, long *y, long *z,
00340                     int hpos, int vpos){
00341   if(W == TRITOP){
00342     *x=(long)((double)(WindowCentreX[0]-hpos)*WindowPixelSize)+TVcentreX;
00343     *y=(long)((double)(vpos-WindowCentreY[0])*WindowPixelSize)+TVcentreY;
00344     *z=NpointerZ;
00345   }
00346   else if(W == TRIFRONT){
00347     *x=(long)((double)(WindowCentreX[1]-hpos)*WindowPixelSize)+TVcentreX;
00348     *y=NpointerY;
00349     *z=(long)((double)(WindowCentreY[1]-vpos)*WindowPixelSize)+TVcentreZ;
00350   }
00351   else if(W == TRIRIGHT){
00352     *x=NpointerX;
00353     *y=(long)((double)(WindowCentreX[2]-hpos)*WindowPixelSize)+TVcentreY;
00354     *z=(long)((double)(WindowCentreY[2]-vpos)*WindowPixelSize)+TVcentreZ;
00355   }
00356 }
00357 
00358 void GetWindowCoords1(int W, long x, long y, long z,
00359                      int *hpos, int *vpos){
00360  double wdx,wdy;
00361   if(W == TRITOP){
00362    *hpos=(int)((double)WindowCentreX[0]-(double)(x-TVcentreX)/WindowPixelSize+ATOL);
00363    *vpos=(int)((double)WindowCentreY[0]+(double)(y-TVcentreY)/WindowPixelSize+ATOL);
00364   }
00365   else if(W == TRIFRONT){
00366    *hpos=(int)((double)WindowCentreX[1]-(double)(x-TVcentreX)/WindowPixelSize+ATOL);
00367    *vpos=(int)((double)WindowCentreY[1]-(double)(z-TVcentreZ)/WindowPixelSize+ATOL);
00368   }
00369   else if(W == TRIRIGHT){
00370    *hpos=(int)((double)WindowCentreX[2]-(double)(y-TVcentreY)/WindowPixelSize+ATOL);
00371    *vpos=(int)((double)WindowCentreY[2]-(double)(z-TVcentreZ)/WindowPixelSize+ATOL);
00372   }
00373 }
00374 
00375 void SetUpWindowBoxView(int view){
00376  if(view == 0){
00377    GetWorldCoords  = GetWorldCoords0;
00378    GetWindowCoords = GetWindowCoords0;
00379    WindowBox_view=0;
00380  }
00381  else if(view == 1){
00382    WindowBox_view=1;
00383    GetWorldCoords  = GetWorldCoords1;
00384    GetWindowCoords = GetWindowCoords1;
00385  }
00386 }
00387 
00388 void GetTriview(BOOL reset){
00389  double scale;
00390  if(reset){
00391    TVsizeX=TVsizeY=TVsizeZ=UNIT2;
00392    TVcentreX=TVcentreY=TVcentreZ=0;
00393  }
00394  if(View == TRIVIEW){
00395    scale=(double)WindowSizeX[1]/(double)WindowSizeY[1];
00396    TVsizeX=(long)((double)TVsizeZ*scale);
00397    scale=(double)WindowSizeX[2]/(double)WindowSizeY[1];
00398    TVsizeY=(long)((double)TVsizeZ*scale);
00399    scale=(double)WindowSizeY[0]/(double)WindowSizeX[1];
00400    TVsizeY=max(TVsizeY,(long)((double)TVsizeX*scale));
00401  }
00402  else{
00403    scale=(double)WindowSizeX[ActiveView]/(double)WindowSizeY[ActiveView];
00404    if     (ActiveView == TRITOP){
00405      TVsizeX=(long)((double)TVsizeZ*scale);
00406    }
00407    else if(ActiveView == TRIFRONT){
00408      TVsizeY=TVsizeX=(long)((double)TVsizeZ*scale);
00409    }
00410    else if(ActiveView == TRIRIGHT){
00411      TVsizeY=TVsizeX=(long)((double)TVsizeZ*scale);
00412    }
00413  }
00414  TVpointX=(TVcentreX-TVsizeX/2);
00415  TVpointY=(TVcentreY-TVsizeY/2);
00416  TVpointZ=(TVcentreZ-TVsizeZ/2);
00417  WindowPixelSize=(double)TVsizeZ/(double)WindowSizeY[1];
00418 }
00419 
00420 void reset_mod_maxview(short option){
00421  point TVC,TVP;
00422  if(Nvert == 0 && Nnurbs == 0)return;
00423  get_centre(option,TVC,TVP,TRUE);           /* redraw full zoom */
00424  TVsizeX=2*(TVC[0]-TVP[0]);  NpointerX=TVcentreX=TVC[0];
00425  TVsizeY=2*(TVC[1]-TVP[1]);  NpointerY=TVcentreY=TVC[1];
00426  TVsizeZ=2*(TVC[2]-TVP[2]);  NpointerZ=TVcentreZ=TVC[2];
00427  TVsizeX += TVsizeX/5;
00428  TVsizeY += TVsizeY/5;
00429  TVsizeZ += TVsizeZ/5;
00430  GetTriview(FALSE);  /* this will adjust the TV size */
00431 }
00432 
00433 void get_centre(short option, point p, point TVp, BOOL all){
00434  vertex *vp;
00435  double x,y,z,an;
00436  short flag;
00437  long i,n,xmin,xmax,ymin,ymax,zmin,zmax,d;
00438  flag=0;
00439  if     (option == 0){x=0; y=0; z=0; n=0;}
00440  else if(option >= 1){xmin=ymin=zmin=MAXUNIT; xmax=ymax=zmax = -MAXUNIT;}
00441  vp=MainVp; if(MainVp != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
00442    if(vp->status == SELECTED || all == TRUE){
00443      flag=1;
00444      if(option == 0){ /* centroid */
00445        n++; an=(double)(n-1)/(double)n;
00446        x=x*an+(double)(vp->xyz[0])/(double)n;
00447        y=y*an+(double)(vp->xyz[1])/(double)n;
00448        z=z*an+(double)(vp->xyz[2])/(double)n;
00449      }
00450      else if(option >= 1){ /* average */
00451       if(vp->xyz[0] < xmin)xmin=vp->xyz[0];
00452       if(vp->xyz[1] < ymin)ymin=vp->xyz[1];
00453       if(vp->xyz[2] < zmin)zmin=vp->xyz[2];
00454       if(vp->xyz[0] > xmax)xmax=vp->xyz[0];
00455       if(vp->xyz[1] > ymax)ymax=vp->xyz[1];
00456       if(vp->xyz[2] > zmax)zmax=vp->xyz[2];
00457      }
00458    }
00459    vp++;
00460  }
00461  if(option >= 1)IncludeNurbsBoundary(&flag,&xmin,&xmax,&ymin,&ymax,&zmin,&zmax);
00462  if(flag == 0){ /* no points found to average */
00463    p[0]=NpointerX; p[1]=NpointerY; p[2]=NpointerZ;
00464    TVp[0]=TVpointX; TVp[1]=TVpointY; TVp[2]=TVpointZ;
00465    return;
00466  }
00467  else if(option == 0){ /* centroid */
00468    p[0]=(long)x; p[1]=(long)y; p[2]=(long)z;
00469  }
00470  else if(option == 1){  /* midpoint */
00471   p[0]=(xmax+xmin)/2; p[1]=(ymax+ymin)/2; p[2]=(zmax+zmin)/2;
00472  }
00473  else if(option == 2){ /* horizontal xy plane */
00474   p[0]=(xmax+xmin)/2; p[1]=(ymax+ymin)/2; p[2]=NpointerZ;
00475  }
00476  else if(option == 3){ /* vertical F/B */
00477   p[0]=NpointerX; p[1]=(ymax+ymin)/2; p[2]=(zmax+zmin)/2;
00478  }
00479  else if(option == 4){ /* vertical L/R */
00480   p[0]=(xmax+xmin)/2; p[1]=NpointerY; p[2]=(zmax+zmin)/2;
00481  }
00482  d=max(labs(xmax-xmin),labs(ymax-ymin)); d=max(d,labs(zmax-zmin));
00483  d=max(d,MINUNIT); d=min(d,MAXUNIT); d /= 2;
00484  TVp[0]=p[0]-d; TVp[1]=p[1]-d; TVp[2]=p[2]-d;
00485 }
00486 
00487 void Draw3dCursor(void){
00488  int i;
00489  HDC hdc;
00490  int ifd,ild;
00491  if(View == TRIVIEW){ifd=0;ild=3;}
00492  else               {ifd=ActiveView; ild=ifd+1;}
00493  for(i=ifd;i<ild;i++){
00494    hdc=GetDC(ghwnd_triview[i]);
00495    SelectPalette(hdc,ghpaletteScreen,FALSE);
00496    RealizePalette (hdc);
00497    DrawOne3dCursor(hdc,i);
00498    ReleaseDC(ghwnd_triview[i],hdc);
00499  }
00500 }
00501 
00502 void DrawOne3dCursor(HDC hdc, int i){
00503  int sho,svo,oldROP;
00504  HPEN holdpen;
00505  GetWindowCoords(i,NpointerX,NpointerY,NpointerZ,&sho,&svo);
00506  oldROP=SetROP2(hdc,R2_XORPEN);
00507  holdpen=SelectObject(hdc,ghCursorPen);
00508  if(CursorToggle == 0){
00509    MoveToEx(hdc,sho-10,svo,NULL); LineTo(hdc,sho-3,svo);
00510    MoveToEx(hdc,sho+3,svo,NULL);  LineTo(hdc,sho+10,svo);
00511    MoveToEx(hdc,sho,svo-10,NULL); LineTo(hdc,sho,svo-3);
00512    MoveToEx(hdc,sho,svo+3,NULL);  LineTo(hdc,sho,svo+10);
00513  }
00514  else{
00515    MoveToEx(hdc,0,svo,NULL); LineTo(hdc,WindowSizeX[i],svo);
00516    MoveToEx(hdc,sho,0,NULL); LineTo(hdc,sho,WindowSizeY[i]);
00517  }
00518  SelectObject(hdc,holdpen);
00519  SetROP2(hdc,oldROP);
00520 }
00521 
00522 void Move3dCursor(int stor, int xw, int yw){
00523  int i;
00524  HDC hdc;
00525  HWND hwnd;
00526  static int xws=0,yws=0;
00527  long x,y,z,g2;
00528  int ifd,ild,dx,dy,dxa,dya;
00529  if((GetKeyState(VK_SHIFT) & 0x8000) && (tool == PLOTTER || tool == PLOT3D)){
00530    if(LastToolVertex >= 0){
00531      x=(MainVp+LastToolVertex)->xyz[0];
00532      y=(MainVp+LastToolVertex)->xyz[1];
00533      z=(MainVp+LastToolVertex)->xyz[2];
00534      GetWindowCoords(ActiveView,x,y,z,&xws,&yws);
00535    }
00536    else{
00537      GetWindowCoords(ActiveView,NpointerX,NpointerY,NpointerZ,&xws,&yws);
00538    }
00539    dx=xw-xws; dy=yw-yws;  dxa=abs(dx); dya=abs(dy);
00540    if(dya == 0)dya=1;
00541    if(dxa == 0)dxa=1;
00542    if     (dya < dxa/2)yw=yws;
00543    else if(dxa < dya/2)xw=xws;
00544    else if(dya < dxa)yw=yws+(int)((double)dxa*(double)dy/(double)dya);
00545    else if(dxa < dya)xw=xws+(int)((double)dya*(double)dx/(double)dxa);
00546  }
00547  else if(stor){
00548    xws=xw; yws=yw;
00549  }
00550  else if((GetKeyState(VK_SHIFT) & 0x8000) &&
00551          (tool == GRABBER || tool == NODETOOL)){
00552    dx=xw-xws; dy=yw-yws;  dxa=abs(dx); dya=abs(dy);
00553    if(dya == 0)dya=1;
00554    if(dxa == 0)dxa=1;
00555    if     (dya < dxa/2)yw=yws;
00556    else if(dxa < dya/2)xw=xws;
00557    else if(dya < dxa)yw=yws+(int)((double)dxa*(double)dy/(double)dya);
00558    else if(dxa < dya)xw=xws+(int)((double)dya*(double)dx/(double)dxa);
00559  }
00560  if(View == TRIVIEW){ifd=0;ild=3;}
00561  else               {ifd=ActiveView; ild=ifd+1;}
00562  for(i=ifd;i<ild;i++){
00563    hwnd=ghwnd_triview[i];
00564    hdc=GetDC(hwnd);
00565    SelectPalette(hdc,ghpaletteScreen,FALSE);
00566    RealizePalette (hdc);
00567    DrawOne3dCursor(hdc,i);
00568    ReleaseDC(hwnd,hdc);
00569  }
00570  GetWorldCoords(ActiveView,&x,&y,&z,xw,yw);
00571  if(grid_on){
00572 //   g2=grid_size/2;
00573 //   x = lrulerx+((x+(x >= 0  ? g2 : -g2)-lrulerx)/grid_size)*grid_size;
00574 //   y = lrulery+((y+(y >= 0  ? g2 : -g2)-lrulery)/grid_size)*grid_size;
00575 //   z = lrulerz+((z+(z >= 0  ? g2 : -g2)-lrulerz)/grid_size)*grid_size;
00576    g2=local_grid_size/2;
00577    x = lrulerx+((x+(x >= 0  ? g2 : -g2)-lrulerx)/local_grid_size)*local_grid_size;
00578    y = lrulery+((y+(y >= 0  ? g2 : -g2)-lrulery)/local_grid_size)*local_grid_size;
00579    z = lrulerz+((z+(z >= 0  ? g2 : -g2)-lrulerz)/local_grid_size)*local_grid_size;
00580  }
00581  NpointerX=x; NpointerY=y; NpointerZ=z;
00582  for(i=ifd;i<ild;i++){
00583    hwnd=ghwnd_triview[i];
00584    hdc=GetDC(hwnd);
00585    SelectPalette(hdc,ghpaletteScreen,FALSE);
00586    RealizePalette (hdc);
00587    DrawOne3dCursor(hdc,i);
00588    ReleaseDC(hwnd,hdc);
00589  }
00590  if(coords_visible)UpdateRuler(0);
00591 }
00592 
00593 #define ARROW_ICON_SIZE 12
00594 #define WINDOW_ID_XSIZE 48
00595 #define WINDOW_ID_YSIZE 20
00596 
00597 static HBITMAP hbmArrow[6]={NULL,NULL,NULL,NULL,NULL,NULL},
00598                 hbmName[5]={NULL,NULL,NULL,NULL,NULL};
00599 static int ArrowOK,ArrowID[6]={IDBM_ARROW_Zp,IDBM_ARROW_Zm,
00600                                IDBM_ARROW_Xp,IDBM_ARROW_Xm,
00601                                IDBM_ARROW_Yp,IDBM_ARROW_Ym};
00602 
00603 void LoadArrowIcons(void){
00604  int i;
00605  ArrowOK=1;
00606  for(i=0;i<6;i++){
00607    if((hbmArrow[i]=LoadBitmap(ghinst_main,
00608       MAKEINTRESOURCE(ArrowID[i]))) == NULL)ArrowOK=0;
00609  }
00610  if(!Preferences.buttons){
00611    if((hbmName[0]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_WIN_Th))) == NULL)ArrowOK=0;
00612    if((hbmName[1]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_WIN_Rh))) == NULL)ArrowOK=0;
00613    if((hbmName[2]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_WIN_Sh))) == NULL)ArrowOK=0;
00614    if((hbmName[4]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_WIN_Fh))) == NULL)ArrowOK=0;
00615  }
00616  else{
00617    if((hbmName[0]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_WIN_T))) == NULL)ArrowOK=0;
00618    if((hbmName[1]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_WIN_R))) == NULL)ArrowOK=0;
00619    if((hbmName[2]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_WIN_S))) == NULL)ArrowOK=0;
00620    if((hbmName[4]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(IDBM_WIN_F))) == NULL)ArrowOK=0;
00621  }
00622 }
00623 
00624 void DrawArrowIcons(HDC hDC, int id){
00625  int i,ic,x,y;
00626  HDC hMemDC;
00627  HBITMAP hbmOld;
00628  HBRUSH holdBrush;
00629  static int arrow_table[2][3][4]={
00630   {{3,2,4,5} ,     /* top   */
00631    {3,2,0,1} ,     /* rear  */
00632    {5,4,0,1} } ,   /* right */
00633   {{2,3,5,4} ,
00634    {2,3,0,1} ,
00635    {4,5,0,1} }
00636  };
00637  if(!ArrowOK)return;
00638  hMemDC = CreateCompatibleDC(hDC);
00639  for(i=0;i<4;i++){
00640    ic=arrow_table[WindowBox_view][id][i];
00641    if(i == 0)hbmOld = SelectObject(hMemDC,hbmArrow[ic]);
00642    else      SelectObject(hMemDC,hbmArrow[ic]);
00643    if     (i == 0){x=0; y=WindowSizeY[id]/2-ARROW_ICON_SIZE/2;}
00644    else if(i == 1){x=WindowSizeX[id]-ARROW_ICON_SIZE-1;
00645                    y=WindowSizeY[id]/2-ARROW_ICON_SIZE/2;}
00646    else if(i == 2){x=WindowSizeX[id]/2-ARROW_ICON_SIZE/2; y=0;}
00647    else if(i == 3){x=WindowSizeX[id]/2-ARROW_ICON_SIZE/2;
00648                    y=WindowSizeY[id]-ARROW_ICON_SIZE-1;}
00649    BitBlt(hDC,x,y,ARROW_ICON_SIZE,ARROW_ICON_SIZE,hMemDC,0,0,SRCPAINT);
00650  }
00651  SelectObject(hMemDC,hbmName[id]);
00652  x=y=0;
00653  if(!Preferences.buttons)
00654       BitBlt(hDC,x,y,WINDOW_ID_XSIZE,WINDOW_ID_YSIZE,hMemDC,0,0,SRCPAINT);
00655  else BitBlt(hDC,x,y,WINDOW_ID_XSIZE,WINDOW_ID_YSIZE,hMemDC,0,0,SRCCOPY);
00656  if(View == ONEVIEW){
00657    x=WindowSizeX[id]-2*WINDOW_ID_XSIZE-1;
00658    y=0;
00659    holdBrush=SelectObject(hDC,GetStockObject(LTGRAY_BRUSH));
00660    for(i=0;i<3;i++)if(i != id){
00661      SelectObject(hMemDC,hbmName[i]);
00662      if(!Preferences.buttons){
00663        BitBlt(hDC,x,y,WINDOW_ID_XSIZE,WINDOW_ID_YSIZE,hMemDC,0,0,0x00220326); /*  DSna */
00664        BitBlt(hDC,x,y,WINDOW_ID_XSIZE,WINDOW_ID_YSIZE,hMemDC,0,0,0x00ea02e9); /* DPSao */
00665      }
00666      else BitBlt(hDC,x,y,WINDOW_ID_XSIZE,WINDOW_ID_YSIZE,hMemDC,0,0,SRCCOPY);
00667      x+=WINDOW_ID_XSIZE;
00668    }
00669    SelectObject(hDC,holdBrush);
00670  }
00671  SelectObject(hMemDC, hbmOld);
00672  DeleteDC(hMemDC);
00673 }
00674 
00675 int CheckWindowIcon(int xi, int yi){
00676 #if 0
00677  int i,x,y;
00678  if(xi > WindowSizeX[ActiveView]-WINDOW_ID_XSIZE &&
00679     xi < WindowSizeX[ActiveView] &&
00680     yi > WindowSizeY[ActiveView]-WINDOW_ID_YSIZE &&
00681     yi < WindowSizeY[ActiveView])return 4;
00682  if(View == ONEVIEW){
00683    if(xi > 1 && xi < WINDOW_ID_XSIZE &&
00684       yi > WindowSizeY[ActiveView]-WINDOW_ID_YSIZE &&
00685       yi < WindowSizeY[ActiveView])return 5;
00686    if(xi > 1+WINDOW_ID_XSIZE && xi < 2*WINDOW_ID_XSIZE &&
00687       yi > WindowSizeY[ActiveView]-WINDOW_ID_YSIZE &&
00688       yi < WindowSizeY[ActiveView])return 6;
00689  }
00690 #endif
00691  if(xi >=0 &&
00692     xi < WINDOW_ID_XSIZE &&
00693     yi >=0 &&
00694     yi < WINDOW_ID_YSIZE)return 4;
00695  if(View == ONEVIEW){
00696    if(xi > WindowSizeX[ActiveView]-2*WINDOW_ID_XSIZE &&
00697       xi < WindowSizeX[ActiveView]-WINDOW_ID_XSIZE &&
00698       yi > 0 &&
00699       yi < WINDOW_ID_YSIZE)return 5;
00700    if(xi > WindowSizeX[ActiveView]-WINDOW_ID_XSIZE &&
00701       xi < WindowSizeX[ActiveView] &&
00702       yi > 0 &&
00703       yi < WINDOW_ID_YSIZE)return 6;
00704  }
00705  return -1;
00706 }
00707 
00708 void InvertWindowIcon(int i, HWND hwnd){
00709  HDC hdc;
00710  RECT rc;
00711  if     (i == 0){rc.left=0;
00712                  rc.top=WindowSizeY[ActiveView]/2-ARROW_ICON_SIZE/2;}
00713  else if(i == 1){rc.left=WindowSizeX[ActiveView]-ARROW_ICON_SIZE-1;
00714                  rc.top=WindowSizeY[ActiveView]/2-ARROW_ICON_SIZE/2;}
00715  else if(i == 2){rc.left=WindowSizeX[ActiveView]/2-ARROW_ICON_SIZE/2;
00716                  rc.top=0;}
00717  else if(i == 3){rc.left=WindowSizeX[ActiveView]/2-ARROW_ICON_SIZE/2;
00718                  rc.top=WindowSizeY[ActiveView]-ARROW_ICON_SIZE-1;}
00719  if(i > 3){
00720 #if 0
00721    rc.top = WindowSizeY[ActiveView]-WINDOW_ID_YSIZE;
00722    if     (i == 4)rc.left=WindowSizeX[ActiveView]-WINDOW_ID_XSIZE;
00723    else if(i == 5)rc.left=1;
00724    else if(i == 6)rc.left=1+WINDOW_ID_XSIZE;
00725 #endif
00726    rc.top = 0;
00727    if     (i == 4)rc.left=0;
00728    else if(i == 5)rc.left=WindowSizeX[ActiveView]-2*WINDOW_ID_XSIZE;
00729    else if(i == 6)rc.left=WindowSizeX[ActiveView]-WINDOW_ID_XSIZE;
00730    rc.right=rc.left+WINDOW_ID_XSIZE;
00731    rc.bottom=rc.top+WINDOW_ID_YSIZE;
00732  }
00733  else{  /* other corner for arrows */
00734    rc.right=rc.left+ARROW_ICON_SIZE;
00735    rc.bottom=rc.top+ARROW_ICON_SIZE;
00736  }
00737  hdc=GetDC(hwnd);
00738  InvertRect(hdc,&rc);
00739  ReleaseDC(hwnd,hdc);
00740  return;
00741 }
00742 
00743 void DeleteArrowIcons(void){
00744  int i;
00745  for(i=0;i<6;i++){
00746    if(hbmArrow != NULL)DeleteObject(hbmArrow[i]);
00747    hbmArrow[i]=NULL;
00748  }
00749  if(hbmName[0] != NULL)DeleteObject(hbmName[0]); hbmName[0]=NULL;
00750  if(hbmName[1] != NULL)DeleteObject(hbmName[1]); hbmName[1]=NULL;
00751  if(hbmName[2] != NULL)DeleteObject(hbmName[2]); hbmName[2]=NULL;
00752  if(hbmName[4] != NULL)DeleteObject(hbmName[4]); hbmName[4]=NULL;
00753 }
00754 
00755 void SwapViewBitmaps(void){
00756  HBITMAP hbmTemp;
00757  hbmTemp=hbmName[1];
00758  hbmName[1]=hbmName[4];
00759  hbmName[4]=hbmTemp;
00760 }
00761 
00762 static BOOL CALLBACK CoordinateDlgProc(HWND hwnd, UINT msg,
00763                                     WPARAM wparam, LPARAM lparam){
00764  char tempstr[16];
00765  struct np {char *name; double cal;} *dp;
00766  switch( msg ) {
00767    case WM_PAINT:
00768      PaintDialogBackground(hwnd,ghinst_main);
00769      break;
00770    case WM_INITDIALOG:{
00771        RECT rcDlg;
00772        POINT p;
00773        dp=(struct np *)lparam;
00774        SendDlgItemMessage(hwnd,DLG_COORD_NAME,WM_SETTEXT,0,(LPARAM)dp->name);
00775        SendDlgItemMessage(hwnd,DLG_COORD_NAME,EM_LIMITTEXT,(WPARAM)6,0);
00776        sprintf(tempstr,"%.4lf",dp->cal);
00777        SendDlgItemMessage(hwnd,DLG_COORD_CAL,WM_SETTEXT,0,(LPARAM)tempstr);
00778        SendDlgItemMessage(hwnd,DLG_COORD_CAL,EM_LIMITTEXT,(WPARAM)12,0);
00779        SetWindowLong(hwnd,GWL_USERDATA,lparam);
00780        GetCursorPos(&p);
00781        GetWindowRect(hwnd,&rcDlg);
00782        OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
00783        OffsetRect(&rcDlg,p.x-rcDlg.right/2,p.y-rcDlg.bottom/2);
00784        if(rcDlg.left < 0)OffsetRect(&rcDlg,-rcDlg.left,0);
00785        if(rcDlg.top  < 0)OffsetRect(&rcDlg,0,-rcDlg.top);
00786        if(rcDlg.right  > Xres)OffsetRect(&rcDlg,Xres-rcDlg.right,0);
00787        if(rcDlg.bottom > Yres)OffsetRect(&rcDlg,Yres-rcDlg.bottom,0);
00788        SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
00789      }
00790      return (TRUE);
00791    case WM_COMMAND:
00792       switch(LOWORD(wparam)){
00793         case IDCANCEL:
00794         case DLG_COORD_CANCEL:
00795           EndDialog(hwnd, FAIL);
00796           return(TRUE);
00797         case IDOK:
00798         case DLG_COORD_OK:
00799           dp=(struct np *)GetWindowLong(hwnd,GWL_USERDATA);
00800           if(GetDlgItemText(hwnd,DLG_COORD_NAME,dp->name,7) == 0)EndDialog(hwnd, FAIL);
00801           if(GetDlgItemText(hwnd,DLG_COORD_CAL,tempstr,10) == 0)EndDialog(hwnd, FAIL);
00802           if((dp->cal=atof(tempstr)) == 0)EndDialog(hwnd, FAIL);
00803           EndDialog(hwnd,OK);
00804           return(TRUE);
00805         default:
00806           break;
00807       }
00808       break;
00809     default: break;
00810  }
00811  return(FALSE);
00812 }
00813 
00814 void UpdateRuler(short m){
00815  double dx,dy,dz;
00816  char tempstr[32];
00817  if(m == 1){ /* cancel */
00818    rulerx=NpointerX; rulery=NpointerY; rulerz=NpointerZ;
00819  }
00820  if(m == 2){ /* set origin*/
00821    if(SendPrgmQuery(IDQ_SET_COORD_ORIGIN,1) != IDYES)return;
00822    EDIT_ACTION=YES;
00823    lrulerx=NpointerX; lrulery=NpointerY; lrulerz=NpointerZ;
00824    DrawModel();
00825  }
00826  if(m == 3){ /* set ruler */
00827    char name[10];
00828    struct np {char *name; double cal;} d;
00829    dx = (double)(NpointerX-lrulerx);
00830    dy = (double)(NpointerY-lrulery);
00831    dz = (double)(NpointerZ-lrulerz);
00832    if(dx < (double)MINUNIT || dy < (double)MINUNIT || dz < (double)MINUNIT){
00833      double dd;
00834      EDIT_ACTION=YES;
00835      if(ruler_name[0] == 0)strcpy(name,"<cms>");
00836      else                  strcpy(name,ruler_name);
00837      dd=sqrt(dx*dx+dy*dy+dz*dz);
00838      d.name=name; d.cal=dd/ruler;
00839      EnableToolPannels(ALL_PANNELS,FALSE);
00840      if(DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_COORD),ghwnd_main,
00841                 (DLGPROC)CoordinateDlgProc,(LPARAM)&d) == OK){
00842        strcpy(ruler_name,d.name);
00843        LoadString(ghinst_main,IDX_MISC_COORDS,tempstr,32);
00844        strcat(tempstr,ruler_name);
00845        SendMessage(ghwndCoord1,WM_SETTEXT,0,(LPARAM)tempstr);
00846        ruler = dd;
00847        if(d.cal > 0.0)ruler /= d.cal;
00848    }
00849    EnableToolPannels(ALL_PANNELS,TRUE);
00850    }
00851    else SendPrgmQuery(IDQ_COORD_BAD_RANGE,0);
00852  }
00853  SendMessage(ghwndCoord1,WM_COMMAND,IDC_COORD_UPDATE,0);
00854 }
00855 
00856 static BOOL CALLBACK GridSizeDlgProc(HWND hwnd, UINT msg,
00857                                      WPARAM wparam, LPARAM lparam){
00858  double d;
00859  char size[16];
00860  switch( msg ) {
00861    case WM_PAINT:
00862      PaintDialogBackground(hwnd,ghinst_main);
00863      break;
00864    case WM_INITDIALOG:{
00865        RECT rcDlg;
00866        POINT p;
00867        SetWindowLong(hwnd,GWL_USERDATA,lparam);
00868        GetCursorPos(&p);
00869        GetWindowRect(hwnd,&rcDlg);
00870        OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
00871        OffsetRect(&rcDlg,p.x-rcDlg.right/2,p.y-rcDlg.bottom/2);
00872        if(rcDlg.left < 0)OffsetRect(&rcDlg,-rcDlg.left,0);
00873        if(rcDlg.top  < 0)OffsetRect(&rcDlg,0,-rcDlg.top);
00874        if(rcDlg.right  > Xres)OffsetRect(&rcDlg,Xres-rcDlg.right,0);
00875        if(rcDlg.bottom > Yres)OffsetRect(&rcDlg,Yres-rcDlg.bottom,0);
00876        SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
00877        if(draw_grid_on)SendDlgItemMessage(hwnd,DLG_GRIDSIZE_ON ,BM_SETCHECK,1,0);
00878        else            SendDlgItemMessage(hwnd,DLG_GRIDSIZE_OFF,BM_SETCHECK,1,0);
00879        sprintf(size,"%.4lf",((double)grid_size)/ruler);
00880        SendDlgItemMessage(hwnd,DLG_GRIDSIZE_EDIT,WM_SETTEXT,0,
00881                           (LPARAM)(LPSTR)size);
00882        SendDlgItemMessage(hwnd,DLG_GRIDSIZE_EDIT,EM_LIMITTEXT,12,0);
00883      }
00884      return (TRUE);  /* must be used unless SetFocus */
00885    case WM_COMMAND:
00886       switch(LOWORD(wparam)){
00887         case IDCANCEL:
00888         case DLG_GRIDSIZE_CANCEL:
00889           EndDialog(hwnd, FAIL);
00890           return(TRUE);
00891         case IDOK:
00892         case DLG_GRIDSIZE_OK:
00893           if(SendDlgItemMessage(hwnd,DLG_GRIDSIZE_ON,BM_GETCHECK,0,0))
00894                draw_grid_on=1;
00895           else draw_grid_on=0;
00896           if(GetDlgItemText(hwnd,DLG_GRIDSIZE_EDIT,size,12)){
00897             if((d=atof(size)) > 0.0)grid_size=(long)(d*ruler);
00898           }
00899           EndDialog(hwnd,OK);
00900           return(TRUE);
00901         default:
00902           break;
00903       }
00904       break;
00905     default: break;
00906  }
00907  return(FALSE);
00908 }
00909 
00910 void SetUpGrid(void){
00911  EnableToolPannels(ALL_PANNELS,FALSE);
00912  DialogBox(ghinst_main,MAKEINTRESOURCE(DLG_GRIDSIZE),ghwnd_main,
00913             (DLGPROC)GridSizeDlgProc);
00914  EnableToolPannels(ALL_PANNELS,TRUE);
00915  return;
00916 }
00917 
00918 void DrawGridInOne(HDC hdc, int i){
00919  COLORREF OldColour;
00920  HPEN hPen1,hPen2,hPen3,hOldPen,hTempPen;
00921  BOOL flagx[50],flagy[50];
00922  int ng,ngx,ngy,ngz,ng1,ng2,j,k,xx[50],yy[50],d;
00923  long x,y,z,x1,y1,z1,g2,nx,ny,nz,iter;
00924  local_grid_size=grid_size/10;
00925  iter=0;
00926  TRYAGAIN:
00927  if(local_grid_size == 0)return;
00928  g2=local_grid_size/2;
00929  x=TVpointX; y=TVpointY; z=TVpointZ;
00930  x1 = lrulerx+((x+(x >= 0  ? g2 : -g2)-lrulerx)/local_grid_size)*local_grid_size;
00931  y1 = lrulery+((y+(y >= 0  ? g2 : -g2)-lrulery)/local_grid_size)*local_grid_size;
00932  z1 = lrulerz+((z+(z >= 0  ? g2 : -g2)-lrulerz)/local_grid_size)*local_grid_size;
00933  if(x1 <= TVpointX)x1 += local_grid_size;
00934  if(y1 <= TVpointY)y1 += local_grid_size;
00935  if(z1 <= TVpointZ)z1 += local_grid_size;
00936  ngx=(TVsizeX/local_grid_size);
00937  ngy=(TVsizeY/local_grid_size);
00938  ngz=(TVsizeZ/local_grid_size);
00939  ng = max(ngx,ngy);   ng=max(ngz,ng); ng++;
00940  if(ng == 0)return;
00941  if(ng > 30){
00942    local_grid_size *= 10;
00943    if(iter++ > 100)return;
00944    goto TRYAGAIN;
00945  }
00946  ng1 = ng2 = -1; x=x1; y=y1; z=z1;
00947  for(j=0;j<ng;j++){
00948    nx = labs(x-lrulerx)/local_grid_size;
00949    ny = labs(y-lrulery)/local_grid_size;
00950    nz = labs(z-lrulerz)/local_grid_size;
00951    flagx[j]=flagy[j]=FALSE;
00952    if(i == TRIRIGHT){
00953      nx=ny;
00954      ny=nz;
00955    }
00956    else if(i == TRIFRONT){
00957      ny=nz;
00958    }
00959    if(nx%10 == 0)flagx[j]=TRUE;
00960    if(ny%10 == 0)flagy[j]=TRUE;
00961    GetWindowCoords(i,x,y,z,&xx[j],&yy[j]);
00962    x += local_grid_size; y += local_grid_size; z += local_grid_size;
00963    if(WindowBox_view == 0){
00964      if(xx[j] >= WindowSizeX[i] && ng1 < 0)ng1=j;
00965      if(yy[j] <= 0              && ng2 < 0)ng2=j;
00966    }
00967    else{
00968      if(xx[j] <= 0 && ng1 < 0)ng1=j;
00969      if(i==TRITOP){if(yy[j] >= WindowSizeY[i] && ng2 < 0)ng2=j;}
00970      else         {if(yy[j] <= 0              && ng2 < 0)ng2=j;}
00971    }
00972  }
00973  if(ng1 < 0)ng1=ng; if(ng2 < 0)ng2=ng;
00974 // if(iter == 0)hPen1=CreatePen(PS_DOT,0,RGB(118,118,118));
00975 // else         hPen1=CreatePen(PS_SOLID,0,RGB(118,118,118));
00976 // hPen2=CreatePen(PS_SOLID,0,RGB(151,151,151));
00977 // hPen3=CreatePen(PS_SOLID,0,RGB(  0,  0,255));
00978  if(iter == 0)hPen1=CreatePen(PS_DOT,0,gGridColourRef1);
00979  else         hPen1=CreatePen(PS_SOLID,0,gGridColourRef1);
00980  hPen2=CreatePen(PS_SOLID,0,gGridColourRef2);
00981  hPen3=CreatePen(PS_SOLID,0,RGB(255,255,255));
00982  OldColour=SetBkColor(hdc,gScreenColourRef);
00983  hOldPen=SelectObject(hdc,hPen1);
00984  x= -1; y = -1;
00985  if(lrulerx > TVpointX || lrulerx < TVpointX+TVsizeX ||
00986     lrulery > TVpointY || lrulery < TVpointY+TVsizeY ||
00987     lrulerz > TVpointZ || lrulerz < TVpointZ+TVsizeZ){
00988    GetWindowCoords(i,lrulerx,lrulery,lrulerz,(int *)(&x),(int *)&y);
00989  }
00990  if(ng1 > 0 && ng2 > 0){
00991    for(j=0;j<ng2;j++){
00992      if(yy[j] == y)continue;
00993      if(flagy[j])hTempPen=SelectObject(hdc,hPen2);
00994      MoveToEx(hdc,0,yy[j],NULL); LineTo(hdc,WindowSizeX[i]+1,yy[j]);
00995      if(flagy[j])SelectObject(hdc,hTempPen);
00996    }
00997    for(k=0;k<ng1;k++){
00998      if(xx[k] == x)continue;
00999      if(flagx[k])hTempPen=SelectObject(hdc,hPen2);
01000      MoveToEx(hdc,xx[k],0,NULL); LineTo(hdc,xx[k],WindowSizeY[i]+1);
01001      if(flagx[k])SelectObject(hdc,hTempPen);
01002    }
01003  }
01004  SetBkColor(hdc,OldColour);
01005  SelectObject(hdc,hPen3);
01006  if(y >= 0 && y <= WindowSizeY[i]){
01007    MoveToEx(hdc,0,y,NULL); LineTo(hdc,WindowSizeX[i]+1,y);
01008  }
01009  if(x >= 0 && x <= WindowSizeX[i]){
01010    MoveToEx(hdc,x,0,NULL); LineTo(hdc,x,WindowSizeY[i]+1);
01011  }
01012  SelectObject(hdc,hOldPen);
01013  DeleteObject(hPen1);
01014  DeleteObject(hPen2);
01015  DeleteObject(hPen3);
01016  return;
01017 }
01018 
01019 static char *ColorSelectDlgString;
01020 
01021 static BOOL CALLBACK ColorSelectDlgProc(HWND hwnd, UINT msg, WPARAM wparam,
01022                                         LPARAM lparam){
01023  switch( msg ) {
01024    case WM_INITDIALOG:
01025      SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)ColorSelectDlgString);
01026      return TRUE;
01027    default:
01028      break;
01029  }
01030  return FALSE;
01031 }
01032 
01033 BOOL SetColour(unsigned char colour[], char *Title, HWND parent){
01034  BOOL result=FALSE;
01035  CHOOSECOLOR cc;
01036  static COLORREF CustColours[16]={
01037    RGB(255,255,255), RGB(239,239,239), RGB(223,223,223), RGB(207,207,207),
01038    RGB(191,191,191), RGB(175,175,175), RGB(159,159,159), RGB(143,143,143),
01039    RGB(127,127,127), RGB(111,111,111), RGB( 95, 95, 95), RGB( 79, 79, 79),
01040    RGB( 63, 63, 63), RGB( 47, 47, 47), RGB( 31, 31, 31), RGB( 15, 15, 15) };
01041  cc.lStructSize=sizeof(CHOOSECOLOR);
01042  cc.hwndOwner=parent;
01043  cc.rgbResult=RGB(colour[0],colour[1],colour[2]);
01044  cc.lpCustColors=(LPDWORD)CustColours;
01045  cc.Flags=CC_FULLOPEN | CC_RGBINIT | CC_ENABLEHOOK;
01046  cc.lCustData=(DWORD)0;
01047  ColorSelectDlgString=Title;
01048  cc.lpfnHook=(LPCCHOOKPROC)ColorSelectDlgProc;
01049  if((result=ChooseColor(&cc))){
01050    colour[0]=GetRValue(cc.rgbResult);
01051    colour[1]=GetGValue(cc.rgbResult);
01052    colour[2]=GetBValue(cc.rgbResult);
01053  }
01054  return result;
01055 }
01056 
01057 BOOL SetSfxColour(unsigned char colour[], long ID, HWND parent){
01058  char szTitle[256];
01059  LoadString(ghinst_main,ID,szTitle,255);
01060  return SetColour(colour,szTitle,parent);
01061 }
01062 
01063 void scal(double t[4][4], double sx, double sy, double sz){
01064  long i,j;
01065  for(i=0;i<4;i++) for(j=0;j<4;j++) t[i][j]=0.0;
01066  t[0][0]=sx; t[1][1]=sy; t[2][2]=sz; t[3][3]=1;
01067  return;
01068 }
01069 
01070 void rotz(double tr[4][4], double ang){
01071  short i,j;
01072  for(i=0;i<4;i++)
01073  for(j=0;j<4;j++)
01074  {
01075   tr[i][j]=0.0;
01076   if(i == j)tr[i][j]=1.0;
01077  }
01078   tr[0][0]= cos(ang);
01079   tr[0][1]=-sin(ang);
01080   tr[1][0]= sin(ang);
01081   tr[1][1]= cos(ang);
01082   return;
01083 }
01084 
01085 void roty(double tr[4][4], double ang){
01086  short i,j;
01087  for(i=0;i<4;i++)
01088  for(j=0;j<4;j++)
01089  {
01090   tr[i][j]=0.0;
01091   if(i == j)tr[i][j]=1.0;
01092  }
01093   tr[0][0]= cos(ang);
01094   tr[0][2]=-sin(ang);
01095   tr[2][0]= sin(ang);
01096   tr[2][2]= cos(ang);
01097   return;
01098 }
01099 
01100 void rotx(double tr[4][4], double ang){
01101  long i,j;
01102  for(i=0;i<4;i++)
01103  for(j=0;j<4;j++)
01104  {
01105   tr[i][j]=0.0;
01106   if(i == j)tr[i][j]=1.0;
01107  }
01108   tr[1][1]= cos(ang);
01109   tr[1][2]=-sin(ang);
01110   tr[2][1]= sin(ang);
01111   tr[2][2]= cos(ang);
01112   return;
01113 }
01114 
01115 void tram(double t[4][4], double dx, double dy, double dz){
01116  short i,j;
01117  for(i=0;i<4;i++)
01118  for(j=0;j<4;j++)
01119  {
01120   t[i][j]=0.0;
01121   if(i == j)t[i][j]=1.0;
01122  }
01123  t[0][3]=dx;
01124  t[1][3]=dy;
01125  t[2][3]=dz;
01126  t[3][3]=1;
01127  return;
01128 }
01129 
01130 void mv4by1(double t4[4][4], vector v1, vector v2){
01131  double xx,yy,zz;
01132  xx=t4[0][0]*v1[0]+t4[0][1]*v1[1]+t4[0][2]*v1[2]+t4[0][3];
01133  yy=t4[1][0]*v1[0]+t4[1][1]*v1[1]+t4[1][2]*v1[2]+t4[1][3];
01134  zz=t4[2][0]*v1[0]+t4[2][1]*v1[1]+t4[2][2]*v1[2]+t4[2][3];
01135  v2[0]=xx; v2[1]=yy; v2[2]=zz;
01136  return;
01137 }
01138 
01139 void m4by4(double t1[4][4], double t2[4][4], double tr[4][4]){
01140  short n=4,i,j,k;
01141  for(i=0;i<4;i++)
01142  for(j=0;j<4;j++)
01143  {
01144   tr[i][j]=0.0;
01145   for(k=0;k<4;k++)tr[i][j]=tr[i][j]+t1[i][k]*t2[k][j];
01146  }
01147  return;
01148 }
01149 
01150 void m4by1(double t4[4][4], double x, double y, double z,
01151            double *xx, double *yy, double *zz){
01152  *xx=t4[0][0]*x+t4[0][1]*y+t4[0][2]*z+t4[0][3];
01153  *yy=t4[1][0]*x+t4[1][1]*y+t4[1][2]*z+t4[1][3];
01154  *zz=t4[2][0]*x+t4[2][1]*y+t4[2][2]*z+t4[2][3];
01155  return;
01156 }
01157 
01158 void c4to4(double tin[4][4], double tout[4][4]){
01159  short i,j;
01160  for(i=0;i<4;i++)
01161  for(j=0;j<4;j++)
01162  tout[i][j]=tin[i][j];
01163 }
01164 
01165 void null_transform(double t[4][4]){
01166  short i,j;
01167  for(i=0;i<4;i++)
01168  for(j=0;j<4;j++)
01169  if(i == j)t[i][j]=1.0;
01170  else      t[i][j]=0.0;
01171 }
01172 
01173 void arbitrary_rotate(double angle, point p1, point p2, double t[4][4]){
01174   double dx,dy,dz,phi,theta,dxy;
01175   double t1[4][4],t2[4][4],t3[4][4];
01176   angle *= PI/180.0;
01177   dx=p2[0]-p1[0]; dy=p2[1]-p1[1]; dz=p2[2]-p1[2];
01178   dxy=dx*dx+dy*dy;
01179   tram(t1, -p1[0], -p1[1], -p1[2]);
01180   if(dxy < 1.0){ /* vertical so just rotate about z  and return */
01181     if(dz > 0.0)rotz(t2, angle);
01182     else        rotz(t2,-angle);
01183     m4by4(t2,t1,t3);
01184     tram(t1,p1[0],p1[1],p1[2]);
01185     m4by4(t1,t3,t);
01186     return;
01187   }
01188   dxy=sqrt(dxy);
01189   if     (dx == 0.0 && dy > 0.0)phi =  PI2;
01190   else if(dx == 0.0 && dy < 0.0)phi = -PI2;
01191   else phi = atan2(dy,dx);
01192   theta = atan2(dz,dxy);
01193   rotz(t2, -phi);
01194   m4by4(t2,t1,t3);
01195   roty(t2, -theta);
01196   m4by4(t2,t3,t1);
01197   rotx(t2, angle);
01198   m4by4(t2,t1,t3);
01199   roty(t2,theta);
01200   m4by4(t2,t3,t1);
01201   rotz(t2,phi);
01202   m4by4(t2,t1,t3);
01203   tram(t1,p1[0],p1[1],p1[2]);
01204   m4by4(t1,t3,t);
01205 }
01206 
01207 void rotate_round_vector(double angle, vector v, double t[4][4]){
01208   double dx,dy,dz,phi,theta,dxy;
01209   double t1[4][4],t2[4][4],t3[4][4];
01210   angle *= PI/180.0;
01211   dx=v[0]; dy=v[1]; dz=v[2];
01212   dxy=dx*dx+dy*dy;
01213   if(dxy < 0.00001){ /* vertical so just rotate about z  and return */
01214     if(dz > 0.0)rotz(t, angle);
01215     else        rotz(t,-angle);
01216     return;
01217   }
01218   dxy=sqrt(dxy);
01219   if     (dx == 0.0 && dy > 0.0)phi =  PI2;
01220   else if(dx == 0.0 && dy < 0.0)phi = -PI2;
01221   else phi = atan2(dy,dx);
01222   theta = atan2(dz,dxy);
01223   rotz(t3, -phi);
01224   roty(t2, -theta);
01225   m4by4(t2,t3,t1);
01226   rotx(t2, angle);
01227   m4by4(t2,t1,t3);
01228   roty(t2,theta);
01229   m4by4(t2,t3,t1);
01230   rotz(t2,phi);
01231   m4by4(t2,t1,t);
01232 }
01233 
01234 void L_cross(point p1, point p2, point p3, point p4){
01235  double v1[3],v2[3],r[3];
01236  v1[0]=(double)(p2[0]-p1[0]);
01237  v1[1]=(double)(p2[1]-p1[1]);
01238  v1[2]=(double)(p2[2]-p1[2]);
01239  v2[0]=(double)(p3[0]-p1[0]);
01240  v2[1]=(double)(p3[1]-p1[1]);
01241  v2[2]=(double)(p3[2]-p1[2]);
01242  r[0] = (v1[1]*v2[2]) - (v2[1]*v1[2]);
01243  r[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]);
01244  r[2] = (v1[0]*v2[1]) - (v2[0]*v1[1]);
01245  p4[0] = p1[0] + (long)(r[0]/UNIT);
01246  p4[1] = p1[1] + (long)(r[1]/UNIT);
01247  p4[2] = p1[2] + (long)(r[2]/UNIT);
01248 }
01249 
01250 void CentreDialogOnCursor(HWND hwnd){
01251  RECT rcDlg;
01252  POINT p;
01253  GetCursorPos(&p);
01254  GetWindowRect(hwnd,&rcDlg);
01255  OffsetRect(&rcDlg,-rcDlg.left,-rcDlg.top);
01256  OffsetRect(&rcDlg,p.x-rcDlg.right/2,p.y-rcDlg.bottom/2);
01257  if(rcDlg.left < 0)OffsetRect(&rcDlg,-rcDlg.left,0);
01258  if(rcDlg.top  < 0)OffsetRect(&rcDlg,0,-rcDlg.top);
01259  if(rcDlg.right  > Xres)OffsetRect(&rcDlg,Xres-rcDlg.right,0);
01260  if(rcDlg.bottom > Yres)OffsetRect(&rcDlg,0,Yres-rcDlg.bottom);
01261  SetWindowPos(hwnd,HWND_TOP,rcDlg.left,rcDlg.top,0,0,SWP_NOSIZE);
01262  return;
01263 }
01264 
01265 void CentreDialogOnScreen(HWND hWnd){
01266  RECT rc;
01267  GetWindowRect(hWnd, &rc);
01268  SetWindowPos(hWnd, NULL,
01269     (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2,
01270     (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2,
01271     0, 0, SWP_NOSIZE | SWP_NOZORDER);
01272 }
01273 
01274 void PaintDialogBackground(HWND hDlg, HINSTANCE hInst){
01275  int x;
01276  int y;
01277  HDC hDC;
01278  HPALETTE hpalT;
01279  HBRUSH hOldBrush;
01280  RECT rc1,rc2;
01281  HDC hMemDC;
01282  HBITMAP hBmBackground,hbmOld;
01283  BITMAP  bm;
01284  PAINTSTRUCT ps;
01285  hDC = BeginPaint(hDlg,&ps);
01286  hBmBackground=LoadBitmap(hInst,MAKEINTRESOURCE(IDBM_BACKGROUND));
01287  if(hBmBackground != NULL){
01288    GetObject(hBmBackground,sizeof(BITMAP),&bm);
01289    hMemDC = CreateCompatibleDC(hDC);
01290    hbmOld = SelectObject(hMemDC,hBmBackground);
01291    GetClientRect(hDlg,&rc2);
01292    for(x=0;x<(rc2.right/bm.bmWidth)+1;x++)
01293    for(y=0;y<(rc2.bottom/bm.bmHeight)+1;y++)
01294      BitBlt(hDC,
01295           x*bm.bmWidth,y*bm.bmHeight,
01296           bm.bmWidth,
01297           bm.bmHeight,
01298           hMemDC,
01299           0,0,
01300           SRCCOPY);
01301    SelectObject(hMemDC,hbmOld);
01302    DeleteDC(hMemDC);
01303    DeleteObject(hBmBackground);
01304  }
01305  EndPaint(hDlg,&ps);
01306 }
01307 
01308 void AppendFileExtension(char *filename, char *ext){
01309  if(strrchr(filename,'.') == NULL){
01310    strcat(filename,ext);
01311  }
01312 }
01313 
01314 static short PanTo(long *, long *, long);
01315 
01316 static short PanTo(long *start, long *centre, long increment){
01317  long newpoint;
01318  newpoint = *start + increment;
01319  if(newpoint > MAXUNIT || newpoint < -MAXUNIT){
01320    SendPrgmQuery(IDQ_PANTOOFAR,0);
01321    return 0;
01322  }
01323  *start = newpoint;
01324  *centre = *centre + increment;
01325  return 1;
01326 }
01327 
01328 void Zoom2(double fraction){
01329  long what_shift,cx,cy,cz;
01330  double zf;
01331  short f;
01332  zf= (1.0+(double)fraction / 5.0);
01333  if(TVsizeX <= MINUNIT || TVsizeY <= MINUNIT || TVsizeZ <= MINUNIT){
01334     SendPrgmQuery(IDQ_NOZOOMIN,0);
01335     return;
01336  }
01337   if(TVsizeX >= MAXUNIT || TVsizeY >= MAXUNIT || TVsizeZ >= MAXUNIT){
01338     SendPrgmQuery(IDQ_NOZOOMOUT,0);
01339     return;
01340  }
01341  cx=TVpointX+TVsizeX/2; cy=TVpointY+TVsizeY/2; cz=TVpointZ+TVsizeZ/2;
01342  TVsizeX=(long)((double)TVsizeX/zf);
01343  TVsizeY=(long)((double)TVsizeY/zf);
01344  TVsizeZ=(long)((double)TVsizeZ/zf);
01345  WindowPixelSize=(double)TVsizeZ/(double)WindowSizeY[1];
01346  TVpointX=cx-TVsizeX/2;
01347  TVpointY=cy-TVsizeY/2;
01348  TVpointZ=cz-TVsizeZ/2;
01349  if(NpointerX < TVpointX)        NpointerX=TVpointX;
01350  if(NpointerX > TVpointX+TVsizeX)NpointerX=TVpointX+TVsizeX;
01351  if(NpointerY < TVpointY)        NpointerY=TVpointY;
01352  if(NpointerY > TVpointY+TVsizeY)NpointerY=TVpointY+TVsizeY;
01353  if(NpointerZ < TVpointZ)        NpointerZ=TVpointZ;
01354  if(NpointerZ > TVpointZ+TVsizeZ)NpointerZ=TVpointZ+TVsizeZ;
01355  DrawModel();
01356 }
01357 
01358 void Zoom(int command, int redraw){
01359  long what_shift,cx,cy,cz;
01360  double zf;
01361  short f;
01362  if(command == ZOOMIN || command == ZOOMOUT){
01363    zf=1.2;
01364    if(GetAsyncKeyState(VK_SHIFT  ) & 0x8000)zf=1.5;
01365    if(GetAsyncKeyState(VK_CONTROL) & 0x8000)zf=2.0;
01366    if(GetAsyncKeyState(VK_MENU   ) & 0x8000)zf=4.0;
01367  }
01368  else{
01369    what_shift=TVsizeX/16;
01370    if(GetAsyncKeyState(VK_SHIFT  ) & 0x8000)what_shift=TVsizeX/2;
01371    if(GetAsyncKeyState(VK_CONTROL) & 0x8000)what_shift=TVsizeX;
01372    if(GetAsyncKeyState(VK_MENU   ) & 0x8000)what_shift=TVsizeX*1.5;
01373  }
01374  if(command == ZOOMIN){
01375   if(TVsizeX <= MINUNIT || TVsizeY <= MINUNIT || TVsizeZ <= MINUNIT){
01376     SendPrgmQuery(IDQ_NOZOOMIN,0);
01377     goto EXIT;
01378   }
01379   cx=TVpointX+TVsizeX/2; cy=TVpointY+TVsizeY/2; cz=TVpointZ+TVsizeZ/2;
01380   TVsizeX=(long)((double)TVsizeX/zf);
01381   TVsizeY=(long)((double)TVsizeY/zf);
01382   TVsizeZ=(long)((double)TVsizeZ/zf);
01383   WindowPixelSize=(double)TVsizeZ/(double)WindowSizeY[1];
01384   TVpointX=cx-TVsizeX/2;
01385   TVpointY=cy-TVsizeY/2;
01386   TVpointZ=cz-TVsizeZ/2;
01387  }
01388  else if(command == ZOOMOUT){
01389   if(TVsizeX >= MAXUNIT || TVsizeY >= MAXUNIT || TVsizeZ >= MAXUNIT){
01390     SendPrgmQuery(IDQ_NOZOOMOUT,0);
01391     goto EXIT;
01392   }
01393   cx=TVpointX+TVsizeX/2; cy=TVpointY+TVsizeY/2; cz=TVpointZ+TVsizeZ/2;
01394   TVsizeX=(long)((double)TVsizeX*zf);
01395   TVsizeY=(long)((double)TVsizeY*zf);
01396   TVsizeZ=(long)((double)TVsizeZ*zf);
01397   WindowPixelSize=(double)TVsizeZ/(double)WindowSizeY[1];
01398   TVpointX=cx-TVsizeX/2;
01399   TVpointY=cy-TVsizeY/2;
01400   TVpointZ=cz-TVsizeZ/2;
01401  }
01402  else if(command == RECENTRE){
01403   if(TVsizeX >= MAXUNIT || TVsizeY >= MAXUNIT || TVsizeZ >= MAXUNIT){
01404     goto EXIT;
01405   }
01406   TVpointX=NpointerX-TVsizeX/2; TVcentreX=NpointerX;
01407   TVpointY=NpointerY-TVsizeY/2; TVcentreY=NpointerY;
01408   TVpointZ=NpointerZ-TVsizeZ/2; TVcentreZ=NpointerZ;
01409  }
01410  else if(command == CENTREWORLD){
01411    reset_mod_maxview(1);
01412  }
01413  else { /* pan commands */
01414    if(WindowBox_view == 1){
01415     if(command == PANFORWARD ||
01416        command == PANBACK    ||
01417        command == PANRIGHT   ||
01418        command == PANLEFT)what_shift *= -1.0;
01419    }
01420    if(command == PANFORWARD){if(!PanTo(&TVpointY,&TVcentreY,+what_shift))goto EXIT;} /* forward   */
01421    if(command == PANBACK   ){if(!PanTo(&TVpointY,&TVcentreY,-what_shift))goto EXIT;} /* backwards */
01422    if(command == PANRIGHT  ){if(!PanTo(&TVpointX,&TVcentreX,+what_shift))goto EXIT;} /* right     */
01423    if(command == PANLEFT   ){if(!PanTo(&TVpointX,&TVcentreX,-what_shift))goto EXIT;} /* left      */
01424    if(command == PANUP     ){if(!PanTo(&TVpointZ,&TVcentreZ,+what_shift))goto EXIT;} /* up        */
01425    if(command == PANDOWN   ){if(!PanTo(&TVpointZ,&TVcentreZ,-what_shift))goto EXIT;} /* down      */
01426  }
01427  if(NpointerX < TVpointX)        NpointerX=TVpointX;
01428  if(NpointerX > TVpointX+TVsizeX)NpointerX=TVpointX+TVsizeX;
01429  if(NpointerY < TVpointY)        NpointerY=TVpointY;
01430  if(NpointerY > TVpointY+TVsizeY)NpointerY=TVpointY+TVsizeY;
01431  if(NpointerZ < TVpointZ)        NpointerZ=TVpointZ;
01432  if(NpointerZ > TVpointZ+TVsizeZ)NpointerZ=TVpointZ+TVsizeZ;
01433  if(redraw)DrawModel();
01434  EXIT:;
01435 }

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