DRAW.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX - Modelling, Animation and Rendering Package
00003 -- */
00004 
00005 
00006 /* file draw.c  */
00007 
00008 // Drawing code
00009 
00010 
00011 #define MODULE_DRAW 1
00012 
00013 #include "design.h"
00014 
00015 static short in_modeller_view2(vertex *, vertex *);
00016 static short in_modeller_view1(vertex *, vertex *);
00017 static void DrawAllEdgesInOne(HDC,int);
00018 static void DrawAllVerticesInOne(HDC, int);
00019 static void DrawOneVertexInOne(vertex *, HDC, int);
00020 static void DrawWireFrame(HDC hdc,int skelview);
00021 static void DrawQuickWireFrame(HDC hdc,int skelview);
00022 static void DrawHiddenLine(HDC hdc);
00023 
00024 static double trr[4][4], t1[4][4],
00025               t2[4][4],  t3[4][4],
00026               rrt[4][4];  // inverse of rotation - for moving at right angles to current view
00027 static double scale,rad;
00028 static vertex vobserver;
00029 static int zoom_abort=NO,abort_enable=YES;
00030 static int order_list[3][3]={ {0,1,2},{1,2,0},{2,0,1} };
00031 
00032 int CheckInterrupt(void){
00033  int i;
00034  MSG msg;
00035  if(do_NOT_abort)return 0;
00036  if(PeekMessage(&msg,NULL,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE)){
00037    if(msg.message == WM_LBUTTONDOWN){
00038      if(GetKeyState(VK_SPACE) & 0x8000 || tool == PAN ||
00039         tool == INZOOM){
00040        for(i=0;i<3;i++)if(msg.hwnd == ghwnd_triview[i]){
00041          if(msg.hwnd != ghwnd_current){
00042            HDC hdc;
00043            hdc=GetDC(ghwnd_main);
00044            FocusActiveWindow(hdc,FALSE);
00045            ghwnd_current=msg.hwnd;
00046            ActiveView=GetWindowLong(msg.hwnd,GWL_ID);
00047            FocusActiveWindow(hdc,TRUE);
00048            ReleaseDC(ghwnd_main,hdc);
00049          }
00050        }
00051        PostMessage(msg.hwnd,msg.message,msg.wParam,msg.lParam);
00052        zoom_abort=0;
00053        return 1;
00054      }
00055    }
00056    else if(msg.message == WM_LBUTTONUP){
00057      for(i=0;i<3;i++){
00058        if(msg.hwnd == ghwnd_triview[i]){
00059          if(msg.hwnd != ghwnd_current){
00060            HDC hdc;
00061            hdc=GetDC(ghwnd_main);
00062            FocusActiveWindow(hdc,FALSE);
00063            ghwnd_current=msg.hwnd;
00064            ActiveView=GetWindowLong(msg.hwnd,GWL_ID);
00065            FocusActiveWindow(hdc,TRUE);
00066            ReleaseDC(ghwnd_main,hdc);
00067          }
00068          ScreenToClient(ghwnd_triview[i],&msg.pt);
00069          if((zoom_abort=CheckWindowIcon((int)msg.pt.x,(int)msg.pt.y)+1) > 0)
00070            return 1;
00071        }
00072      }
00073    }
00074  }
00075  return 0;
00076 }
00077 
00078 void SelectInPerspective(int tl,int boxl,int box,int boyl,int boy){
00079  vertex *vp;
00080  double x1,y1,z1;
00081  int i,ix1,iy1,pwincx,pwincy;
00082  RECT rc;
00083  GetClientRect(ghwnd_view,&rc);
00084  pwincx=rc.right/2; pwincy=rc.bottom/2;
00085  vp=MainVp; if(MainVp != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
00086    if(intriview(vp)){
00087      m4by1(trr,(double)vp->xyz[0],(double)vp->xyz[1],(double)vp->xyz[2]
00088           ,&x1,&y1,&z1);
00089      if(y1 >= 0.0){
00090        ix1=(int)((double)pwincx+scale*x1);
00091        iy1=(int)((double)pwincy-scale*z1);
00092        if(ix1 > min(box,boxl) && ix1 < max(box,boxl) &&
00093           iy1 > min(boy,boyl) && iy1 < max(boy,boyl)){
00094          if(tl == SELECTOR && vp->status == DESELECTED){
00095            vp->status=SELECTED;
00096            NvertSelect++; NvertDeselect--;
00097          }
00098          else if(tl == DESELECTOR && vp->status == SELECTED){
00099            vp->status=DESELECTED;
00100            NvertSelect--; NvertDeselect++;
00101          }
00102        }
00103      }
00104     }
00105    vp++;
00106  }
00107 }
00108 
00109 void MoveInPerspective(int dx, int dy){
00110  vertex *vp;
00111  double x1,y1,z1;
00112  int i;
00113  m4by1(rrt,(double)dx/scale,0.0,-(double)dy/scale,&x1,&y1,&z1);
00114  vp=MainVp; if(MainVp != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
00115    if(vp->status == SELECTED){
00116      vp->xyz[0] += (long)x1;
00117      vp->xyz[1] += (long)y1;
00118      vp->xyz[2] += (long)z1;
00119    }
00120    vp++;
00121  }
00122 }
00123 
00124 void UpdateCounters(void){
00125   char temp[64];
00126   sprintf(temp,"Vertices=%ld(%ld) Faces=%ld",NvertSelect,Nvert,Nface);
00127   SendMessage(ghwnd_info,SB_SETTEXT,(WPARAM)1,(LPARAM)temp);
00128   if(data_visible && ghwndData != NULL)InvalidateRect(ghwndData,NULL,FALSE);
00129   if(ghwndDlgAttribs != NULL && IsWindow(ghwndDlgAttribs))
00130     SendMessage(ghwndDlgAttribs,WM_COMMAND,DLG_ATTRIBS_UPDATE,0);
00131 }
00132 
00133 void DrawVerticesOnly(vertex *vs){
00134  int i,j,n,k;
00135  RECT rc;
00136  HCURSOR lhcurSave;
00137  if(View == TRIVIEW)n=3;
00138  else               n=1;
00139  if(vs == NULL)lhcurSave=SetCursor(ghcurWait);
00140  k=ActiveView;
00141  for(j=0;j<n;j++){
00142    i=order_list[k][j];
00143    if(ghdc_triview_Bitmap[i] == NULL)return;
00144    if(ghbm_triview[i] == NULL)return;
00145    if(vs == NULL)DrawAllVerticesInOne(ghdc_triview_Bitmap[i],i);
00146    else          DrawOneVertexInOne(vs,ghdc_triview_Bitmap[i],i);
00147    DrawArrowIcons(ghdc_triview_Bitmap[i],i);
00148    InvalidateRect(ghwnd_triview[i],NULL,FALSE);
00149    UpdateWindow(ghwnd_triview[i]);
00150  }
00151  if(vs == NULL)SetCursor(lhcurSave);
00152 }
00153 
00154 void DrawOneEdgeOnly(vertex *v1, vertex *v2){
00155  int i,j,k,n;
00156  RECT rc;
00157  int sh1,sv1,sh2,sv2;
00158  short (*in_modeller_view)(vertex *vp1, vertex *vp2);
00159  HDC hdc;
00160  HPEN holdpen;
00161  if(View == TRIVIEW)n=3;
00162  else               n=1;
00163  k=ActiveView;
00164  if(!draw_joins)in_modeller_view = in_modeller_view2; /* scroll lock   */
00165  else           in_modeller_view = in_modeller_view1; /* test function */
00166  for(j=0;j<n;j++){
00167    i=order_list[k][j];
00168    if((hdc=ghdc_triview_Bitmap[i]) == NULL)return;
00169    if(ghbm_triview[i] == NULL)return;
00170    if(in_modeller_view(v1,v2)){
00171      GetWindowCoords(i,v1->xyz[0],v1->xyz[1],v1->xyz[2],&sh1,&sv1);
00172      GetWindowCoords(i,v2->xyz[0],v2->xyz[1],v2->xyz[2],&sh2,&sv2);
00173      holdpen=SelectObject(hdc,ghEdgePen);
00174      MoveToEx(hdc,sh1,sv1,NULL); LineTo(hdc,sh2,sv2);
00175      if(v1->status == SELECTED)SelectObject(hdc,ghSelectedPen);
00176      else                      SelectObject(hdc,ghDeselectedPen);
00177      MoveToEx(hdc,sh1,sv1,NULL); LineTo(hdc,sh1+1,sv1);
00178      if(v2->status == SELECTED)SelectObject(hdc,ghSelectedPen);
00179      else                      SelectObject(hdc,ghDeselectedPen);
00180      MoveToEx(hdc,sh2,sv2,NULL); LineTo(hdc,sh2+1,sv2);
00181      SelectObject(hdc,holdpen);
00182    }
00183    DrawArrowIcons(ghdc_triview_Bitmap[i],i);
00184    InvalidateRect(ghwnd_triview[i],NULL,FALSE);
00185    UpdateWindow(ghwnd_triview[i]);
00186  }
00187 }
00188 
00189 void DrawModel(void){
00190  int i,j,n,k;
00191  RECT rc;
00192  HCURSOR lhcurSave;
00193  if(View == TRIVIEW)n=3;
00194  else               n=1;
00195  if(sktool == NO || tool != SKANIMATE)lhcurSave=SetCursor(ghcurWait);
00196  k=ActiveView;
00197  for(j=0;j<n;j++){
00198    i=order_list[k][j];
00199    if(ghdc_triview_Bitmap[i] == NULL)return;
00200    if(ghbm_triview[i] == NULL)return;
00201    GetClientRect(ghwnd_triview[i],&rc);
00202    PatBlt(ghdc_triview_Bitmap[i],0,0,rc.right,rc.bottom,PATCOPY);
00203    if(sktool == YES && tool == SKANIMATE){
00204      DrawTrSkeletonInOne(ghdc_triview_Bitmap[i],i);
00205    }
00206    else {
00207      if(/* grid_on && */draw_grid_on)DrawGridInOne(ghdc_triview_Bitmap[i],i);
00208      SelectObject(ghdc_triview_Bitmap[i],ghEdgePen);
00209      if(!global_quickdraw){
00210        DrawAllEdgesInOne(ghdc_triview_Bitmap[i],i);
00211        DrawArrowIcons(ghdc_triview_Bitmap[i],i);
00212        InvalidateRect(ghwnd_triview[i],NULL,FALSE);
00213        UpdateWindow(ghwnd_triview[i]);
00214        if(zoom_abort)break;
00215      }
00216      DrawAllVerticesInOne(ghdc_triview_Bitmap[i],i);
00217      DrawAllNurbsInOne(ghdc_triview_Bitmap[i],i,FALSE);
00218    }
00219    DrawArrowIcons(ghdc_triview_Bitmap[i],i);
00220    // inserted to draw brush in background windows
00221    if(SelectedBrush >= 0)DrawBrushInOne(ghdc_triview_Bitmap[i],i,SelectedBrush);
00222    //
00223    InvalidateRect(ghwnd_triview[i],NULL,FALSE);
00224    UpdateWindow(ghwnd_triview[i]);
00225    if(zoom_abort)break;
00226  }
00227  if(sktool == NO || tool != SKANIMATE)SetCursor(lhcurSave);
00228  if(zoom_abort > 0){
00229    if     (zoom_abort ==  1)zoom_abort=IDM_PAN_LEFT;
00230    else if(zoom_abort ==  2)zoom_abort=IDM_PAN_RIGHT;
00231    else if(zoom_abort ==  3)zoom_abort=IDM_PAN_UP;
00232    else if(zoom_abort ==  4)zoom_abort=IDM_PAN_DOWN;
00233    else if(zoom_abort ==  5)zoom_abort=IDM_WINDOW_SWITCHWINDOWS;
00234    else if(zoom_abort ==  6)zoom_abort=IDM_WINDOW_SWITCHWINDOW0;
00235    else if(zoom_abort ==  7)zoom_abort=IDM_WINDOW_SWITCHWINDOW1;
00236    else if(zoom_abort ==  8)zoom_abort=IDM_ZOOM_IN;
00237    else if(zoom_abort ==  9)zoom_abort=IDM_ZOOM_OUT;
00238    else if(zoom_abort == 10)zoom_abort=IDM_ACTIONS_ROTATE_ANTICLOCKWISE;
00239    else if(zoom_abort == 11)zoom_abort=IDM_ACTIONS_ROTATE_CLOCKWISE;
00240    PostMessage(ghwnd_main,WM_COMMAND,(WPARAM)zoom_abort,(LPARAM)ActiveView);
00241    zoom_abort=NO;
00242  }
00243  return;
00244 }
00245 
00246 static void DrawAllVerticesInOne(HDC hdc, int view){
00247  int i,sho,svo;
00248  vertex *vp;
00249  HPEN holdpen;
00250  holdpen=SelectObject(hdc,ghDeselectedPen);
00251  if(intriview(&ObjectAxis.Offset)){
00252    GetWindowCoords(view,ObjectAxis.Offset.xyz[0],
00253       ObjectAxis.Offset.xyz[1],ObjectAxis.Offset.xyz[2],&sho,&svo);
00254    MoveToEx(hdc,sho-3,svo,NULL); LineTo(hdc,sho+4,svo);
00255    MoveToEx(hdc,sho,svo-3,NULL); LineTo(hdc,sho,svo+4);
00256  }
00257  SelectObject(hdc,ghSelectedPen);
00258  if(intriview(&ObjectAxis.Origin)){
00259    GetWindowCoords(view,ObjectAxis.Origin.xyz[0],
00260       ObjectAxis.Origin.xyz[1],ObjectAxis.Origin.xyz[2],&sho,&svo);
00261    MoveToEx(hdc,sho-5,svo,NULL); LineTo(hdc,sho+6,svo);
00262    MoveToEx(hdc,sho,svo-5,NULL); LineTo(hdc,sho,svo+6);
00263  }
00264  if(Preferences.bigv){
00265    SelectObject(hdc,ghDeselectedPen);
00266    vp=MainVp; if(MainVp != NULL && NvertDeselect > 0)for(i=0;i<Nvert;i++){
00267     if(vp->status == DESELECTED)if(intriview(vp)){
00268       GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sho,&svo);
00269 //      MoveToEx(hdc,sho-1,svo-1,NULL); LineTo(hdc,sho+2,svo-1);
00270       MoveToEx(hdc,sho-1,svo,NULL); LineTo(hdc,sho+2,svo);
00271       MoveToEx(hdc,sho,svo-1,NULL); LineTo(hdc,sho,svo+2);
00272 //      MoveToEx(hdc,sho-1,svo+1,NULL); LineTo(hdc,sho+2,svo+1);
00273       if(HIWORD(GetQueueStatus(QS_MOUSEBUTTON)) == QS_MOUSEBUTTON
00274          &&  CheckInterrupt())goto ABORT;
00275     }
00276     vp++;
00277    }
00278    SelectObject(hdc,ghSelectedPen);
00279    vp=MainVp; if(MainVp != NULL && NvertSelect > 0)for(i=0;i<Nvert;i++){
00280     if(vp->status == SELECTED)if(intriview(vp)){
00281       GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sho,&svo);
00282 //      MoveToEx(hdc,sho-1,svo-1,NULL); LineTo(hdc,sho+2,svo-1);
00283       MoveToEx(hdc,sho-1,svo,NULL); LineTo(hdc,sho+2,svo);
00284       MoveToEx(hdc,sho,svo-1,NULL); LineTo(hdc,sho,svo+2);
00285 //      MoveToEx(hdc,sho-1,svo+1,NULL); LineTo(hdc,sho+2,svo+1);
00286       if(HIWORD(GetQueueStatus(QS_MOUSEBUTTON)) == QS_MOUSEBUTTON
00287          &&  CheckInterrupt())goto ABORT;
00288     }
00289     vp++;
00290    }
00291  }
00292  else{
00293    SelectObject(hdc,ghDeselectedPen);
00294    vp=MainVp; if(MainVp != NULL && NvertDeselect > 0)for(i=0;i<Nvert;i++){
00295     if(vp->status == DESELECTED)if(intriview(vp)){
00296       GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sho,&svo);
00297       MoveToEx(hdc,sho,svo,NULL); LineTo(hdc,sho+1,svo);
00298       if(HIWORD(GetQueueStatus(QS_MOUSEBUTTON)) == QS_MOUSEBUTTON
00299          &&  CheckInterrupt())goto ABORT;
00300     }
00301     vp++;
00302    }
00303    SelectObject(hdc,ghSelectedPen);
00304    vp=MainVp; if(MainVp != NULL && NvertSelect > 0)for(i=0;i<Nvert;i++){
00305     if(vp->status == SELECTED)if(intriview(vp)){
00306       GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sho,&svo);
00307       MoveToEx(hdc,sho,svo,NULL); LineTo(hdc,sho+1,svo);
00308       if(HIWORD(GetQueueStatus(QS_MOUSEBUTTON)) == QS_MOUSEBUTTON
00309          &&  CheckInterrupt())goto ABORT;
00310     }
00311     vp++;
00312    }
00313  }
00314  ABORT:
00315  SelectObject(hdc,holdpen);
00316  return;
00317 }
00318 
00319 static void DrawOneVertexInOne(vertex *Vp, HDC hdc, int view){
00320  int sho,svo;
00321  HPEN holdpen;
00322  if(intriview(Vp)){
00323    if(Vp->status == DESELECTED){
00324      holdpen=SelectObject(hdc,ghDeselectedPen);
00325    }
00326    else{
00327      holdpen=SelectObject(hdc,ghSelectedPen);
00328    }
00329    GetWindowCoords(view,Vp->xyz[0],Vp->xyz[1],Vp->xyz[2],&sho,&svo);
00330    if(Preferences.bigv){
00331 //     MoveToEx(hdc,sho-1,svo-1,NULL); LineTo(hdc,sho+2,svo-1);
00332      MoveToEx(hdc,sho-1,svo,NULL); LineTo(hdc,sho+2,svo);
00333      MoveToEx(hdc,sho,svo-1,NULL); LineTo(hdc,sho,svo+2);
00334 //     MoveToEx(hdc,sho-1,svo+1,NULL); LineTo(hdc,sho+2,svo+1);
00335    }
00336    else MoveToEx(hdc,sho,svo,NULL); LineTo(hdc,sho+1,svo);
00337  }
00338  return;
00339 }
00340 
00341 static short in_modeller_view1(vertex *vp1, vertex *vp2){
00342  if(vp1->status == HIDDEN && vp2->status == HIDDEN)return 0;
00343  if( ((vp1->xyz[0] > TVpointX) && (vp1->xyz[0] < TVpointX+TVsizeX))
00344   && ((vp1->xyz[1] > TVpointY) && (vp1->xyz[1] < TVpointY+TVsizeY))
00345   && ((vp1->xyz[2] > TVpointZ) && (vp1->xyz[2] < TVpointZ+TVsizeZ))
00346    )return 1;
00347  if( ((vp2->xyz[0] > TVpointX) && (vp2->xyz[0] < TVpointX+TVsizeX))
00348   && ((vp2->xyz[1] > TVpointY) && (vp2->xyz[1] < TVpointY+TVsizeY))
00349   && ((vp2->xyz[2] > TVpointZ) && (vp2->xyz[2] < TVpointZ+TVsizeZ))
00350    )return 1;
00351  return 0;
00352 }
00353 
00354 static short in_modeller_view2(vertex *vp1, vertex *vp2){
00355  if(vp1->status == HIDDEN || vp2->status == HIDDEN)return 0;
00356  if( ((vp1->xyz[0] > TVpointX) && (vp1->xyz[0] < TVpointX+TVsizeX))
00357   && ((vp1->xyz[1] > TVpointY) && (vp1->xyz[1] < TVpointY+TVsizeY))
00358   && ((vp1->xyz[2] > TVpointZ) && (vp1->xyz[2] < TVpointZ+TVsizeZ))
00359    )return 1;
00360  if( ((vp2->xyz[0] > TVpointX) && (vp2->xyz[0] < TVpointX+TVsizeX))
00361   && ((vp2->xyz[1] > TVpointY) && (vp2->xyz[1] < TVpointY+TVsizeY))
00362   && ((vp2->xyz[2] > TVpointZ) && (vp2->xyz[2] < TVpointZ+TVsizeZ))
00363    )return 1;
00364  return 0;
00365 }
00366 
00367 static void DrawAllEdgesInOne(HDC hdc, int view){
00368  int i,sh1,sv1,sh2,sv2;
00369  edge   *ep;
00370  vertex *v1,*v2;
00371  short (*in_modeller_view)(vertex *vp1, vertex *vp2);
00372  LPPOINT lppt;
00373  LPBYTE  lpbTypes;
00374  int     cCount;
00375  long    pcount;
00376  if(Nedge == 0)return;
00377 #ifdef _LINE_DRAW
00378  if((lppt=(LPPOINT)LocalAlloc(LMEM_FIXED,2*Nedge*sizeof(POINT))) == NULL)return;
00379  if((lpbTypes=(LPBYTE)LocalAlloc(LMEM_FIXED,2*Nedge*sizeof(BYTE))) == NULL){
00380   LocalFree((HLOCAL)lppt);
00381   return;
00382  }
00383  cCount=0; pcount=0;
00384 #endif
00385  if(!draw_joins)in_modeller_view = in_modeller_view2; /* scroll lock   */
00386  else           in_modeller_view = in_modeller_view1; /* test function */
00387  ep=MainEp;
00388  for(i=0;i<Nedge;i++){
00389   v1=(MainVp+ep->V[0]);
00390   v2=(MainVp+ep->V[1]);
00391   if(in_modeller_view(v1,v2)){
00392     GetWindowCoords(view,v1->xyz[0],v1->xyz[1],v1->xyz[2],&sh1,&sv1);
00393     GetWindowCoords(view,v2->xyz[0],v2->xyz[1],v2->xyz[2],&sh2,&sv2);
00394     if((!Preferences.quick_trick || abs(sh1-sh2) > 3 || abs(sv1-sv2) > 3) ){
00395 #ifdef _LINE_DRAW
00396       lppt[cCount].x=sh1; lppt[cCount].y=sv1;
00397       lpbTypes[cCount]=PT_MOVETO; cCount++;
00398       lppt[cCount].x=sh2; lppt[cCount].y=sv2;
00399       lpbTypes[cCount]=PT_LINETO; cCount++;
00400 #else
00401       MoveToEx(hdc,sh1,sv1,NULL); LineTo(hdc,sh2,sv2);
00402 #endif
00403     }
00404     if(HIWORD(GetQueueStatus(QS_MOUSEBUTTON)) == QS_MOUSEBUTTON
00405        &&  CheckInterrupt())goto ABORT;
00406   }
00407   ep++;
00408  }
00409  ABORT:;
00410 #ifdef _LINE_DRAW
00411  if(cCount > 0 && PolyDraw(hdc,lppt,lpbTypes,cCount) == FALSE){
00412    char message[128];
00413    sprintf(message,"ERROR: pcount=%ld ccount=%ld",pcount,cCount);
00414    MessageBox (NULL,message, NULL,
00415    MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
00416  }
00417  LocalFree((HLOCAL)lppt);
00418  LocalFree((HLOCAL)lpbTypes);
00419 #endif
00420 }
00421 
00422 void Draw3dView(int smab,int skelview){
00423  RECT rc;
00424  HCURSOR lhcurSave;
00425  double xt,yt,zt,dr;
00426  double tt1[4][4],tt2[4][4],tt3[4][4];
00427  short i,j;
00428  for(i=0;i<4;i++) for(j=0;j<4;j++){
00429    trr[i][j]=0.0; if(i == j)trr[i][j]=1;
00430  }
00431  GetClientRect(ghwnd_view,&rc);
00432  scale=266.0*(double)rc.right/320.0/(double)TVsizeX;
00433  rad=(double)TVsizeX*10;
00434  dr=PI/180.0;
00435  xt=(double)(TVpointX+TVsizeX/2);
00436  yt=(double)(TVpointY+TVsizeY/2);
00437  zt=(double)(TVpointZ+TVsizeZ/2);
00438  tram(tt1,-xt,-yt,-zt);
00439  if(type_of_view){ // NOT USED
00440    rotz(tt2,-PerspFi*dr);  /* to rotate to the like a camera */
00441    m4by4(tt2,tt1,tt3);
00442    rotx(tt1,-PerspTheta*dr);
00443  }
00444  else{
00445    rotz(tt2,PerspFi*dr);
00446    m4by4(tt2,tt1,tt3);
00447    rotx(tt1,PerspTheta*dr);
00448  }
00449  // get the perspective view transform
00450  m4by4(tt1,tt3,tt2);
00451  tram(tt1,0.0,rad,0.0);
00452  m4by4(tt1,tt2,trr);
00453  // get the inverse transform for moving in the perspective view
00454  rotz(tt2,-PerspFi*dr);
00455  rotx(tt1,-PerspTheta*dr);
00456  m4by4(tt2,tt1,rrt);
00457  if(ghdc_view_Bitmap == NULL || ghbm_view == NULL)return;
00458  PatBlt(ghdc_view_Bitmap,0,0,rc.right,rc.bottom,PATCOPY);
00459  SelectObject(ghdc_view_Bitmap,ghWireframePen);
00460  SelectPalette(ghdc_view_Bitmap,ghpaletteScreen,FALSE);
00461  RealizePalette(ghdc_view_Bitmap);
00462  if(smab){
00463    lhcurSave=SetCursor(ghcurWait);
00464    DrawHiddenLine(ghdc_view_Bitmap);
00465    SetCursor(lhcurSave);
00466  }
00467  else{
00468    DrawWireFrame(ghdc_view_Bitmap,skelview);
00469    DrawNurbsWireFrame(ghdc_view_Bitmap,skelview,scale,trr,
00470                       in_modeller_view1,in_modeller_view2,FALSE);
00471  }
00472  InvalidateRect(ghwnd_view,NULL,FALSE);
00473  return;
00474 }
00475 
00476 static void DrawWireFrame(HDC hdc,int skelview){
00477  edge *ep;
00478  vertex *v1,*v2,*vop;
00479  double x1,y1,z1,x2,y2,z2;
00480  int i,ix1,ix2,iy1,iy2,flag,line_flag=0,
00481      pwinl,pwinr,pwint,pwinb,pwincx,pwincy;
00482  short (*in_modeller_view)(vertex *vp1, vertex *vp2);
00483  MSG msg;
00484  RECT rc;
00485  LPPOINT lppt;
00486  LPBYTE  lpbTypes;
00487  int     cCount;
00488  long    pcount;
00489  if(Nedge == 0)return;
00490 #ifdef _LINE_DRAW
00491  if(tool != SKANIMATE || skelview == 1)line_flag=1;
00492  if(line_flag){
00493    if((lppt=(LPPOINT)LocalAlloc(LMEM_FIXED,2*Nedge*sizeof(POINT))) == NULL)return;
00494    if((lpbTypes=(LPBYTE)LocalAlloc(LMEM_FIXED,2*Nedge*sizeof(BYTE))) == NULL){
00495      LocalFree((HLOCAL)lppt);
00496      return;
00497    }
00498  }
00499  cCount=0; pcount=0;
00500 #endif
00501  if(!draw_joins)in_modeller_view = in_modeller_view2; /* scroll lock   */
00502  else           in_modeller_view = in_modeller_view1; /* test function */
00503  GetClientRect(ghwnd_view,&rc);
00504  pwinl=pwint=0; pwinr=rc.right; pwinb=rc.bottom;
00505  pwincx=rc.right/2; pwincy=rc.bottom/2;
00506  if(tool != SKANIMATE){ /* draw wireframe as is */
00507    ep=MainEp; for(i=0;i<Nedge;i++){
00508     v1=(MainVp+ep->V[0]);
00509     v2=(MainVp+ep->V[1]);
00510     if(in_modeller_view(v1,v2)){
00511       flag=0;
00512       m4by1(trr,(double)v1->xyz[0],(double)v1->xyz[1],(double)v1->xyz[2]
00513                ,&x1,&y1,&z1);
00514       m4by1(trr,(double)v2->xyz[0],(double)v2->xyz[1],(double)v2->xyz[2]
00515                ,&x2,&y2,&z2);
00516       if(y1 >= 0.0){
00517         ix1=(int)(pwincx+scale*x1);
00518         iy1=(int)(pwincy-scale*z1);
00519       }
00520       else  flag=1;
00521       if(y2 >= 0.0){
00522         ix2=(int)(pwincx+scale*x2);
00523         iy2=(int)(pwincy-scale*z2);
00524       }
00525       else flag=1;
00526       if(flag == 0 && (!Preferences.quick_trick || abs(ix1-ix2) > 2 || abs(iy1-iy2) > 2) ){
00527 #ifdef _LINE_DRAW
00528         lppt[cCount].x=ix1; lppt[cCount].y=iy1;
00529         lpbTypes[cCount]=PT_MOVETO; cCount++;
00530         lppt[cCount].x=ix2; lppt[cCount].y=iy2;
00531         lpbTypes[cCount]=PT_LINETO; cCount++;
00532 #else
00533         MoveToEx(hdc,ix1,iy1,NULL);
00534         LineTo(hdc,ix2,iy2);
00535 #endif
00536       }
00537     }
00538     ep++;
00539    }
00540    vop=&vobserver;           /* draw the current cursor point in 3d */
00541    vop->status=SELECTED;
00542    vop->xyz[0]=NpointerX; vop->xyz[1]=NpointerY; vop->xyz[2]=NpointerZ;
00543    if(intriview(vop)){
00544 #if 0
00545      m4by1(trr,(double)vop->xyz[0],(double)vop->xyz[1],(double)vop->xyz[2]
00546               ,&x1,&y1,&z1);
00547      if(y1 >= 0.0){
00548        HPEN holdpen=SelectObject(hdc,ghEdgePen);
00549        ix1=(int)(pwincx+scale*x1);
00550        iy1=(int)(pwincy-scale*z1);
00551        MoveToEx(hdc,ix1-5,iy1,NULL); LineTo(hdc,ix1+5,iy1);
00552        MoveToEx(hdc,ix1,iy1-5,NULL); LineTo(hdc,ix1,iy1+5);
00553        SelectObject(hdc,holdpen);
00554      }
00555 #endif
00556      {long d,dx,dy,dz;
00557       HPEN holdpen=SelectObject(hdc,ghEdgePen);
00558       d=TVsizeX/30;
00559       for(i=0;i<3;i++){
00560         if     (i == 0){dx=d; dy=dz=0;}
00561         else if(i == 1){dy=d; dx=dz=0;}
00562         else           {dz=d; dx=dy=0;}
00563         m4by1(trr,(double)(vop->xyz[0]-dx),
00564                   (double)(vop->xyz[1]-dy),
00565                   (double)(vop->xyz[2]-dz),
00566                   &x1,&y1,&z1);
00567         m4by1(trr,(double)(vop->xyz[0]+dx),
00568                   (double)(vop->xyz[1]+dy),
00569                   (double)(vop->xyz[2]+dz),
00570                   &x2,&y2,&z2);
00571         if(y1 >= 0.0 || y2 >= 0){
00572           ix1=(int)(pwincx+scale*x1);
00573           iy1=(int)(pwincy-scale*z1);
00574           ix2=(int)(pwincx+scale*x2);
00575           iy2=(int)(pwincy-scale*z2);
00576           MoveToEx(hdc,ix1,iy1,NULL); LineTo(hdc,ix2,iy2);
00577         }
00578       }
00579       SelectObject(hdc,holdpen);
00580      }
00581    } /* end of cursor draw */
00582  }
00583  else{ /* draw using skeletal transformation */
00584    if(skelview == 0){
00585      static short ep1[12]={0,1,2,3,4,5,6,7,0,1,2,3};
00586      static short ep2[12]={1,2,3,0,5,6,7,4,4,5,6,7};
00587      int i;
00588      skel *sp;
00589      if((sp=MainSp) != NULL)while(sp != NULL){
00590        if(skintriview(sp->tp) || (sp->at != NULL && skintriview(sp->at->tp))){
00591          flag=0;
00592          m4by4(trr,sp->t,t1);
00593          for(i=0;i<12;i++){
00594            m4by1(t1 ,(double)sp->bx[ep1[i]][0]
00595                     ,(double)sp->bx[ep1[i]][1]
00596                     ,(double)sp->bx[ep1[i]][2]
00597                     ,&x1,&y1,&z1);
00598            m4by1(t1 ,(double)sp->bx[ep2[i]][0]
00599                     ,(double)sp->bx[ep2[i]][1]
00600                     ,(double)sp->bx[ep2[i]][2]
00601                     ,&x2,&y2,&z2);
00602            if(y1 >= 0.0){
00603              ix1=(int)(pwincx+scale*x1);
00604              iy1=(int)(pwincy-scale*z1);
00605            }
00606            else  flag=1;
00607            if(y2 > 0.0){
00608              ix2=(int)(pwincx+scale*x2);
00609              iy2=(int)(pwincy-scale*z2);
00610            }
00611            else flag=1;
00612            if(flag == 0){
00613              MoveToEx(hdc,ix1,iy1,NULL);
00614              LineTo(hdc,ix2,iy2);
00615            }
00616          }
00617        }
00618        sp=sp->last;
00619      }
00620    }
00621    else {
00622      ep=MainEp; for(i=0;i<Nedge;i++){
00623        v1=(MainVp+ep->V[0]);
00624        v2=(MainVp+ep->V[1]);
00625        if(in_modeller_view(v1,v2)){
00626          flag=0;
00627          if(v1->sp != NULL)m4by4(trr,v1->sp->t,t1);
00628          else              c4to4(trr,t1);
00629          m4by1(t1 ,(double)v1->xyz[0],(double)v1->xyz[1],(double)v1->xyz[2]
00630                   ,&x1,&y1,&z1);
00631          if(v2->sp != NULL)m4by4(trr,v2->sp->t,t1);
00632          else              c4to4(trr,t1);
00633           m4by1(t1 ,(double)v2->xyz[0],(double)v2->xyz[1],(double)v2->xyz[2]
00634                   ,&x2,&y2,&z2);
00635          if(y1 >= 0.0){
00636            ix1=(int)(pwincx+scale*x1);
00637            iy1=(int)(pwincy-scale*z1);
00638          }
00639          else  flag=1;
00640          if(y2 > 0.0){
00641            ix2=(int)(pwincx+scale*x2);
00642            iy2=(int)(pwincy-scale*z2);
00643          }
00644          else flag=1;
00645          if(flag == 0 && (!Preferences.quick_trick || abs(ix1-ix2) > 2 || abs(iy1-iy2) > 2) ){
00646 #ifdef _LINE_DRAW
00647            lppt[cCount].x=ix1; lppt[cCount].y=iy1;
00648            lpbTypes[cCount]=PT_MOVETO; cCount++;
00649            lppt[cCount].x=ix2; lppt[cCount].y=iy2;
00650            lpbTypes[cCount]=PT_LINETO; cCount++;
00651 #else
00652            MoveToEx(hdc,ix1,iy1,NULL);
00653            LineTo(hdc,ix2,iy2);
00654 #endif
00655          }
00656        }
00657        ep++;
00658      }
00659    }
00660  }
00661 #ifdef _LINE_DRAW
00662  if(line_flag){
00663    if(cCount > 0 && PolyDraw(hdc,lppt,lpbTypes,cCount) == FALSE){
00664      char message[128];
00665      sprintf(message,"ERROR: pcount=%ld ccount=%ld",pcount,cCount);
00666      MessageBox (NULL,message, NULL,
00667      MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
00668    }
00669    LocalFree((HLOCAL)lppt);
00670    LocalFree((HLOCAL)lpbTypes);
00671  }
00672 #endif
00673  return;
00674 }
00675 
00676 void DrawQuick3dView(int skelview){
00677  RECT rc;
00678  HCURSOR lhcurSave;
00679  HDC hdc;
00680  double xt,yt,zt,dr;
00681  double tt1[4][4],tt2[4][4],tt3[4][4];
00682  short i,j;
00683  for(i=0;i<4;i++) for(j=0;j<4;j++){
00684    trr[i][j]=0.0; if(i == j)trr[i][j]=1;
00685  }
00686  GetClientRect(ghwnd_view,&rc);
00687  scale=266.0*(double)rc.right/320.0/(double)TVsizeX;
00688  rad=(double)TVsizeX*10;
00689  dr=PI/180.0;
00690  xt=(double)(TVpointX+TVsizeX/2);
00691  yt=(double)(TVpointY+TVsizeY/2);
00692  zt=(double)(TVpointZ+TVsizeZ/2);
00693  tram(tt1,-xt,-yt,-zt);
00694  if(type_of_view){
00695    rotz(tt2,-PerspFi*dr);  /* to rotate to the like a camera */
00696    m4by4(tt2,tt1,tt3);
00697    rotx(tt1,-PerspTheta*dr);
00698  }
00699  else{
00700    rotz(tt2,PerspFi*dr);
00701    m4by4(tt2,tt1,tt3);
00702    rotx(tt1,PerspTheta*dr);
00703  }
00704  m4by4(tt1,tt3,tt2);
00705  tram(tt1,0.0,rad,0.0);
00706  m4by4(tt1,tt2,trr);
00707  hdc=GetDC(ghwnd_view);
00708  SelectPalette(hdc,ghpaletteScreen,FALSE);
00709  RealizePalette (hdc);
00710  SelectObject(hdc,ghbrushWindow);
00711  PatBlt(hdc,0,0,rc.right,rc.bottom,PATCOPY);
00712  SelectObject(hdc,ghWireframePen);
00713  DrawQuickWireFrame(hdc,skelview);
00714  DrawNurbsWireFrame(hdc,skelview,scale,trr,
00715                     in_modeller_view1,in_modeller_view2,TRUE);
00716  ReleaseDC(ghwnd_view,hdc);
00717  return;
00718 }
00719 
00720 static void DrawQuickWireFrame(HDC hdc,int skelview){
00721  edge *ep;
00722  vertex *v1,*v2,*vop;
00723  double x1,y1,z1,x2,y2,z2;
00724  int i,ix1,ix2,iy1,iy2,flag,line_flag=0,j,nstep,
00725      pwinl,pwinr,pwint,pwinb,pwincx,pwincy;
00726  short (*in_modeller_view)(vertex *vp1, vertex *vp2);
00727  MSG msg;
00728  RECT rc;
00729  LPPOINT lppt;
00730  LPBYTE  lpbTypes;
00731  int     cCount;
00732  long    pcount;
00733  if(Nedge == 0)return;
00734  if(!draw_joins)in_modeller_view = in_modeller_view2; /* scroll lock   */
00735  else           in_modeller_view = in_modeller_view1; /* test function */
00736  GetClientRect(ghwnd_view,&rc);
00737  pwinl=pwint=0; pwinr=rc.right; pwinb=rc.bottom;
00738  pwincx=rc.right/2; pwincy=rc.bottom/2;
00739  if(tool != SKANIMATE){ /* draw wireframe as is */
00740    flag=0;
00741    nstep=5;
00742    for(v1=MainVp,i=0;i<Nvert;i+=nstep,v1+=nstep){
00743      if(intriview(v1)){
00744        m4by1(trr,(double)v1->xyz[0],(double)v1->xyz[1],(double)v1->xyz[2]
00745                 ,&x1,&y1,&z1);
00746        if(y1 >= 0.0){
00747          ix1=(int)(pwincx+scale*x1);
00748          iy1=(int)(pwincy-scale*z1);
00749          MoveToEx(hdc,ix1-1,iy1,NULL);  LineTo(hdc,ix1+2,iy1);
00750          MoveToEx(hdc,ix1,iy1-1,NULL);  LineTo(hdc,ix1,iy1+2);
00751        }
00752        if(HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE)return;
00753      }
00754    }
00755 //   if(flag)return;
00756    ep=MainEp; for(i=0;i<Nedge;i++){
00757     v1=(MainVp+ep->V[0]);
00758     v2=(MainVp+ep->V[1]);
00759     if(in_modeller_view(v1,v2)){
00760       flag=0;
00761       m4by1(trr,(double)v1->xyz[0],(double)v1->xyz[1],(double)v1->xyz[2]
00762                ,&x1,&y1,&z1);
00763       m4by1(trr,(double)v2->xyz[0],(double)v2->xyz[1],(double)v2->xyz[2]
00764                ,&x2,&y2,&z2);
00765       if(y1 >= 0.0){
00766         ix1=(int)(pwincx+scale*x1);
00767         iy1=(int)(pwincy-scale*z1);
00768       }
00769       else  flag=1;
00770       if(y2 >= 0.0){
00771         ix2=(int)(pwincx+scale*x2);
00772         iy2=(int)(pwincy-scale*z2);
00773       }
00774       else flag=1;
00775       if(flag == 0 && (!Preferences.quick_trick || abs(ix1-ix2) > 2 || abs(iy1-iy2) > 2) ){
00776         MoveToEx(hdc,ix1,iy1,NULL);
00777         LineTo(hdc,ix2,iy2);
00778       }
00779       if(HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE)break;
00780     }
00781     ep++;
00782    }
00783  }
00784  else{ /* draw using skeletal transformation */
00785    if(skelview == 0){
00786      static short ep1[12]={0,1,2,3,4,5,6,7,0,1,2,3};
00787      static short ep2[12]={1,2,3,0,5,6,7,4,4,5,6,7};
00788      int i;
00789      skel *sp;
00790      if((sp=MainSp) != NULL)while(sp != NULL){
00791        if(skintriview(sp->tp) || (sp->at != NULL && skintriview(sp->at->tp))){
00792          flag=0;
00793          m4by4(trr,sp->t,t1);
00794          for(i=0;i<12;i++){
00795            m4by1(t1 ,(double)sp->bx[ep1[i]][0]
00796                     ,(double)sp->bx[ep1[i]][1]
00797                     ,(double)sp->bx[ep1[i]][2]
00798                     ,&x1,&y1,&z1);
00799            m4by1(t1 ,(double)sp->bx[ep2[i]][0]
00800                     ,(double)sp->bx[ep2[i]][1]
00801                     ,(double)sp->bx[ep2[i]][2]
00802                     ,&x2,&y2,&z2);
00803            if(y1 >= 0.0){
00804              ix1=(int)(pwincx+scale*x1);
00805              iy1=(int)(pwincy-scale*z1);
00806            }
00807            else  flag=1;
00808            if(y2 > 0.0){
00809              ix2=(int)(pwincx+scale*x2);
00810              iy2=(int)(pwincy-scale*z2);
00811            }
00812            else flag=1;
00813            if(flag == 0){
00814              MoveToEx(hdc,ix1,iy1,NULL);
00815              LineTo(hdc,ix2,iy2);
00816            }
00817          }
00818        }
00819        sp=sp->last;
00820      }
00821    }
00822    else {
00823      ep=MainEp; for(i=0;i<Nedge;i++){
00824        v1=(MainVp+ep->V[0]);
00825        v2=(MainVp+ep->V[1]);
00826        if(in_modeller_view(v1,v2)){
00827          flag=0;
00828          if(v1->sp != NULL)m4by4(trr,v1->sp->t,t1);
00829          else              c4to4(trr,t1);
00830          m4by1(t1 ,(double)v1->xyz[0],(double)v1->xyz[1],(double)v1->xyz[2]
00831                   ,&x1,&y1,&z1);
00832          if(v2->sp != NULL)m4by4(trr,v2->sp->t,t1);
00833          else              c4to4(trr,t1);
00834           m4by1(t1 ,(double)v2->xyz[0],(double)v2->xyz[1],(double)v2->xyz[2]
00835                   ,&x2,&y2,&z2);
00836          if(y1 >= 0.0){
00837            ix1=(int)(pwincx+scale*x1);
00838            iy1=(int)(pwincy-scale*z1);
00839          }
00840          else  flag=1;
00841          if(y2 > 0.0){
00842            ix2=(int)(pwincx+scale*x2);
00843            iy2=(int)(pwincy-scale*z2);
00844          }
00845          else flag=1;
00846          if(flag == 0 && (!Preferences.quick_trick || abs(ix1-ix2) > 2 || abs(iy1-iy2) > 2) ){
00847            MoveToEx(hdc,ix1,iy1,NULL);
00848            LineTo(hdc,ix2,iy2);
00849          }
00850          if(HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE)break;
00851        }
00852        ep++;
00853      }
00854    }
00855  }
00856  return;
00857 }
00858 
00859 int O_normalize(vector v){
00860  double n,nn;
00861  n= (double)((v[0]*v[0]) + (v[1]*v[1]) + (v[2]*v[2]));
00862  if(n < 1.e-10)return FAIL;
00863  nn=sqrt(n);
00864  n = 1.0 / nn;
00865  VECSCALE(n,v,v)
00866  return OK;
00867 }
00868 
00869 BOOL O_Normalize(point x, point y, point z, vector n){
00870  double dz[3],dy[3];
00871  VECSUB((double)y,(double)x,dy)
00872  VECSUB((double)z,(double)x,dz)
00873  CROSS(dy,dz,n)
00874  if(O_normalize(n) == OK)return TRUE;
00875  return FALSE;
00876 }
00877 
00878 
00879 // Hidden line drawing code
00880 
00881 #include "hidden.h"
00882 
00883 #define HRES 2000
00884 
00885 static long    Zbuffer[HRES];
00886 static double  Zdepth [HRES];
00887 static double  DL[HRES],DR[HRES],D1[HRES];
00888 
00889 static object  Object;
00890 static long    XMIN,
00891                XMAX,
00892                YMIN,
00893                YMAX,
00894                Xcentre,
00895                Ycentre;
00896 
00897 static void ModNormUpdate(rvertex *v, rface *f, eface *e);
00898 static void ModRenderHide(RECT rc, HDC hdc, int left_point, int top_point);
00899 static void ModUpdateScanBuffers(double xl, double xr, long id,
00900                        rface  *f, eface  *e, double d2);
00901 static long IntersectZ(long scanline, rvertex  *v1, rvertex  *v2,
00902                 double *xi);
00903 static long ActiveZ(long scanline, rvertex  *v, rface  *f,
00904                       double *leftedge, double *rightedge);
00905 
00906 static void DrawHiddenLine(HDC hdc){
00907  face      *fp;
00908  vertex    *vp,*V0,*V1,*V2;
00909  double   x1,y1,z1,x2,y2,z2;
00910  long     sv,mm,sf,se,me,i,j,k,FirstNurbsVertex;
00911  int      ix1,ix2,iy1,iy2,flag,pwinl,pwinr,pwint,pwinb,pwincx,pwincy;
00912  rvertex  *v;
00913  rface    *f;
00914  eface    *e;
00915  RECT rc;
00916  if((Nvert == 0 || Nface == 0) && Nnurbs == 0)return;
00917  GetClientRect(ghwnd_view,&rc);
00918  pwinl=pwint=0; pwinr=rc.right; pwinb=rc.bottom;
00919  pwincx=rc.right/2; pwincy=rc.bottom/2;
00920  XMIN=0; XMAX=(pwinr-pwinl);
00921  YMIN=0; YMAX=(pwinb-pwint);
00922  Xcentre = XMAX/2; Ycentre=YMAX/2;
00923  Object.NoVertices=0;
00924  Object.NoFaces=0;
00925  vp=MainVp; if(MainVp != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
00926    vp->id = 65535;
00927    vp++;
00928  }
00929  fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++){
00930    V0=(MainVp+fp->V[0]);
00931    V1=(MainVp+fp->V[1]);
00932    V2=(MainVp+fp->V[2]);
00933    if(intriview(V0))V0->id=1;
00934    if(intriview(V1))V1->id=1;
00935    if(intriview(V2))V2->id=1;
00936    fp++;
00937  }
00938  fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++){
00939    V0=(MainVp+fp->V[0]);
00940    V1=(MainVp+fp->V[1]);
00941    V2=(MainVp+fp->V[2]);
00942    if(V0->id == 1 || V1->id == 1 || V2->id == 1 ){
00943      if(V0->id != 1)V0->id = 2;
00944      if(V1->id != 1)V1->id = 2;
00945      if(V2->id != 1)V2->id = 2;
00946    }
00947    fp++;
00948  }
00949  Object.NoVertices=0;
00950  vp=MainVp; if(MainVp != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
00951    if(vp->id == 1 || vp->id == 2){Object.NoVertices++; vp->id = 1;}
00952    vp++;
00953  }
00954  if(Object.NoVertices > 65535){
00955    SendPrgmQuery(IDQ_NOHIDDEN,0);
00956    goto NOTHING;
00957  }
00958  Object.NoFaces=0;
00959  fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++){
00960    V0=(MainVp+fp->V[0]);
00961    V1=(MainVp+fp->V[1]);
00962    V2=(MainVp+fp->V[2]);
00963    if(V0->id == 1 && V1->id == 1 && V2->id == 1 ){
00964      Object.NoFaces++;
00965    }
00966    fp++;
00967  }
00968  //update number of vertices and faces for NURBS
00969  HiddenGetNurbsNumbers(&Object.NoVertices,&Object.NoFaces);
00970  if(Object.NoVertices == 0 || Object.NoFaces == 0)goto NOTHING;
00971  sv=sizeof(rvertex);
00972  mm=Object.NoVertices*(long)sv;
00973  Object.Vbase=(rvertex  *)X__Malloc(mm);
00974  if(Object.Vbase == NULL){
00975    SendPrgmQuery(IDQ_NOHIDDEN,0);
00976    goto NOTHING;
00977  }
00978  sf=sizeof(rface);
00979  mm=Object.NoFaces*(long)sf;
00980  se=sizeof(eface);
00981  me=Object.NoFaces*(long)se;
00982  Object.Fbase=(rface  *)X__Malloc(mm);
00983  if(Object.Fbase == NULL){
00984    SendPrgmQuery(IDQ_NOHIDDEN,0);
00985    X__Free(Object.Vbase);  goto NOTHING;
00986  }
00987  Object.Ebase=(eface  *)X__Malloc(me);
00988  if(Object.Ebase == NULL){
00989   SendPrgmQuery(IDQ_NOHIDDEN,0);
00990   X__Free(Object.Vbase); X__Free(Object.Fbase); goto NOTHING;
00991  }
00992  v=Object.Vbase;
00993  f=Object.Fbase;
00994  e=Object.Ebase;
00995  i=0;
00996  if(1){
00997 // if(tool != SKANIMATE){ /* draw wireframe as is */
00998    vp=MainVp; if(Nvert > 0)for(k=0;k<Nvert;k++){
00999     if(vp->id == 1){
01000       m4by1(trr,(double)vp->xyz[0],(double)vp->xyz[1],(double)vp->xyz[2]
01001                ,&x1,&y1,&z1);
01002       v[i].p[0]=x1; v[i].p[1]=y1; v[i].p[2]=z1;
01003       if(y1 >= 0.0){
01004         v[i].x=Xcentre+scale*x1;
01005         v[i].y=Ycentre-scale*z1;
01006       }
01007       else {v[i].x = 0; v[i].y= 0;}
01008       vp->id= i;
01009       i++;
01010       if(i > Object.NoVertices){
01011         SendPrgmQuery(IDQ_HIDDEN1,0);
01012         goto FREEALL;
01013       }
01014     }
01015     vp++;
01016    }
01017    //add vertices for NURBS
01018    FirstNurbsVertex=i;
01019    HiddenAddNurbsVertices(&i,Object.Vbase,scale,trr,XMAX,YMAX,Xcentre,Ycentre);
01020  }
01021  else{ /* draw using skeletal transformation */
01022    vp=MainVp; for(k=0;k<Nvert;k++){
01023     if(vp->id == 1){
01024       if(vp->sp != NULL)m4by4(trr,vp->sp->t,t1);
01025       else              c4to4(trr,t1);
01026       m4by1(t1 ,(double)vp->xyz[0],(double)vp->xyz[1],(double)vp->xyz[2]
01027                ,&x1,&y1,&z1);
01028       v[i].p[0]=x1; v[i].p[1]=y1; v[i].p[2]=z1;
01029       if(y1 >= 0.0){
01030         v[i].x=Xcentre+scale*x1;
01031         v[i].y=Ycentre-scale*z1;
01032       }
01033       else {v[i].x = 0; v[i].y= 0;}
01034       vp->id= i;
01035       i++;
01036     }
01037     vp++;
01038    }
01039    //add vertices for NURBS
01040    FirstNurbsVertex=i;
01041    HiddenAddNurbsVertices(&i,Object.Vbase,scale,t1,XMAX,YMAX,Xcentre,Ycentre);
01042  }
01043  if(i != Object.NoVertices){
01044    SendPrgmQuery(IDQ_HIDDEN2,0);
01045    goto FREEALL;
01046  }
01047  f=Object.Fbase;
01048  e=Object.Ebase;
01049  i=0;
01050  fp=MainFp; for(k=0;k<Nface;k++){
01051    V0=(MainVp+fp->V[0]);
01052    V1=(MainVp+fp->V[1]);
01053    V2=(MainVp+fp->V[2]);
01054    if(V0->id < 65535 && V1->id < 65535 && V2->id < 65535){
01055      if(i >= Object.NoFaces){
01056        SendPrgmQuery(IDQ_HIDDEN3,0);
01057        goto FREEALL;
01058      }
01059      f[i].V[0]=V0->id;
01060      f[i].V[1]=V1->id;
01061      f[i].V[2]=V2->id;
01062      i++;
01063    }
01064    fp++;
01065  }
01066  //add Nurbs Faces
01067  HiddenAddNurbsFaces(&i,Object.Fbase,FirstNurbsVertex);
01068  if(i != Object.NoFaces){
01069    SendPrgmQuery(IDQ_HIDDEN4,0);
01070    goto FREEALL;
01071  }
01072  ModNormUpdate(v,f,e);
01073  ModRenderHide(rc,hdc,pwinl,pwint);
01074  FREEALL:
01075  X__Free(Object.Vbase);
01076  X__Free(Object.Fbase);
01077  X__Free(Object.Ebase);
01078  NOTHING:
01079  return;
01080 }
01081 
01082 static void ModNormUpdate(rvertex *v, rface *f, eface *e){
01083    long i,bad;
01084    double c,ftop,fbottom,fleft,fright;
01085    vector p1,p2,p0;
01086    for(i=0;i<Object.NoFaces;i++)
01087    {
01088     p0[0]=(v+f->V[0])->p[0];
01089     p0[1]=(v+f->V[0])->p[1];
01090     p0[2]=(v+f->V[0])->p[2];
01091     p1[0]=(v+f->V[1])->p[0];
01092     p1[1]=(v+f->V[1])->p[1];
01093     p1[2]=(v+f->V[1])->p[2];
01094     p2[0]=(v+f->V[2])->p[0];
01095     p2[1]=(v+f->V[2])->p[1];
01096     p2[2]=(v+f->V[2])->p[2];
01097     VECSUB(p2,p0,p2)
01098     VECSUB(p1,p0,p1)
01099     CROSS(p1,p2,e->n)
01100     if(O_normalize(e->n) == FAIL)bad=1;
01101     else                         bad=0;
01102     c=DOT(p0,e->n);
01103     e->c=(double)c;
01104       if(c > 0.0){
01105         VECSCALE((double)(-1.0),e->n,e->n)
01106         e->c=(double)c*(-1.0);
01107     }
01108     ftop=min((v+(f->V[0]))->y,(v+(f->V[1]))->y);
01109     ftop=min((v+(f->V[2]))->y,ftop);
01110     fbottom=max((v+(f->V[0]))->y,(v+(f->V[1]))->y);
01111     fbottom=max((v+(f->V[2]))->y,fbottom)+1;
01112     fleft=min((v+(f->V[0]))->x,(v+(f->V[1]))->x);
01113     fleft=min((v+(f->V[2]))->x,fleft);
01114     fright=max((v+(f->V[0]))->x,(v+(f->V[1]))->x);
01115     fright=max((v+(f->V[2]))->x,fright)+1;
01116     if(ftop < 0.0)f->top= -1;
01117     else if(ftop > YMAX)f->top=YMAX+1;
01118     else f->top=(int)ftop;
01119     if(fbottom < 0.0)f->bottom= -1;
01120     else if(fbottom > YMAX)f->bottom=YMAX+1;
01121     else f->bottom=(int)fbottom;
01122     if(fleft < 0.0)f->left= -1;
01123     else if(fleft > XMAX)f->left=XMAX+1;
01124     else f->left=(int)fleft;
01125     if(fright < 0.0)f->right= -1;
01126     else if(fright > XMAX)f->right=XMAX+1;
01127     else f->right=(int)fright;
01128     if( ( v[ f->V[0] ].p[1] <= 0)  /* nodes in face are either behind */
01129      && ( v[ f->V[1] ].p[1] <= 0)  /* or on viewing plane */
01130      && ( v[ f->V[2] ].p[1] <= 0)){
01131       f->top=YMAX+1;
01132     }
01133     if(f->left >= XMAX){
01134       f->top=YMAX+1;
01135     }
01136     if(f->right < XMIN){
01137       f->top=YMAX+1;
01138     }
01139     if(fabs(e->c) < 1.e-5){
01140       f->top=YMAX+1;
01141     }
01142     if(bad)f->top=YMAX+1;
01143     f++; e++;
01144    }
01145 }
01146 
01147 static void ModRenderHide(RECT rc, HDC hdc, int left_point, int top_point){
01148  long i,j,jj,k;
01149  long Zold[HRES];
01150  double d2,xl,xr;
01151  rvertex  *v;
01152  rface    *f;
01153  eface   *e;
01154  HPEN holdpen;
01155 // LOGPEN lopn;
01156 // GetObject(ghEdgePen,sizeof(LOGPEN),&lopn);
01157  holdpen=SelectObject(hdc,ghEdgePen);
01158  rc.bottom=rc.top;
01159  for(i=XMIN;i<XMAX;i++) {
01160    DL[i]=(double)(i - Xcentre);        DL[i]/=scale;
01161    DR[i]=(double)(i+1-Xcentre);        DR[i]/=scale;
01162    D1[i]=(double)(i - Xcentre) + 0.5;  D1[i]/=scale;
01163    Zold[i]= -1;
01164  }
01165  for(k=YMIN;k<YMAX;k++){
01166    d2=(double)(Ycentre-k);
01167    d2/=scale;
01168    for(i=XMIN;i<XMAX;i++){
01169      Zbuffer[i] = -1;
01170      Zdepth [i] = FARAWAY;
01171    }
01172    v=Object.Vbase;
01173    f=Object.Fbase;
01174    e=Object.Ebase;
01175    for(j=0;j<Object.NoFaces;j++)
01176      if( ActiveZ(k,v,f+j,&xl,&xr) ){
01177        ModUpdateScanBuffers(xl,xr,j,f+j,e+j,d2);
01178      }
01179    for(j=XMIN+1;j<XMAX;j++){
01180      if((Zbuffer[j] != Zbuffer[j-1])
01181         || (Zold[j] != Zbuffer[j])) {
01182 //        X__SetPixel(hdc,j+left_point,k+top_point,lopn.lopnColor);
01183         MoveToEx(hdc,j+left_point,k+top_point,NULL);
01184         LineTo(hdc,j+left_point+1,k+top_point);
01185       }
01186       Zold[j]=Zbuffer[j];
01187    }
01188    if(GetAsyncKeyState(VK_ESCAPE) & 0x8000)break;
01189    rc.bottom++;
01190    InvalidateRect(ghwnd_view,&rc,FALSE);
01191    rc.top++;
01192    UpdateWindow(ghwnd_view);
01193  }
01194  SelectObject(hdc,holdpen);
01195  return;
01196 }
01197 
01198 static void ModUpdateScanBuffers(double xl, double xr, long id,
01199                        rface  *f, eface  *e, double d2){
01200  long i,ixl,ixr;
01201  double en1,depth,bL,bR,aL,aR,dL,dR,dl,dr,dd;
01202  ixl = (long)xl;
01203  ixr = (long)xr;
01204  if(ixl < 0)ixl=0;
01205  if(ixr < 0)ixr=0;
01206  if(ixl >= XMAX)ixl=XMAX-1;
01207  if(ixr >= XMAX)ixr=XMAX-1;
01208  if(fabs(e->n[1]) < 1.e-30)en1=1.e-30;
01209  else                      en1=e->n[1];
01210  if(ixl == ixr){
01211    dL = xl - (double)Xcentre; dL/=scale;
01212    dR = xr - (double)Xcentre; dR/=scale;
01213    aL = (e->c - e->n[0]*dL - e->n[2]*d2)/en1;
01214    aR = (e->c - e->n[0]*dR - e->n[2]*d2)/en1;
01215    depth=min(aL,aR);
01216    if(depth > 0 && depth <= Zdepth[ixl]){
01217      Zdepth[ixl]=depth; Zbuffer[ixl]=id;
01218    }
01219    return;
01220  }
01221  else{
01222    dl = (e->c - e->n[0]*DR[ixl] - e->n[2]*d2)/en1;
01223    dr = (e->c - e->n[0]*DL[ixr] - e->n[2]*d2)/en1;
01224    dd = (dr-dl)/(xr-xl);
01225    for(i=0;i<ixr-ixl;i++){
01226      depth = dl + i*dd;
01227      if(depth > 0 && depth <= Zdepth[i+ixl]){
01228        Zdepth[i+ixl]=depth; Zbuffer[i+ixl]=id;
01229      }
01230    }
01231  }
01232 }
01233 
01234 static long IntersectZ(long scanline, rvertex  *v1, rvertex  *v2,
01235                 double *xi){
01236  double ddx,ddy,doff,ddxy;
01237  if((v1->y < scanline)  && (v2->y < scanline))return 0;
01238  if((v1->y > scanline)  && (v2->y > scanline))return 0;
01239  ddy = (v2->y) - (v1->y);
01240  if(fabs(ddy) < 0.0001)return 0;
01241  ddx = (v2->x) - (v1->x);
01242  doff=(double)scanline - v1->y;
01243  ddxy=ddx*doff/ddy;
01244  *xi=(v1->x)+ddxy;
01245  return 1;
01246 }
01247 
01248 static long ActiveZ(long scanline, rvertex  *v, rface  *f,
01249                       double *leftedge, double *rightedge){
01250  long v1,v2,v3
01251      ,i1,i2,i3;
01252  double x1,x2,x3;
01253  if(f->top > scanline)       return 0;
01254  if(f->bottom < scanline)    return 0;
01255  v1=f->V[0];
01256  v2=f->V[1];
01257  v3=f->V[2];
01258  i1=IntersectZ(scanline,(v+v1),(v+v2),&x1);
01259  i2=IntersectZ(scanline,(v+v2),(v+v3),&x2);
01260  i3=IntersectZ(scanline,(v+v3),(v+v1),&x3);
01261  if((i1 == 1) && (i2 == 1) && (i3 == 1))
01262  {*leftedge = min(min(x1,x2),x3);
01263   *rightedge= max(max(x1,x2),x3);}
01264  else if((i2 == 1) && (i3 == 1))
01265  {*leftedge = min(x2,x3);
01266   *rightedge= max(x2,x3);}
01267  else if((i3 == 1) && (i1 == 1))
01268  {*leftedge = min(x3,x1);
01269   *rightedge= max(x3,x1);}
01270  else if((i1 == 1) && (i2 == 1))
01271  {*leftedge = min(x1,x2);
01272   *rightedge= max(x1,x2);}
01273  else return 0;
01274  if(*leftedge >= XMAX)return 0;
01275  else *leftedge  = max(0,*leftedge);
01276  if(*rightedge < XMIN)return 0;
01277  *rightedge = min(XMAX-0.01,*rightedge);
01278  return 1;
01279 }
01280 
01281 // End of hidden line drawing code
01282 
01283 void DrawRubberBoundBox(long xmin, long ymin, long zmin,
01284                         long xmax, long ymax, long zmax){
01285  int i,j,n;
01286  int x1,y1,x2,y2;
01287  RECT rc;
01288  HDC hDC;
01289  if(View == TRIVIEW)n=3;
01290  else               n=1;
01291  for(j=0;j<n;j++){
01292    i=order_list[ActiveView][j];
01293    hDC=GetDC(ghwnd_triview[i]);
01294    SelectObject(hDC,ghInvertPen);
01295    SetROP2(hDC,R2_XORPEN);
01296    SelectPalette(hDC,ghpaletteScreen,FALSE);
01297    RealizePalette(hDC);
01298    GetWindowCoords(i,xmin,ymin,zmin,&x1,&y1);
01299    GetWindowCoords(i,xmax,ymax,zmax,&x2,&y2);
01300    if(x2 == x1)x2++; if(y2 == y1)y2++;
01301    DrawOne3dCursor(hDC,i);
01302    MoveToEx(hDC,x1,y1,NULL);
01303    LineTo(hDC,x2,y1); LineTo(hDC,x2,y2); LineTo(hDC,x1,y2); LineTo(hDC,x1,y1);
01304    DrawOne3dCursor(hDC,i);
01305    ReleaseDC(ghwnd_triview[i],hDC);
01306  }
01307 }
01308 
01309 void DrawRubber3dLine(point p1,point p2){
01310  int i,j,n;
01311  int x1,y1,x2,y2;
01312  RECT rc;
01313  HDC hDC;
01314  if(View == TRIVIEW)n=3;
01315  else               n=1;
01316  for(j=0;j<n;j++){
01317    i=order_list[ActiveView][j];
01318    hDC=GetDC(ghwnd_triview[i]);
01319    SelectObject(hDC,ghInvertPen);
01320    SetROP2(hDC,R2_XORPEN);
01321    SelectPalette(hDC,ghpaletteScreen,FALSE);
01322    RealizePalette(hDC);
01323    GetWindowCoords(i,p1[0],p1[1],p1[2],&x1,&y1);
01324    GetWindowCoords(i,p2[0],p2[1],p2[2],&x2,&y2);
01325    if(x2 == x1)x2++; if(y2 == y1)y2++;
01326    DrawOne3dCursor(hDC,i);
01327    MoveToEx(hDC,x2,y2,NULL); LineTo(hDC,x1,y1);
01328    DrawOne3dCursor(hDC,i);
01329    ReleaseDC(ghwnd_triview[i],hDC);
01330  }
01331 }
01332 
01333 void DrawRubberLines(HWND hwnd, int av, long vtx, int x, int y){
01334  static long last_V,last_x,last_y,last_z;
01335  long xx,yy,zz;
01336  edge *ep;
01337  vertex *this_V;
01338  int i,j,n,k;
01339  int x1,y1,x2,y2,xo,yo;
01340  RECT rc;
01341  HDC hDC;
01342  if(Nedge == 0)return;
01343  if(vtx >= 0)last_V=vtx;
01344  if(View == TRIVIEW)n=3;
01345  else               n=1;
01346  if(ActiveView == TRIFRONT){
01347    xx=NpointerX; yy=(MainVp+last_V)->xyz[1]; zz=NpointerZ;
01348  }
01349  else if(ActiveView == TRIRIGHT){
01350    xx=(MainVp+last_V)->xyz[0]; yy=NpointerY; zz=NpointerZ;
01351  }
01352  else{
01353    xx=NpointerX; yy=NpointerY; zz=(MainVp+last_V)->xyz[2];
01354  }
01355  for(j=0;j<n;j++){
01356    i=order_list[ActiveView][j];
01357    hDC=GetDC(ghwnd_triview[i]);
01358    SelectObject(hDC,ghInvertPen);
01359    SetROP2(hDC,R2_XORPEN);
01360    SelectPalette(hDC,ghpaletteScreen,FALSE);
01361    RealizePalette(hDC);
01362    DrawOne3dCursor(hDC,i);
01363    if(vtx < 0){
01364      GetWindowCoords(i,last_x,last_y,last_z,&xo,&yo);
01365    }
01366    GetWindowCoords(i,xx,yy,zz,&x1,&y1);
01367    for(k=0;k<Nedge;k++){
01368      ep=(MainEp+k);
01369      if     (ep->V[0] == last_V)this_V=(MainVp+ep->V[1]);
01370      else if(ep->V[1] == last_V)this_V=(MainVp+ep->V[0]);
01371      else continue;
01372      if(this_V->status == HIDDEN)continue;
01373      GetWindowCoords(i,this_V->xyz[0],this_V->xyz[1],this_V->xyz[2],&x2,&y2);
01374      if(vtx < 0){
01375        MoveToEx(hDC,xo,yo,NULL); LineTo(hDC,x2,y2);
01376      }
01377      if(vtx > -2){
01378        MoveToEx(hDC,x1,y1,NULL); LineTo(hDC,x2,y2);
01379      }
01380    }
01381    DrawOne3dCursor(hDC,i);
01382    ReleaseDC(ghwnd_triview[i],hDC);
01383  }
01384  last_x=xx; last_y=yy; last_z=zz;
01385  if(vtx == -2){
01386    (MainVp+last_V)->xyz[0]=xx;
01387    (MainVp+last_V)->xyz[1]=yy;
01388    (MainVp+last_V)->xyz[2]=zz;
01389  }
01390 }
01391 
01392 void DrawBrush(int brushID){
01393  HDC hdc;
01394  int i,j,n,k;
01395  if(View == TRIVIEW)n=3;
01396  else               n=1;
01397  k=ActiveView;
01398  for(j=0;j<n;j++){
01399    i=order_list[k][j];
01400 //   to draw the brush in the background windows
01401 //   hdc=GetDC(ghwnd_triview[i]);
01402 //   DrawBrushInOne(hdc,i,SelectedBrush);
01403    DrawBrushInOne(ghdc_triview_Bitmap[i],i,SelectedBrush);
01404    InvalidateRect(ghwnd_triview[i],NULL,FALSE);
01405    //   ReleaseDC(ghwnd_triview[i],hdc);
01406  }
01407 }
01408 
01409 void DrawShader(int shaderID){
01410  HDC hdc;
01411  int i,j,n,k;
01412  if(View == TRIVIEW)n=3;
01413  else               n=1;
01414  k=ActiveView;
01415  for(j=0;j<n;j++){
01416    i=order_list[k][j];
01417    hdc=GetDC(ghwnd_triview[i]);
01418    DrawShaderInOne(hdc,i,shaderID);
01419    ReleaseDC(ghwnd_triview[i],hdc);
01420  }
01421 }
01422 
01423 void DrawShaperSphere(long x,long y,long z,
01424                       double shaper_angle_theta,
01425                       double shaper_angle_phi,
01426                       double shaper_size){
01427  vector shaper_direction={0.0,0.0,1.0};
01428  int   x1,y1,x2,y2,x3,y3,i,j,n,radius;
01429  long  Px,Py,Pz;
01430  double shaper_scale;
01431  RECT rc;
01432  HDC hDC;
01433  shaper_direction[2]=cos(shaper_angle_theta);
01434  shaper_direction[0]=cos(shaper_angle_phi)*sin(shaper_angle_theta);
01435  shaper_direction[1]=sin(shaper_angle_phi)*sin(shaper_angle_theta);
01436  shaper_scale=(double)TVsizeX/shaper_size*1.2;
01437  Px=x+(long)(shaper_direction[0]*shaper_scale);
01438  Py=y+(long)(shaper_direction[1]*shaper_scale);
01439  Pz=z+(long)(shaper_direction[2]*shaper_scale);
01440  if(View == TRIVIEW)n=3;
01441  else               n=1;
01442  for(j=0;j<n;j++){
01443    i=order_list[ActiveView][j];
01444    hDC=GetDC(ghwnd_triview[i]);
01445    SelectObject(hDC,ghInvertPen);
01446    SelectObject(hDC,GetStockObject(HOLLOW_BRUSH));
01447    SetROP2(hDC,R2_XORPEN);
01448    SelectPalette(hDC,ghpaletteScreen,FALSE);
01449    RealizePalette(hDC);
01450    GetWindowCoords(i,x,y,z,&x1,&y1);
01451    GetWindowCoords(i,Px,Py,Pz,&x3,&y3);
01452    GetWindowCoords(i,x+(long)(TVsizeX/shaper_size),
01453                      y+(long)(TVsizeY/shaper_size),
01454                      z+(long)(TVsizeZ/shaper_size),&x2,&y2);
01455    if(x2 == x1)x2++; if(y2 == y1)y2++;
01456    DrawOne3dCursor(hDC,i);
01457 //   MoveToEx(hDC,x1,y1,NULL); LineTo(hDC,x3,y3);  // SHAPER
01458    radius=abs(x2-x1);
01459    if(radius > 0)Ellipse(hDC,x1-radius,y1-radius,
01460                              x1+radius,y1+radius);
01461    DrawOne3dCursor(hDC,i);
01462    ReleaseDC(ghwnd_triview[i],hDC);
01463  }
01464 }
01465 
01466 void DrawSkeleton(void){
01467  HDC hdc;
01468  int i,j,n,k;
01469  if(View == TRIVIEW)n=3;
01470  else               n=1;
01471  k=ActiveView;
01472  for(j=0;j<n;j++){
01473    i=order_list[k][j];
01474    hdc=GetDC(ghwnd_triview[i]);
01475    DrawSkeletonInOne(hdc,i);
01476    ReleaseDC(ghwnd_triview[i],hdc);
01477  }
01478 }
01479 
01480 #if 0
01481 void DrawQuickModel(void){
01482  int v;
01483  RECT rc;
01484  v=ActiveView;
01485  if(ghdc_triview_Bitmap[v] == NULL)return;
01486  if(ghbm_triview[v] == NULL)return;
01487  GetClientRect(ghwnd_triview[v],&rc);
01488  PatBlt(ghdc_triview_Bitmap[v],0,0,rc.right,rc.bottom,PATCOPY);
01489  if(sktool == YES && tool == SKANIMATE){
01490    DrawTrSkeletonInOne(ghdc_triview_Bitmap[v],v);
01491  }
01492  else {
01493    int i,j,sho,svo,sh1,sv1,sh2,sv2,k=0;
01494    edge   *ep;
01495    vertex *vp,*v1,*v2;
01496    HDC hdc;
01497    HPEN holdpen;
01498    short (*in_modeller_view)(vertex *vp1, vertex *vp2);
01499    hdc=ghdc_triview_Bitmap[v];
01500    holdpen=SelectObject(hdc,ghEdgePen);
01501    if(Nedge > 1){
01502      in_modeller_view = in_modeller_view1; /* test function */
01503      for(j=0;j<2;j++){
01504      ep=MainEp; if(j == 1)ep++; k=0;
01505      for(i=j;i<Nedge;i+=2){
01506        v1=(MainVp+ep->V[0]);
01507        v2=(MainVp+ep->V[1]);
01508        if(in_modeller_view(v1,v2)){
01509          GetWindowCoords(v,v1->xyz[0],v1->xyz[1],v1->xyz[2],&sh1,&sv1);
01510          GetWindowCoords(v,v2->xyz[0],v2->xyz[1],v2->xyz[2],&sh2,&sv2);
01511          if((!Preferences.quick_trick || abs(sh1-sh2) > 3 || abs(sv1-sv2) > 3) ){
01512            MoveToEx(hdc,sh1,sv1,NULL); LineTo(hdc,sh2,sv2); k++;
01513          }
01514        }
01515        if(HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE && k > 75){
01516          update_timer=SetTimer(ghwnd_main,1,33,NULL);
01517          goto ABORT;
01518        }
01519        ep+=2;
01520      }
01521      }
01522    }
01523    DrawArrowIcons(ghdc_triview_Bitmap[v],v);
01524    InvalidateRect(ghwnd_triview[v],NULL,FALSE);
01525    UpdateWindow(ghwnd_triview[v]);
01526    SelectObject(hdc,ghDeselectedPen);
01527    if(intriview(&ObjectAxis.Offset)){
01528      GetWindowCoords(v,ObjectAxis.Offset.xyz[0],
01529         ObjectAxis.Offset.xyz[1],ObjectAxis.Offset.xyz[2],&sho,&svo);
01530      MoveToEx(hdc,sho-3,svo,NULL); LineTo(hdc,sho+4,svo);
01531      MoveToEx(hdc,sho,svo-3,NULL); LineTo(hdc,sho,svo+4);
01532    }
01533    SelectObject(hdc,ghSelectedPen);
01534    if(intriview(&ObjectAxis.Origin)){
01535      GetWindowCoords(v,ObjectAxis.Origin.xyz[0],
01536       ObjectAxis.Origin.xyz[1],ObjectAxis.Origin.xyz[2],&sho,&svo);
01537      MoveToEx(hdc,sho-5,svo,NULL); LineTo(hdc,sho+6,svo);
01538      MoveToEx(hdc,sho,svo-5,NULL); LineTo(hdc,sho,svo+6);
01539    }
01540    SelectObject(hdc,ghSelectedPen);
01541    vp=MainVp; if(MainVp != NULL)for(i=0;i<Nvert;i++){
01542     if(vp->status != HIDDEN)if(intriview(vp)){
01543       GetWindowCoords(v,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sho,&svo);
01544       MoveToEx(hdc,sho,svo,NULL); LineTo(hdc,sho+1,svo);
01545       if(HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE){
01546         if(update_timer == 0){
01547           update_timer=SetTimer(ghwnd_main,1,33,NULL);
01548         }
01549         goto ABORT;
01550       }
01551     }
01552     vp++;
01553    }
01554    ABORT:
01555    SelectObject(hdc,holdpen);
01556  }
01557  DrawArrowIcons(ghdc_triview_Bitmap[v],v);
01558  InvalidateRect(ghwnd_triview[v],NULL,FALSE);
01559  UpdateWindow(ghwnd_triview[v]);
01560  return;
01561 }
01562 #endif
01563 
01564 void DrawQuickModel(void){
01565  int v;
01566  RECT rc;
01567  HDC hdc;
01568  HPALETTE hpalT;
01569  HBRUSH hOldBrush;
01570  v=ActiveView;
01571  hdc=GetDC(ghwnd_triview[v]);
01572  hpalT = SelectPalette(hdc,ghpaletteScreen,FALSE);
01573  RealizePalette (hdc);
01574  hOldBrush = SelectObject(hdc,ghbrushWindow);
01575  GetClientRect(ghwnd_triview[v],&rc);
01576  PatBlt(hdc,0,0,rc.right,rc.bottom,PATCOPY);
01577  if(sktool == YES && tool == SKANIMATE){
01578    DrawTrSkeletonInOne(hdc,v);
01579  }
01580  else {
01581    int i,j,sho,svo,sh1,sv1,sh2,sv2,k=0,Nstep;
01582    edge   *ep;
01583    vertex *vp,*v1,*v2;
01584    HPEN holdpen;
01585    short (*in_modeller_view)(vertex *vp1, vertex *vp2);
01586    if(draw_grid_on)DrawGridInOne(hdc,v);
01587    DrawArrowIcons(hdc,v);
01588    holdpen=SelectObject(hdc,ghDeselectedPen);
01589    if(intriview(&ObjectAxis.Offset)){
01590      GetWindowCoords(v,ObjectAxis.Offset.xyz[0],
01591         ObjectAxis.Offset.xyz[1],ObjectAxis.Offset.xyz[2],&sho,&svo);
01592      MoveToEx(hdc,sho-3,svo,NULL); LineTo(hdc,sho+4,svo);
01593      MoveToEx(hdc,sho,svo-3,NULL); LineTo(hdc,sho,svo+4);
01594    }
01595    SelectObject(hdc,ghSelectedPen);
01596    if(intriview(&ObjectAxis.Origin)){
01597      GetWindowCoords(v,ObjectAxis.Origin.xyz[0],
01598       ObjectAxis.Origin.xyz[1],ObjectAxis.Origin.xyz[2],&sho,&svo);
01599      MoveToEx(hdc,sho-5,svo,NULL); LineTo(hdc,sho+6,svo);
01600      MoveToEx(hdc,sho,svo-5,NULL); LineTo(hdc,sho,svo+6);
01601    }
01602    SelectObject(hdc,ghSelectedPen);
01603    Nstep=4;
01604    vp=MainVp; if(MainVp != NULL)for(i=0;i<Nvert;i+=Nstep){
01605     if(vp->status != HIDDEN)if(intriview(vp)){
01606       GetWindowCoords(v,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sho,&svo);
01607       MoveToEx(hdc,sho,svo,NULL); LineTo(hdc,sho+1,svo);
01608       if(HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE){
01609         goto ABORT;
01610       }
01611       if(HIWORD(GetQueueStatus(QS_MOUSEBUTTON)) == QS_MOUSEBUTTON)goto ABORT;
01612     }
01613     vp+=Nstep;
01614    }
01615    SelectObject(hdc,ghEdgePen);
01616    if(Nedge > 1){
01617      in_modeller_view = in_modeller_view1; /* test function */
01618      for(j=0;j<2;j++){
01619      ep=MainEp; if(j == 1)ep++; k=0;
01620      for(i=j;i<Nedge;i+=2){
01621        v1=(MainVp+ep->V[0]);
01622        v2=(MainVp+ep->V[1]);
01623        if(in_modeller_view(v1,v2)){
01624          GetWindowCoords(v,v1->xyz[0],v1->xyz[1],v1->xyz[2],&sh1,&sv1);
01625          GetWindowCoords(v,v2->xyz[0],v2->xyz[1],v2->xyz[2],&sh2,&sv2);
01626          if((!Preferences.quick_trick || abs(sh1-sh2) > 3 || abs(sv1-sv2) > 3) ){
01627            MoveToEx(hdc,sh1,sv1,NULL); LineTo(hdc,sh2,sv2); k++;
01628          }
01629        }
01630        if(HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE && k > 75){
01631          goto ABORT;
01632        }
01633        if(HIWORD(GetQueueStatus(QS_MOUSEBUTTON)) == QS_MOUSEBUTTON)goto ABORT;
01634        ep+=2;
01635      }
01636      }
01637    }
01638    DrawAllNurbsInOne(hdc,v,TRUE);
01639    ABORT:
01640    SelectObject(hdc,holdpen);
01641  }
01642  DrawArrowIcons(hdc,v);
01643  SelectObject (hdc, hOldBrush);
01644  SelectPalette(hdc,hpalT,FALSE);
01645  ReleaseDC(ghwnd_triview[v],hdc);
01646  return;
01647 }

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