TWIST.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 - 2007 OpenFX Development Team
00004 -- */
00005 
00006 /*  TWIST.C  */
00007 #include <stdlib.h>
00008 #include <stdio.h>
00009 #include <math.h>
00010 #include <windows.h>
00011 
00012 #include "struct.h"
00013 #include "dstruct.h"
00014 
00015 #include "twist.h"
00016 
00017 #define DESELECTED 0
00018 #define SELECTED   1
00019 #define FAIL      -1
00020 #define OK         1
00021 
00022 #define POINT2VECTOR(p,v) v[0]=(double)p[0]; v[1]=(double)p[1]; \
00023                           v[2]=(double)p[2];
00024 #define VECTOR2POINT(v,p) p[0]=(long)v[0]; p[1]=(long)v[1]; \
00025                           p[2]=(long)v[2];
00026 #define VECCOPY(a,b)    { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
00027 #define VECSUB(a,b,c)   { c[0]=a[0]-b[0]; c[1]=a[1]-b[1]; c[2]=a[2]-b[2];}
00028 #define VECSUM(a,b,c)   { c[0]=a[0]+b[0]; c[1]=a[1]+b[1]; c[2]=a[2]+b[2];}
00029 #define VECSCALE(a,b,c) { c[0]=(a)*b[0]; c[1]=(a)*b[1]; c[2]=(a)*b[2];}
00030 #define DOT(a,b)        ( (a[0]*b[0]) + (a[1]*b[1]) + (a[2]*b[2]) )
00031 #define CROSS(v1,v2,r)  { \
00032                           r[0] = (v1[1]*v2[2]) - (v2[1]*v1[2]);  \
00033                           r[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]);  \
00034                           r[2] = (v1[0]*v2[1]) - (v2[0]*v1[1]);  \
00035                          }
00036 
00037 static HWND      hParent;
00038 static HINSTANCE hThisInstance;
00039 
00040 static BOOL CALLBACK TwistAlongDlgProc(HWND hwnd, UINT msg,
00041                              WPARAM wparam, LPARAM lparam);
00042 
00043 void MultMV(double t4[4][4], long x, long y, long z,
00044            long *xx, long *yy, long *zz){
00045  *xx=(long)(t4[0][0]*(double)x+t4[0][1]*(double)y+t4[0][2]*(double)z+t4[0][3]);
00046  *yy=(long)(t4[1][0]*(double)x+t4[1][1]*(double)y+t4[1][2]*(double)z+t4[1][3]);
00047  *zz=(long)(t4[2][0]*(double)x+t4[2][1]*(double)y+t4[2][2]*(double)z+t4[2][3]);
00048  return;
00049 }
00050 
00051 void CopyMM(double tin[4][4], double tout[4][4]){
00052  short i,j;
00053  for(i=0;i<4;i++)
00054  for(j=0;j<4;j++)
00055  tout[i][j]=tin[i][j];
00056 }
00057 
00058 void MultMM(double t1[4][4], double t2[4][4], double tr[4][4]){
00059  short n=4,i,j,k;
00060  for(i=0;i<4;i++)
00061  for(j=0;j<4;j++)
00062  {
00063   tr[i][j]=0.0;
00064   for(k=0;k<4;k++)tr[i][j]=tr[i][j]+t1[i][k]*t2[k][j];
00065  }
00066  return;
00067 }
00068 
00069 #if __WATCOMC__
00070 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00071 #else
00072 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00073 #endif
00074   switch (dwReason) {
00075     case DLL_PROCESS_ATTACH: {
00076       hThisInstance=hDLL;
00077       if(hDLL == NULL)MessageBox ( GetFocus()," NULL instance",NULL, MB_OK);
00078       break;
00079     }
00080     case DLL_PROCESS_DETACH:
00081       break;
00082   }
00083   return TRUE;
00084 }
00085 
00086 #if __SC__
00087 #pragma startaddress(DllMain)
00088 #endif
00089 
00090 BOOL _Xmodeler
00091  (HWND parent_window,HWND info_window,X__STRUCTURE *lpevi){
00092  BOOL Twist,Xtrude=TRUE;
00093  struct np {int nstep; double repeat_map,angle; BOOL Xtrude;} data;
00094  long vp,vf,*va,LastV;
00095  double t[4][4],tr[4][4],ts[4][4];
00096  double l,ll,ls,dmap,ddmap,theta,alpha,dz,repeat_map=4.0,twist=360.0;
00097  long i,j,Npath,Dn,Nstep=16;
00098  vertex *Vp,*Va,*Va1,*Va2;
00099  vector dr,drr,n;
00100  point pc,pn;
00101  HCURSOR hSave;
00102  lpEVI=lpevi;
00103  hParent=parent_window;
00104  if(NvertSelect < 1 || NvertSelect > 32000)return FALSE;
00105  if((vf=get_closest_vertex()) < 0)return FALSE;
00106  data.repeat_map=repeat_map;
00107  data.angle=twist;
00108  data.nstep=Nstep;
00109  data.Xtrude=Xtrude;
00110  if(DialogBoxParam(hThisInstance,MAKEINTRESOURCE(DLG_TWIST),
00111      hParent,(DLGPROC)TwistAlongDlgProc,(LPARAM)&data) == FAIL)return FALSE;
00112  repeat_map=data.repeat_map;
00113  twist=data.angle;
00114  Xtrude=data.Xtrude;
00115  Nstep=data.nstep; if(Nstep < 1)return FALSE;
00116  if((va=(long *)X__Malloc(NvertSelect*sizeof(long))) == NULL){
00117    return FALSE;
00118  }
00119  hSave=SetCursor(LoadCursor(NULL,IDC_WAIT));
00120  Npath=0; va[0]=vf; (MainVp+va[0])->id=1;
00121  (MainVp+vf)->status=DESELECTED; NvertSelect--; NvertDeselect++;
00122  vp=0; while(vp < Nvert){
00123    Vp=(MainVp+vp);
00124    if(Vp->status == SELECTED && Vp->id == 0 && Connected(va[Npath],vp)){
00125      Npath++;
00126      va[Npath]=vp;
00127      Vp->id=1;
00128      Vp->status=DESELECTED;
00129      NvertSelect--; NvertDeselect++;
00130      vp=0;
00131    }
00132    else vp++;
00133  }
00134  if(Npath > 0){ /* at least 2 points needed */
00135    l=0.0; ll=0.0; /* get length of path */
00136    for(i=1;i<=Npath;i++){
00137      Va=(MainVp+va[i]); Va1=(MainVp+va[i-1]);
00138      l += sqrt(
00139          (double)(Va->xyz[0] - Va1->xyz[0])*
00140          (double)(Va->xyz[0] - Va1->xyz[0])+
00141          (double)(Va->xyz[1] - Va1->xyz[1])*
00142          (double)(Va->xyz[1] - Va1->xyz[1])+
00143          (double)(Va->xyz[2] - Va1->xyz[2])*
00144          (double)(Va->xyz[2] - Va1->xyz[2]));
00145    }
00146    for(i=1;i<=Npath;i++){ /* extrude along each path segment */
00147 //   for(i=1;i<=1;i++){ /* extrude along each path segment */
00148      Va=(MainVp+va[i]); Va1=(MainVp+va[i-1]);
00149      VECSUB((double)Va->xyz,(double)Va1->xyz,dr)
00150      if(oNormalize(dr) == FAIL)goto EXIT;
00151      ls = sqrt(
00152          (double)(Va->xyz[0] - Va1->xyz[0])*
00153          (double)(Va->xyz[0] - Va1->xyz[0])+
00154          (double)(Va->xyz[1] - Va1->xyz[1])*
00155          (double)(Va->xyz[1] - Va1->xyz[1])+
00156          (double)(Va->xyz[2] - Va1->xyz[2])*
00157          (double)(Va->xyz[2] - Va1->xyz[2]));
00158      ll += ls;
00159      dmap=ll/l*repeat_map;
00160      theta=twist/Nstep; dz=ls/Nstep; ddmap=dmap/Nstep; dmap=ddmap;
00161      Twist=FALSE;
00162      if(i < Npath){
00163        Va2=(MainVp+va[i+1]);
00164        VECSUB((double)Va2->xyz,(double)Va->xyz,drr)
00165        if(oNormalize(drr) != FAIL){
00166          if((alpha=fabs(DOT(dr,drr))) < 9.8){ /* bend in path */
00167            CROSS(dr,drr,n)
00168            VECSCALE((double)TVsizeZ,n,n)
00169            alpha = acos(alpha);
00170            alpha *= 180.0/3.14159;
00171            if(alpha > 2.0)Twist=TRUE;
00172            alpha /= Nstep;
00173          }
00174        }
00175      }
00176      LastV=Nvert;
00177      for(j=0;j<Nstep;j++){
00178        if(Xtrude){
00179          if(!CreateAttachedCopy(1))goto EXIT;
00180        }
00181        else{
00182          if(!AddCopy(0))goto EXIT;
00183        }
00184      }
00185      Va=(MainVp+va[i]); Va1=(MainVp+va[i-1]);
00186      Dn=(Nvert-LastV)/Nstep;
00187      VECCOPY(Va1->xyz,pc)
00188      VECSUM(pc,(long)n,pn)
00189      for(j=0;j<Nstep;j++){ /* twist each step in segment  */
00190        ArbitraryRotate(theta*(j+1),Va1->xyz,Va->xyz,tr);
00191        if(Twist){
00192          ArbitraryRotate(alpha*(j+1),pc,pn,ts);
00193          MultMM(ts,tr,t);
00194        }
00195        else CopyMM(tr,t);
00196        for(vp=LastV;vp<LastV+Dn;vp++){ /* move new points into position */
00197          Vp=(MainVp+vp);
00198          if(Vp->gp > 0){
00199            Vp->y = dmap;
00200          }
00201          MultMV(t,Vp->xyz[0],Vp->xyz[1],Vp->xyz[2],
00202                 &Vp->xyz[0],&Vp->xyz[1],&Vp->xyz[2]);
00203          Vp->xyz[0] += (dz*(j+1))*dr[0];  // shift in direction of edge
00204          Vp->xyz[1] += (dz*(j+1))*dr[1];
00205          Vp->xyz[2] += (dz*(j+1))*dr[2];
00206        }
00207        LastV += Dn;
00208        dmap += ddmap;
00209      }
00210    }
00211    /* set curve now as selected  everything else deselected*/
00212    vp=0; while(vp < Nvert){
00213      Vp=(MainVp+vp);
00214      if(Vp->status == SELECTED){
00215        Vp->status=DESELECTED; NvertSelect--; NvertDeselect++;
00216      }
00217      vp++;
00218    }
00219    for(i=0;i<=Npath;i++)if((MainVp+va[i])->status == DESELECTED){
00220      (MainVp+va[i])->status=SELECTED;
00221      NvertSelect++; NvertDeselect--;
00222    }
00223  }
00224  EXIT:
00225  X__Free(va);
00226  SetCursor(hSave);
00227  return TRUE;
00228 }
00229 
00230 static BOOL CALLBACK TwistAlongDlgProc(HWND hwnd, UINT msg,
00231                              WPARAM wparam, LPARAM lparam){
00232  char tempstr[16];
00233  BOOL err;
00234  int i;
00235  struct np {int nstep; double repeat_map,angle; BOOL Xtrude;} *dp;
00236  switch( msg ) {
00237    case WM_INITDIALOG:{
00238        SetWindowLong(hwnd,GWL_USERDATA,lparam);
00239        dp=(struct np *)lparam;
00240        SetDlgItemInt(hwnd,DLG_TWIST_STEP,dp->nstep,FALSE);
00241        sprintf(tempstr,"%.0lf",dp->angle);
00242        SendDlgItemMessage(hwnd,DLG_TWIST_ANGLE,WM_SETTEXT,0,(LPARAM)tempstr);
00243        SendDlgItemMessage(hwnd,DLG_TWIST_ANGLE,EM_LIMITTEXT,(WPARAM)12,0);
00244        sprintf(tempstr,"%.4lf",dp->repeat_map);
00245        SendDlgItemMessage(hwnd,DLG_TWIST_MAP,WM_SETTEXT,0,(LPARAM)tempstr);
00246        SendDlgItemMessage(hwnd,DLG_TWIST_MAP,EM_LIMITTEXT,(WPARAM)12,0);
00247        if(dp->Xtrude)
00248          SendDlgItemMessage(hwnd,DLG_TWIST_EXTRUDE,BM_SETCHECK,TRUE,0);
00249        else
00250          SendDlgItemMessage(hwnd,DLG_TWIST_COPY,BM_SETCHECK,TRUE,0);
00251        CentreDlgOnS(hwnd);
00252      }
00253      return (TRUE);
00254    case WM_COMMAND:
00255       dp=(struct np *)GetWindowLong(hwnd,GWL_USERDATA);
00256       switch(LOWORD(wparam)){
00257         case IDCANCEL:
00258           EndDialog(hwnd,FAIL);
00259           return(TRUE);
00260         case IDOK:
00261           dp->nstep=GetDlgItemInt(hwnd,DLG_TWIST_STEP,&err,FALSE);
00262           if(GetDlgItemText(hwnd,DLG_TWIST_ANGLE,tempstr,10) == 0){
00263             EndDialog(hwnd, FAIL);
00264             return(TRUE);
00265           }
00266           if((dp->angle=atof(tempstr)) == 0){
00267             EndDialog(hwnd, FAIL);
00268             return(TRUE);
00269           }
00270           if(GetDlgItemText(hwnd,DLG_TWIST_MAP,tempstr,10) == 0){
00271             EndDialog(hwnd, FAIL);
00272             return(TRUE);
00273           }
00274           if((dp->repeat_map=atof(tempstr)) == 0){
00275             EndDialog(hwnd, FAIL);
00276             return(TRUE);
00277           }
00278           if(SendDlgItemMessage(hwnd,DLG_TWIST_EXTRUDE,BM_GETCHECK,0,0))
00279                dp->Xtrude=TRUE;
00280           else dp->Xtrude=FALSE;
00281           EndDialog(hwnd,1);
00282           return(TRUE);
00283         default:
00284           break;
00285       }
00286       break;
00287     default: break;
00288  }
00289  return(FALSE);
00290 }
Generated on Tue Jan 28 06:18:29 2014 for OpenFX by  doxygen 1.6.3