00001
00002
00003
00004
00005
00006
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){
00135 l=0.0; ll=0.0;
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++){
00147
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){
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++){
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++){
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];
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
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 }