00001
00002
00003
00004
00005
00006
00007
00008 #define MODULE_TOOLS1 1
00009
00010 #include "design.h"
00011
00012 #define TIME_DELAY 30
00013
00014 typedef struct XTRAEDGE {
00015 int ep;
00016 int nc;
00017 } xtraedge;
00018
00019 typedef struct VERTEXVERTEXEDGE {
00020 int vs,vd;
00021 } vertexvertexedge;
00022
00023 long PrimitiveType = 0;
00024
00025 long LastToolVertex = -1;
00026
00027 static void PullMagnet(void);
00028 static void Edge3d(void);
00029 static void Plot3d(void);
00030 static void Grab(void);
00031 static void Shape(void);
00032 static void ShapeShape(int id);
00033 static void FormerDown(void);
00034 static void FormerUp(void);
00035 static void FormerMove(void);
00036 static void ShearerDown(void);
00037 static void ShearerUp(void);
00038 static void ShearerMove(int x, int y);
00039 static void Ixpand(void);
00040 static void Irotate(void);
00041 static void Casteljau(point p, long *Vc, long i, long j, double mu);
00042 static int GetGrabberBoundingBox(int flag);
00043 static void DrawIrotateBoundBox(int i, double theta);
00044 static void RotatePointAbout(long x, long y, long X, long Y, long *tx,
00045 long *ty, double ctheta, double stheta);
00046
00047 static int x_down,y_down;
00048 static BOOL PrimitiveActive=FALSE,Mxpand=FALSE,IxpandFlag=FALSE,
00049 JxpandFlag=FALSE,bFlagNotool=FALSE,bFlagMoved=FALSE,
00050 bFlagNurbs=FALSE;
00051 static long VertexCount1[50],VertexCount2[50];
00052 static long GrabonX,GrabonY,GrabonZ,GrabDx,GrabDy,GrabDz,
00053 grab_xmin,grab_ymin,grab_zmin,
00054 grab_xmax,grab_ymax,grab_zmax;
00055 static double RotatorTheta=0.0;
00056 static double shaper_angle_phi=0.0,shaper_angle_theta=0.0,shaper_size=6;
00057 static point *shaper_list=NULL;
00058 static BOOL bShaperMoved=FALSE;
00059 static unsigned char PrimitiveFaceColour[3]={164,164,164};
00060
00061 static void Casteljau(point p, long *Vc, long i, long j, double mu){
00062 vertex *va,*va1;
00063 point p1,p2;
00064 if(j == 1){
00065 va=(MainVp+(*(Vc+i))); va1=(MainVp+(*(Vc+i+1)));
00066 p[0] = (long)((1.0 - mu)*(double)(va->xyz[0])
00067 + mu*(double)(va1->xyz[0]));
00068 p[1] = (long)((1.0 - mu)*(double)(va->xyz[1])
00069 + mu*(double)(va1->xyz[1]));
00070 p[2] = (long)((1.0 - mu)*(double)(va->xyz[2])
00071 + mu*(double)(va1->xyz[2]));
00072 }
00073 else{
00074 Casteljau(p1,Vc,i,j-1,mu);
00075 Casteljau(p2,Vc,i+1,j-1,mu);
00076 p[0]=(long)((1.0 - mu)*(double)p1[0] + mu*(double)p2[0]);
00077 p[1]=(long)((1.0 - mu)*(double)p1[1] + mu*(double)p2[1]);
00078 p[2]=(long)((1.0 - mu)*(double)p1[2] + mu*(double)p2[2]);
00079 }
00080 }
00081
00082 void RecalibrateBezier(int id){
00083 long i,N,Npath;
00084 double mu;
00085 point p;
00086 N=Bcurves[id].Np-1;
00087 Npath=Bcurves[id].Nc;
00088 for(i=1;i<N;i++){
00089 mu=(double)i/(double)N;
00090 Casteljau(p,Bcurves[id].Vc,0,Npath-1,mu);
00091 (MainVp+Bcurves[id].Vp[i])->xyz[0]=p[0];
00092 (MainVp+Bcurves[id].Vp[i])->xyz[1]=p[1];
00093 (MainVp+Bcurves[id].Vp[i])->xyz[2]=p[2];
00094 }
00095 }
00096
00097 void RecalibrateAllBezier(void){
00098 int i;
00099 if(N_Bcurves == 0)return;
00100 for(i=0;i<N_Bcurves;i++)RecalibrateBezier(i);
00101 }
00102
00103 void MakeBezierCurve(void){
00104 HCURSOR hSave;
00105 vertex *Vp;
00106 long vp,vf,*va;
00107 long Npath,i,N;
00108 double mu;
00109 point p;
00110 bezier_curve *bc;
00111 if(NvertSelect<4)return;
00112 if((vf=get_closest_vertex()) < 0)return;
00113 N=RequestNumEntry(10,3,100,"No. of Edges"," Edges");
00114 if(N < 4)return;
00115 hSave=SetCursor(ghcurWait);
00116
00117
00118 if((va=(long *)X__Malloc(NvertSelect*sizeof(long))) == NULL){
00119 SetCursor(hSave);
00120 SendPrgmQuery(IDQ_NOMEM2,0);
00121 return;
00122 }
00123 Save_Undo(0);
00124 Npath=0; va[0]=vf; (MainVp+va[0])->id=1; i=NvertSelect-1;
00125 vp=0; while(vp < Nvert){
00126 Vp=(MainVp+vp);
00127 if(Vp->status == SELECTED && Vp->id == 0 && connected(va[Npath],vp)){
00128 Npath++;
00129 va[Npath]=vp;
00130 Vp->id=1;
00131 i--;
00132 vp=0;
00133 }
00134 else vp++;
00135 }
00136 Npath++;
00137 if(i != 0 || Npath > 9){
00138 SendPrgmQuery(IDQ_NOTSUITABLECURVE,0);
00139 goto EXIT;
00140 }
00141 if(Npath > 3){
00142 if(N_Bcurves == 0)bc=(bezier_curve *)X__Malloc(sizeof(bezier_curve));
00143 else bc=(bezier_curve *)X__Realloc(Bcurves,sizeof(bezier_curve)*(N_Bcurves+1));
00144 if(bc == NULL){
00145 SendPrgmQuery(IDQ_NOMEM2,0);
00146 goto EXIT;
00147 }
00148 Bcurves=bc; bc = &Bcurves[N_Bcurves];
00149 sprintf(bc->name,"C-%ld",N_Bcurves);
00150 if((bc->Vc = (long *)X__Malloc(Npath*sizeof(long))) == NULL){
00151 SendPrgmQuery(IDQ_NOMEM2,0);
00152 goto EXIT;
00153 }
00154 if((bc->Vp = (long *)X__Malloc((N+1)*sizeof(long))) == NULL){
00155 X__Free(bc->Vc);
00156 SendPrgmQuery(IDQ_NOMEM2,0);
00157 goto EXIT;
00158 }
00159 N_Bcurves++; bc->Nc=Npath; bc->Np=N+1;
00160 for(i=0;i<Npath;i++)bc->Vc[i] = va[i];
00161 if(!UpdateVertexHeap(Nvert+N-1)){
00162 SendPrgmQuery(IDQ_NOMEM2,0);
00163 goto EXIT;
00164 }
00165 if(!UpdateEdgeHeap(Nedge+N+1)){
00166 SendPrgmQuery(IDQ_NOMEM2,0);
00167 goto EXIT;
00168 }
00169 for(i=1;i<N;i++){
00170 mu=(double)i/(double)N;
00171 Casteljau(p,va,0,Npath-1,mu);
00172 CreateVertex();
00173 bc->Vp[i]=Nvert-1;
00174 if(i == 1)CreateEdge(va[0],Nvert-1);
00175 else CreateEdge(Nvert-1,Nvert-2);
00176 Vp=(MainVp+Nvert-1);
00177 Vp->xyz[0]=p[0]; Vp->xyz[1]=p[1]; Vp->xyz[2]=p[2];
00178 }
00179 CreateEdge(Nvert-1,va[Npath-1]);
00180 bc->Vp[0]=va[0];
00181 bc->Vp[N]=va[Npath-1];
00182 RequestCharString(6,bc->name,"Curve ID",ghwnd_main);
00183 }
00184 EXIT:
00185 SetCursor(hSave);
00186 X__Free(va);
00187 DrawModel(); UpdateCounters();
00188 return;
00189 }
00190
00191 int AddFace(void){
00192 vertex *vp;
00193 long Nvs,vps0,vps1,vpn[3];
00194 edge *ep;
00195 int i,count1,count2,j,k,l,c;
00196 if( (NvertSelect < 2) || (NvertSelect > 3))return 0;
00197 Nvs=Nvert;
00198 vp=MainVp; i=0;
00199 for(vp=MainVp,c=0;c<Nvert;c++,vp++){
00200 if(vp->status == SELECTED){
00201 vpn[i++]=(long)c;
00202 if( i > NvertSelect)break;
00203 }
00204 }
00205 if(i == 2)i=1;
00206 else i=3;
00207 for(l=0;l<i;l++){
00208 if (l == 0){vps0=vpn[0]; vps1=vpn[1];}
00209 else if(l == 1){vps0=vpn[1]; vps1=vpn[2];}
00210 else if(l == 2){vps0=vpn[2]; vps1=vpn[0];}
00211 ep=MainEp; count1=0; count2=0;
00212 for(c=0;c<Nedge;c++){
00213 if(ep->V[0] == vps0){VertexCount1[count1]=ep->V[1];count1++;}
00214 if(ep->V[1] == vps0){VertexCount1[count1]=ep->V[0];count1++;}
00215 if(ep->V[0] == vps1){VertexCount2[count2]=ep->V[1];count2++;}
00216 if(ep->V[1] == vps1){VertexCount2[count2]=ep->V[0];count2++;}
00217 ep++;
00218 }
00219 if((count1 > 0) && (count2 > 0)){
00220 for(j=0;j<count1;j++)for(k=0;k<count2;k++){
00221 if(VertexCount1[j] == VertexCount2[k]){
00222 if(!CheckFaceExists(vps0,vps1,VertexCount1[j],0)){
00223 UpdateFaceHeap(Nface+1);
00224 CreateFace(vps0,vps1,VertexCount1[j]);
00225 }
00226 }
00227 }
00228 }
00229 if(!CheckEdgeExists(vps0,vps1,0)){
00230 UpdateEdgeHeap(Nedge+1);
00231 CreateEdge(vps0,vps1);
00232 DrawOneEdgeOnly((MainVp+vps0),(MainVp+vps1));
00233 }
00234 }
00235 return 1;
00236 }
00237
00238 void ToolDown(HWND hwnd, int av, int x, int y){
00239 bFlagMoved=FALSE;
00240 x_down=x; y_down=y;
00241 if(tool == NOTOOL || tool == NODETOOL){
00242 long Vid;
00243 if(SelectedBrush >= 0)GrabBrushPoint(x,y);
00244 else if(SelectedShader >= 0)GrabMaterialAxisPoint(x,y);
00245 else if(tool == NOTOOL){
00246 if(GetAsyncKeyState(VK_CONTROL) & 0x8000){;}
00247 else if((Vid=PickVertex()) >= 0){
00248 SelectConnectedTo(Vid);
00249 Empty_Undo();
00250 }
00251 else SelectNurbsPatch(av,x,y);
00252 }
00253 else if(tool == NODETOOL){
00254 bFlagNotool=FALSE;
00255 bFlagNurbs=FALSE;
00256 if((LastToolVertex=PickVertex()) >= 0){
00257 Empty_Undo();
00258 if((MainVp+LastToolVertex)->status == SELECTED)bFlagNotool=TRUE;
00259 }
00260 else if(GetAsyncKeyState(VK_LBUTTON) & 0x8000){
00261 if(SelectNurbsControlPoint(av,x,y)){
00262 bFlagNurbs=TRUE;
00263 bFlagNotool=TRUE;
00264 MoveNurbsControlPoint(av,x,y,1);
00265 }
00266 else if(GetAsyncKeyState(VK_LBUTTON) & 0x8000){
00267 if(GetAsyncKeyState(VK_MENU) & 0x8000)tool=DESELECTOR;
00268 else tool=SELECTOR;
00269 bFlagNotool=TRUE;
00270 SelectorDown(hwnd,av,x,y);
00271 }
00272 }
00273 }
00274 }
00275 else if(tool == SELECTOR || tool == DESELECTOR){
00276 SelectorDown(hwnd,av,x,y);
00277 }
00278 else if(tool == GRABBER){
00279 GrabOn();
00280 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,
00281 grab_xmax,grab_ymax,grab_zmax);
00282 MoveNurbsSurface(av,x,y,1);
00283 }
00284 else if(tool == EXPANDER || tool == ROTATOR){
00285 IxpandFlag=FALSE;
00286 }
00287 else if(tool == PLOT3D || tool == BUILDER){
00288 point p;
00289 if(LastToolVertex >= 0){
00290 p[0]=GrabDx=NpointerX; p[1]=GrabDy=NpointerY; p[2]=GrabDz=NpointerZ;
00291 DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00292 }
00293 }
00294 else if(tool == PLOTTER){
00295 point p;
00296 if(GetAsyncKeyState(VK_MENU) & 0x8000){LastToolVertex = -1;}
00297 if(LastToolVertex >= 0){
00298 p[0]=GrabDx=NpointerX; p[1]=GrabDy=NpointerY; p[2]=GrabDz=NpointerZ;
00299 DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00300 }
00301 else if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000))ToolAction(x,y);
00302 }
00303 else if(tool == SHAPER){
00304 GrabonX=NpointerX; GrabonY=NpointerY; GrabonZ=NpointerZ;
00305 DrawShaperSphere(GrabonX,GrabonY,GrabonZ,
00306 shaper_angle_theta,shaper_angle_phi,shaper_size);
00307 FormerDown();
00308 }
00309 else if(tool == MAGNETTO){
00310 GrabonX=NpointerX; GrabonY=NpointerY; GrabonZ=NpointerZ;
00311 ShearerDown();
00312 }
00313 else if(tool == PRIMS){
00314 GrabDx=grab_xmin=grab_xmax=NpointerX;
00315 GrabDy=grab_ymin=grab_ymax=NpointerY;
00316 GrabDz=grab_zmin=grab_zmax=NpointerZ;
00317 SendMessage(ghwndDlgPrimitives,WM_INTERROGATE,0,0);
00318 PrimitiveActive=FALSE;
00319 }
00320 else if(sktool == YES)SkToolDown(x,y);
00321 }
00322
00323 void ToolUp(HWND hwnd, int av, int x, int y){
00324 if(tool == NOTOOL || tool == NODETOOL){
00325 if(SelectedBrush >= 0)UnGrabBrushPoint();
00326 else if(SelectedShader >= 0)UnGrabMaterialAxisPoint();
00327 else if(tool == NODETOOL && bFlagNurbs){
00328 bFlagNotool=FALSE; bFlagNurbs=FALSE;
00329 MoveNurbsControlPoint(av,x,y,-1);
00330 DrawModel();
00331 }
00332 else if(tool == NODETOOL && LastToolVertex >= 0){
00333 if(bFlagNotool && bFlagMoved){
00334 DrawRubberLines(hwnd,av,-2,x,y);
00335 DrawModel();
00336 }
00337 else {
00338 vertex *vf;
00339 vf=(MainVp+LastToolVertex);
00340 if(vf->status==SELECTED){
00341 NvertSelect--; NvertDeselect++; vf->status=DESELECTED;
00342 }
00343 else{
00344 NvertSelect++; NvertDeselect--; vf->status=SELECTED;
00345 }
00346 DrawVerticesOnly(vf); UpdateCounters();
00347 }
00348 bFlagNotool=FALSE; LastToolVertex= -1;
00349 }
00350 }
00351 else if(tool == SELECTOR || tool == DESELECTOR){
00352 SelectorUp(hwnd,av,x,y,bFlagMoved,bFlagNotool);
00353 if(bFlagNotool){
00354 tool=NODETOOL; bFlagNotool=FALSE;
00355 }
00356 }
00357 else if(tool == GRABBER){
00358 MoveNurbsSurface(av,x,y,-1);
00359 Grab();
00360 }
00361 else if(tool == PLOT3D || tool == BUILDER){
00362 point p;
00363 if(LastToolVertex >= 0){
00364 p[0]=GrabDx=NpointerX; p[1]=GrabDy=NpointerY; p[2]=GrabDz=NpointerZ;
00365 DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00366 }
00367 }
00368 else if(tool == PLOTTER){
00369 point p;
00370 if(LastToolVertex >= 0){
00371 vertex *vf;
00372 int ix,jy;
00373 vf=(MainVp+LastToolVertex);
00374 p[0]=GrabDx=NpointerX; p[1]=GrabDy=NpointerY; p[2]=GrabDz=NpointerZ;
00375 DrawRubber3dLine(vf->xyz,p);
00376 GetWindowCoords(ActiveView,vf->xyz[0],vf->xyz[1],vf->xyz[2],&ix,&jy);
00377 if(GetAsyncKeyState(VK_CONTROL) & 0x8000){;}
00378 else if(abs(x-ix) >2 || abs(y-jy) > 2)ToolAction(x,y);
00379 }
00380 }
00381 else if(tool == PRIMS){
00382 if(PrimitiveActive){
00383 PrimitiveActive=FALSE;
00384 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,
00385 grab_xmax,grab_ymax,grab_zmax);
00386 UpdatePrimitiveStructure(PrimitiveType,ActiveView,
00387 grab_xmin,grab_ymin,grab_zmin,
00388 grab_xmax,grab_ymax,grab_zmax,
00389 GrabDx,GrabDy,GrabDz);
00390 if(IsWindow(ghwndDlgPrimitives)){
00391 SendMessage(ghwndDlgPrimitives,WM_UPDATEPDIALOG,0,0);
00392 if(PrimStruct.auto_interactive)
00393 SendMessage(ghwndDlgPrimitives,WM_COMMAND,(WPARAM)IDOK,0);
00394 }
00395 }
00396 }
00397 else if(tool == EXPANDER || tool == ROTATOR){
00398 IxpandFlag=FALSE;
00399 }
00400 else if(tool == SHAPER){
00401 DrawShaperSphere(GrabonX,GrabonY,GrabonZ,
00402 shaper_angle_theta,shaper_angle_phi,shaper_size);
00403 FormerUp();
00404 }
00405 else if(tool == MAGNETTO){
00406 ShearerUp();
00407 }
00408 else if(sktool == YES)SkToolUp(x,y);
00409 if(tool == EXPANDER || tool == ROTATOR || tool == GRABBER ||
00410 tool == NODETOOL){
00411 if(ghwndOpenGLview == NULL)Draw3dView(0,0);
00412 else PostMessage(ghwndOpenGLview,(WM_USER+2),0,0);
00413 }
00414 return;
00415 }
00416
00417 void ToolMove(HWND hwnd, int av, int x, int y){
00418 point p;
00419 int flag=0;
00420 POINT pt;
00421 if(!bFlagMoved && abs(x-x_down) < 2 && abs(y-y_down) < 2)return;
00422 if(tool == NOTOOL || tool == NODETOOL){
00423 if(SelectedBrush >= 0)PullBrushPoint(x,y);
00424 else if(SelectedShader >= 0)PullShaderPoint(x,y);
00425 else if(tool == NODETOOL && bFlagNurbs){
00426 MoveNurbsControlPoint(av,x,y,0);
00427 }
00428 else if(tool == NODETOOL && LastToolVertex >= 0 && bFlagNotool){
00429 if(bFlagMoved)DrawRubberLines(hwnd,av,-1,x,y);
00430 else DrawRubberLines(hwnd,av,LastToolVertex,x,y);
00431 }
00432 }
00433 else if(tool == SELECTOR || tool == DESELECTOR){
00434 SelectorMove(hwnd,av,x,y);
00435 }
00436 else if(tool == GRABBER){
00437 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,grab_xmax,grab_ymax,grab_zmax);
00438 grab_xmin += (NpointerX-GrabDx); grab_xmax += (NpointerX-GrabDx);
00439 grab_ymin += (NpointerY-GrabDy); grab_ymax += (NpointerY-GrabDy);
00440 grab_zmin += (NpointerZ-GrabDz); grab_zmax += (NpointerZ-GrabDz);
00441 GrabDx=NpointerX; GrabDy=NpointerY; GrabDz=NpointerZ;
00442 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,grab_xmax,grab_ymax,grab_zmax);
00443 MoveNurbsSurface(av,x,y,0);
00444 }
00445 else if(tool == PLOTTER){
00446 Move3dCursor(0,x,y);
00447 if (x > WindowSizeX[ActiveView] - 4){
00448 flag=1; SendMessage(ghwnd_main,WM_COMMAND,IDM_PAN_RIGHT1,ActiveView);
00449 }
00450 else if(x < 4){
00451 flag=1; SendMessage(ghwnd_main,WM_COMMAND,IDM_PAN_LEFT1,ActiveView);
00452 }
00453 else if(y < 4){
00454 flag=1; SendMessage(ghwnd_main,WM_COMMAND,IDM_PAN_UP1,ActiveView);
00455 }
00456 else if(y > WindowSizeY[ActiveView] - 4){
00457 flag=1; SendMessage(ghwnd_main,WM_COMMAND,IDM_PAN_DOWN1,ActiveView);
00458 }
00459 if(flag){
00460 GetWindowCoords(ActiveView,NpointerX,NpointerY,NpointerZ,&x,&y);
00461 pt.x=x; pt.y=y;
00462 ClientToScreen(ghwnd_current,&pt);
00463 SetCursorPos(pt.x,pt.y);
00464 }
00465 if(LastToolVertex >= 0){
00466 if(!flag){
00467 p[0]=GrabDx; p[1]=GrabDy; p[2]=GrabDz;
00468 DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00469 }
00470 p[0]=GrabDx=NpointerX; p[1]=GrabDy=NpointerY; p[2]=GrabDz=NpointerZ;
00471 DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00472 }
00473 }
00474 else if(tool == PLOT3D || tool == BUILDER){
00475 if(LastToolVertex >= 0){
00476 p[0]=GrabDx; p[1]=GrabDy; p[2]=GrabDz;
00477 DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00478 p[0]=GrabDx=NpointerX; p[1]=GrabDy=NpointerY; p[2]=GrabDz=NpointerZ;
00479 DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00480 }
00481 }
00482 else if(tool == PRIMS){
00483 long d,dx,dy,dz;
00484 if(PrimitiveActive){
00485 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,
00486 grab_xmax,grab_ymax,grab_zmax);
00487 }
00488 else PrimitiveActive=TRUE;
00489 if(ActiveView == TRITOP)
00490 d=max(labs(GrabDx-NpointerX),labs(GrabDy-NpointerY));
00491 if(ActiveView == TRIFRONT)
00492 d=max(labs(GrabDx-NpointerX),labs(GrabDz-NpointerZ));
00493 if(ActiveView == TRIRIGHT)
00494 d=max(labs(GrabDy-NpointerY),labs(GrabDz-NpointerZ));
00495 if(PrimitiveType == 0){
00496 if (ActiveView == TRITOP){
00497 dx=NpointerX-GrabDx; dy=NpointerY-GrabDy; dz=0;
00498 }
00499 else if(ActiveView == TRIFRONT){
00500 dx=NpointerX-GrabDx; dy=0; dz=NpointerZ-GrabDz;
00501 }
00502 else{
00503 dx=0; dy=NpointerY-GrabDy; dz=NpointerZ-GrabDz;
00504 }
00505 grab_xmin=GrabDx; grab_xmax=GrabDx+dx;
00506 grab_ymin=GrabDy; grab_ymax=GrabDy+dy;
00507 grab_zmin=GrabDz; grab_zmax=GrabDz+dz;
00508 }
00509 else{
00510 dx=dy=dz=d;
00511 if(PrimitiveType == 2 || PrimitiveType == 4){
00512 if (ActiveView == TRITOP)dz=0;
00513 else if(ActiveView == TRIFRONT)dy=0;
00514 else dx=0;
00515 }
00516 else if(PrimitiveType != 7 && PrimitiveType != 8 && PrimitiveType != 9){
00517 if(GetAsyncKeyState(VK_CONTROL) & 0x8000){
00518 if (ActiveView == TRITOP)dz=GrabDz-grab_zmin;
00519 else if(ActiveView == TRIFRONT)dy=GrabDy-grab_ymin;
00520 else dx=GrabDx-grab_xmin;
00521 }
00522 }
00523 grab_xmin=GrabDx-dx; grab_xmax=GrabDx+dx;
00524 grab_ymin=GrabDy-dy; grab_ymax=GrabDy+dy;
00525 grab_zmin=GrabDz-dz; grab_zmax=GrabDz+dz;
00526 }
00527 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,
00528 grab_xmax,grab_ymax,grab_zmax);
00529 }
00530 else if(tool == EXPANDER || tool == ROTATOR){
00531 RotatorTheta=0.0;
00532 if(!IxpandFlag){
00533 IxpandFlag=TRUE;
00534 if(GetGrabberBoundingBox(0) == 0){
00535 grab_xmin=grab_xmax=NpointerX;
00536 grab_ymin=grab_ymax=NpointerY;
00537 grab_zmin=grab_zmax=NpointerZ;
00538 }
00539 if(tool == ROTATOR){
00540 DrawIrotateBoundBox(ActiveView,RotatorTheta);
00541 RotateNurbsSurface(av,1,0.0);
00542 }
00543 else{
00544 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,
00545 grab_xmax,grab_ymax,grab_zmax);
00546 XpandNurbsSurface(av,1,0.0,0.0,0.0);
00547 }
00548 if(tool == EXPANDER)Ixpand();
00549 else Irotate();
00550 }
00551 }
00552 else if(tool == SHAPER){
00553 if (GetAsyncKeyState(VK_CONTROL) & 0x8000)ShapeShape(0);
00554
00555
00556 else{
00557 Move3dCursor(0,x,y);
00558 DrawShaperSphere(GrabonX,GrabonY,GrabonZ,
00559 shaper_angle_theta,shaper_angle_phi,shaper_size);
00560
00561 FormerMove();
00562 DrawShaperSphere(GrabonX,GrabonY,GrabonZ,
00563 shaper_angle_theta,shaper_angle_phi,shaper_size);
00564 }
00565 }
00566 else if(tool == MAGNETTO){
00567 ShearerMove(x,y);
00568 }
00569 else if(sktool == YES)SkToolMove(x,y);
00570 bFlagMoved=TRUE;
00571 return;
00572 }
00573
00574 void ToolAction(int x, int y){
00575 if (tool == PLOT3D)Plot3d();
00576 else if(tool == PLOTTER)Plot3d();
00577 else if(tool == BUILDER)Edge3d();
00578
00579
00580 else if(sktool == YES){;}
00581 return;
00582 }
00583
00584 static int GetGrabberBoundingBox(int flag){
00585 int i;
00586 vertex *vp;
00587 grab_xmin=grab_ymin=grab_zmin = MAXUNIT;
00588 grab_xmax=grab_ymax=grab_zmax = -MAXUNIT;
00589 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++){
00590 if(vp->status == SELECTED){
00591 if(vp->xyz[0] > grab_xmax)grab_xmax=vp->xyz[0];
00592 if(vp->xyz[0] < grab_xmin)grab_xmin=vp->xyz[0];
00593 if(vp->xyz[1] > grab_ymax)grab_ymax=vp->xyz[1];
00594 if(vp->xyz[1] < grab_ymin)grab_ymin=vp->xyz[1];
00595 if(vp->xyz[2] > grab_zmax)grab_zmax=vp->xyz[2];
00596 if(vp->xyz[2] < grab_zmin)grab_zmin=vp->xyz[2];
00597 flag=1;
00598 }
00599 vp++;
00600 }
00601 return flag;
00602 }
00603
00604 void GrabOn(void){
00605 int flag=0;
00606 GrabonX=NpointerX; GrabonY=NpointerY; GrabonZ=NpointerZ;
00607 GrabDx=NpointerX; GrabDy=NpointerY; GrabDz=NpointerZ;
00608 flag=GetGrabberBoundingBox(flag);
00609 if(flag == 0){
00610 grab_xmin=grab_xmax=NpointerX;
00611 grab_ymin=grab_ymax=NpointerY;
00612 grab_zmin=grab_zmax=NpointerZ;
00613 }
00614 }
00615
00616 static void Grab(void){
00617 vertex *vp;
00618 long i,dx,dy,dz;
00619 dx=NpointerX-GrabonX; dy=NpointerY-GrabonY; dz=NpointerZ-GrabonZ;
00620 vp=MainVp; for(i=0;i<Nvert;i++){
00621 if(vp->status == SELECTED){
00622 vp->xyz[0] += dx;
00623 vp->xyz[1] += dy;
00624 vp->xyz[2] += dz;
00625 }
00626 vp++;
00627 }
00628 GrabDx=GrabonX=NpointerX;
00629 GrabDy=GrabonY=NpointerY;
00630 GrabDz=GrabonZ=NpointerZ;
00631 RecalibrateAllBezier(); RecalibrateMapLocks();
00632 do_NOT_abort=TRUE;
00633 DrawModel();
00634 if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,(WM_USER+2),0,0);
00635 do_NOT_abort=FALSE;
00636 }
00637
00638 BOOL PrimitiveOn(void){
00639 int i;
00640 PrimitiveActive=FALSE;
00641 PrimStruct.auto_interactive=TRUE;
00642 PrimStruct.nsides=12;
00643 PrimStruct.nsteps=1;
00644 PrimStruct.smooth=1;
00645 PrimStruct.faces=320;
00646 PrimStruct.nvert=9;
00647 PrimStruct.nhorz=16;
00648 PrimStruct.torus_ratio=0.5;
00649 for(i=0;i<3;i++)PrimStruct.fc[i]=PrimitiveFaceColour[i];
00650 PrimitiveType=0;
00651 UpdatePrimitiveStructure(0,ActiveView,
00652 TVcentreX-TVsizeX/2,
00653 TVcentreY-TVsizeY/2,
00654 TVcentreZ-TVsizeZ/2,
00655 TVcentreX+TVsizeX/2,
00656 TVcentreY+TVsizeY/2,
00657 TVcentreZ+TVsizeZ/2,
00658 TVcentreX,TVcentreY,TVcentreZ);
00659 ghwndDlgPrimitives=CreateDialog(ghinst_main,MAKEINTRESOURCE(DLG_TAB_PRIMES),
00660 ghwnd_main,(DLGPROC)PrimitivesDlgProc);
00661 return TRUE;
00662 }
00663
00664 void PrimitiveOff(void){
00665 int i;
00666 PrimitiveActive=FALSE;
00667 for(i=0;i<3;i++)PrimitiveFaceColour[i]=PrimStruct.fc[i];
00668 if(IsWindow(ghwndDlgPrimitives))DestroyWindow(ghwndDlgPrimitives);
00669 ghwndDlgPrimitives=NULL;
00670 }
00671
00672 void Plot3dOn(void){
00673 LastToolVertex = -1;
00674 }
00675
00676 void Plot3dOff(void){
00677 LastToolVertex = -1;
00678 }
00679
00680 void IxpandOn(void){
00681 Mxpand=FALSE;
00682 IxpandFlag=FALSE;
00683 GrabonX=NpointerX; GrabonY=NpointerY; GrabonZ=NpointerZ;
00684 }
00685
00686 void IrotateOn(void){
00687 Mxpand=FALSE;
00688 IxpandFlag=FALSE;
00689 RotatorTheta=0.0;
00690 GrabonX=NpointerX; GrabonY=NpointerY; GrabonZ=NpointerZ;
00691 }
00692
00693 static void Plot3d(void){
00694 int vp,vps[3];
00695 edge *Ep;
00696 int ep;
00697 int count1,count2,j,k;
00698 point p;
00699 p[0]=GrabDx; p[1]=GrabDy; p[2]=GrabDz;
00700 if(LastToolVertex >= 0)DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00701 if( !(GetAsyncKeyState(VK_CONTROL) & 0x8000) && (vp=PickVertex()) >= 0
00702 && (MainVp+vp)->status == SELECTED){
00703 if(LastToolVertex >= 0 && LastToolVertex != vp){
00704 vps[0]=vp;
00705 vps[1]=LastToolVertex;
00706 count1=0; count2=0;
00707 ep=0; while(ep < Nedge){
00708 Ep=(MainEp+ep);
00709 if(Ep->V[0] == vps[0]){VertexCount1[count1]=Ep->V[1]; count1++;}
00710 if(Ep->V[1] == vps[0]){VertexCount1[count1]=Ep->V[0]; count1++;}
00711 if(Ep->V[0] == vps[1]){VertexCount2[count2]=Ep->V[1]; count2++;}
00712 if(Ep->V[1] == vps[1]){VertexCount2[count2]=Ep->V[0]; count2++;}
00713 ep++;
00714 }
00715 if((count1 > 0) && (count2 > 0)){
00716 for(j=0;j<count1;j++)for(k=0;k<count2;k++){
00717 if(VertexCount1[j] == VertexCount2[k]){
00718 if(!CheckFaceExists(vps[0],vps[1],VertexCount1[j],0)){
00719 UpdateFaceHeap(Nface+1);
00720 CreateFace(vps[0],vps[1],VertexCount1[j]);
00721 }
00722 }
00723 }
00724 }
00725 if(!CheckEdgeExists(vps[0],vps[1],0)){
00726 UpdateEdgeHeap(Nedge+1);
00727 CreateEdge(vps[0],vps[1]);
00728 DrawOneEdgeOnly((MainVp+vps[0]),(MainVp+vps[1]));
00729 }
00730 LastToolVertex=-1;
00731 }
00732 else LastToolVertex=vp;
00733 }
00734 else{
00735 UpdateVertexHeap(Nvert+1);
00736 CreateVertex();
00737 if(LastToolVertex >= 0){
00738 UpdateEdgeHeap(Nedge+1);
00739 CreateEdge(LastToolVertex,Nvert-1);
00740 DrawOneEdgeOnly((MainVp+LastToolVertex),(MainVp+Nvert-1));
00741 }
00742 else DrawVerticesOnly((MainVp+Nvert-1));
00743 LastToolVertex=Nvert-1;
00744 }
00745 p[0]=GrabDx=NpointerX; p[1]=GrabDy=NpointerY; p[2]=GrabDz=NpointerZ;
00746 if(LastToolVertex >= 0)DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00747 UpdateCounters();
00748 }
00749
00750 static void Edge3d(void){
00751 int vp,vps[3];
00752 edge *Ep;
00753 int ep;
00754 int count1,count2,j,k;
00755 point p;
00756 p[0]=GrabDx; p[1]=GrabDy; p[2]=GrabDz;
00757 if(LastToolVertex >= 0)DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00758 if((vp=PickVertex()) >= 0){
00759 if(LastToolVertex >= 0 && LastToolVertex != vp){
00760 vps[0]=vp;
00761 vps[1]=LastToolVertex;
00762 count1=0; count2=0;
00763 ep=0; while(ep < Nedge){
00764 Ep=(MainEp+ep);
00765 if(Ep->V[0] == vps[0]){VertexCount1[count1]=Ep->V[1]; count1++;}
00766 if(Ep->V[1] == vps[0]){VertexCount1[count1]=Ep->V[0]; count1++;}
00767 if(Ep->V[0] == vps[1]){VertexCount2[count2]=Ep->V[1]; count2++;}
00768 if(Ep->V[1] == vps[1]){VertexCount2[count2]=Ep->V[0]; count2++;}
00769 ep++;
00770 }
00771 if((count1 > 0) && (count2 > 0)){
00772 for(j=0;j<count1;j++)for(k=0;k<count2;k++){
00773 if(VertexCount1[j] == VertexCount2[k]){
00774 if(!CheckFaceExists(vps[0],vps[1],VertexCount1[j],0)){
00775 UpdateFaceHeap(Nface+1);
00776 CreateFace(vps[0],vps[1],VertexCount1[j]);
00777 }
00778 }
00779 }
00780 }
00781 if(!CheckEdgeExists(vps[0],vps[1],0)){
00782 UpdateEdgeHeap(Nedge+1);
00783 CreateEdge(vps[0],vps[1]);
00784 DrawOneEdgeOnly((MainVp+vps[0]),(MainVp+vps[1]));
00785 }
00786 LastToolVertex=-1;
00787 }
00788 else LastToolVertex=vp;
00789 }
00790 p[0]=GrabDx=NpointerX; p[1]=GrabDy=NpointerY; p[2]=GrabDz=NpointerZ;
00791 if(LastToolVertex >= 0)DrawRubber3dLine((MainVp+LastToolVertex)->xyz,p);
00792 UpdateCounters();
00793 }
00794
00795 static void PullMagnet(void){
00796 long i;
00797 vertex *vp;
00798 double dmin,dmax,d,mu;
00799 dmin=(double)MAXUNIT * (double)MAXUNIT;
00800 dmax=0.0;
00801 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++){
00802 if(vp->status == SELECTED){
00803 d = (double)(vp->xyz[0] - NpointerX)*(double)(vp->xyz[0] - NpointerX)
00804 + (double)(vp->xyz[1] - NpointerY)*(double)(vp->xyz[1] - NpointerY)
00805 + (double)(vp->xyz[2] - NpointerZ)*(double)(vp->xyz[2] - NpointerZ);
00806 d=sqrt(d);
00807 if(d < dmin)dmin=d;
00808 if(d > dmax)dmax=d;
00809 }
00810 vp++;
00811 }
00812 if(dmin <1.e-5)return;
00813 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++){
00814 if(vp->status == SELECTED){
00815 d = (double)(vp->xyz[0] - NpointerX)*(double)(vp->xyz[0] - NpointerX)
00816 + (double)(vp->xyz[1] - NpointerY)*(double)(vp->xyz[1] - NpointerY)
00817 + (double)(vp->xyz[2] - NpointerZ)*(double)(vp->xyz[2] - NpointerZ);
00818 d=sqrt(d);
00819 mu=1.0-(d-dmin)/(dmax-dmin);
00820 mu = mu*mu*mu;
00821 mu=mu/2;
00822 if(GetAsyncKeyState(VK_MENU) & 0x8000)mu *= -1.0;
00823 vp->xyz[0]=(long)((double)vp->xyz[0]+(double)(NpointerX-vp->xyz[0])*mu);
00824 vp->xyz[1]=(long)((double)vp->xyz[1]+(double)(NpointerY-vp->xyz[1])*mu);
00825 vp->xyz[2]=(long)((double)vp->xyz[2]+(double)(NpointerZ-vp->xyz[2])*mu);
00826 }
00827 vp++;
00828 }
00829 DrawModel();
00830 }
00831
00832 BOOL AddCopy(int wait){
00833 HCURSOR hSave;
00834 vertex *vp,*V0,*V1,*V2,*Vp;
00835 edge *ep;
00836 face *fp;
00837 long i,Nvert1,Nedge1,Nface1;
00838 long x,y,z;
00839 if(NvertSelect == 0)return FALSE;
00840 if(NvertSelect > 32000){
00841 SendPrgmQuery(IDQ_WIRETOOBIG,0);
00842 return FALSE;
00843 }
00844 if(wait)hSave=SetCursor(ghcurWait);
00845 if(!UpdateVertexHeap(Nvert+NvertSelect))return FALSE;
00846 for(Nedge1=0,ep=MainEp,i=0;i<Nedge;i++){
00847 V0=(MainVp+ep->V[0]); V1=(MainVp+ep->V[1]);
00848 if(V0->status == SELECTED && V1->status == SELECTED)Nedge1++;
00849 ep++;
00850 }
00851 if(!UpdateEdgeHeap(Nedge+Nedge1))return FALSE;
00852 for(Nface1=0,fp=MainFp,i=0;i<Nface;i++){
00853 V0=(MainVp+fp->V[0]); V1=(MainVp+fp->V[1]); V2=(MainVp+fp->V[2]);
00854 if(V0->status == SELECTED &&
00855 V1->status == SELECTED &&
00856 V2->status == SELECTED)Nface1++;
00857 fp++;
00858 }
00859 if(!UpdateFaceHeap(Nface+Nface1))return FALSE;
00860 Nvert1=Nvert; Nedge1=Nedge; Nface1=Nface;
00861 vp=MainVp; for(i=0;i<Nvert1;i++){
00862 if(vp->status == SELECTED){
00863 CreateVertex();
00864 Vp=(MainVp+Nvert-1);
00865 Vp->xyz[0]=vp->xyz[0];
00866 Vp->xyz[1]=vp->xyz[1];
00867 Vp->xyz[2]=vp->xyz[2];
00868 Vp->gp=vp->gp;
00869 if(Vp->gp == 1){
00870 Vp->x=vp->x;
00871 Vp->y=vp->y;
00872 }
00873 Vp->status=DESELECTED;
00874 vp->id=Nvert-1;
00875 NvertSelect--; NvertDeselect++;
00876 }
00877 else{
00878 vp->id = -1;
00879 }
00880 vp++;
00881 }
00882 if(Nedge > 0)for(ep=MainEp,i=0;i<Nedge1;i++){
00883 V0=(MainVp+ep->V[0]); V1=(MainVp+ep->V[1]);
00884 if(V0->status == SELECTED &&
00885 V1->status == SELECTED){
00886 CreateEdge(V0->id,V1->id);
00887 }
00888 ep++;
00889 }
00890 if(Nface > 0)for(fp=MainFp,i=0;i<Nface1;i++){
00891 V0=(MainVp+fp->V[0]); V1=(MainVp+fp->V[1]); V2=(MainVp+fp->V[2]);
00892 if(V0->status == SELECTED &&
00893 V1->status == SELECTED &&
00894 V2->status == SELECTED) {
00895 CreateFace(V0->id,V1->id,V2->id);
00896 CopyFaceProp(fp,(MainFp+Nface-1));
00897 }
00898 fp++;
00899 }
00900 vp=MainVp; for(i=0;i<Nvert1;i++){
00901 if(vp->status == SELECTED){
00902 vp->status=DESELECTED;
00903 (MainVp+vp->id)->status=SELECTED;
00904 }
00905 vp++;
00906 }
00907 if(wait) {
00908 SetCursor(hSave);
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923 }
00924 return TRUE;
00925 }
00926
00927 BOOL CreateAttachedCopy(int open){
00928
00929 vertex *Vp,*vp,*vl,*vr,*v0,*v1,*v2;
00930 edge *ep;
00931 face *fp;
00932 int ne,addit;
00933 long i,j,uuecount=0,k,Nvert1=0,Nedge1=0,Nface1=0;
00934 xtraedge *xp;
00935 vertexvertexedge *vve=NULL;
00936 if(NvertSelect > 32000 || Nvert < 1){ return FALSE; }
00937 ne=0; if(Nedge > 0)for(j=0,ep=MainEp;j<Nedge;j++,ep++){
00938 v0=(MainVp+ep->V[0]); v1=(MainVp+ep->V[1]);
00939 if(v0->status == SELECTED && v1->status == SELECTED)ne++;
00940 }
00941 Nvert1=NvertSelect;
00942 Nedge1=ne;
00943 if(ne > 0){
00944 xp=(xtraedge *)
00945 X__Malloc(ne*sizeof(xtraedge));
00946 if(xp == NULL){
00947 SendPrgmQuery(IDQ_NOMEM2,0);
00948 return FALSE;
00949 }
00950 i=0; ep=MainEp; for(j=0;j<Nedge;j++,ep++){
00951 v0=(MainVp+ep->V[0]); v1=(MainVp+ep->V[1]);
00952 if(v0->status == SELECTED && v1->status == SELECTED){
00953 xp[i].ep = j; xp[i].nc=0; i++;
00954 }
00955 }
00956 if(i != ne){
00957 SendPrgmQuery(IDQ_EDGEINCONSISTANT,0);
00958 X__Free(xp);
00959 return FALSE;
00960 }
00961 for(i=0;i<ne;i++){
00962 vl=(MainVp+(MainEp+xp[i].ep)->V[0]);
00963 vr=(MainVp+(MainEp+xp[i].ep)->V[1]);
00964 fp=MainFp; if(Nface > 0)for(j=0;j<Nface;j++,fp++){
00965 v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
00966 if(v0->status == SELECTED &&
00967 v1->status == SELECTED &&
00968 v2->status == SELECTED){
00969 if((vl == v0 && vr == v1) || (vl == v1 && vr == v0))xp[i].nc++;
00970 if((vl == v1 && vr == v2) || (vl == v2 && vr == v1))xp[i].nc++;
00971 if((vl == v2 && vr == v0) || (vl == v0 && vr == v2))xp[i].nc++;
00972 }
00973 }
00974 }
00975 }
00976 fp=MainFp; if(Nface > 0)for(i=0;i<Nface;i++,fp++){
00977 v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
00978 if(v0->status == SELECTED &&
00979 v1->status == SELECTED &&
00980 v2->status == SELECTED)Nface1++;
00981 }
00982 if(open == 2 && Nedge > 0){
00983 uuecount=0;
00984 for(i=0,ep=MainEp;i<Nedge;i++){
00985 v0=(MainVp+ep->V[0]); v1=(MainVp+ep->V[1]);
00986 if((v0->status == DESELECTED && v1->status == SELECTED) ||
00987 (v1->status == DESELECTED && v0->status == SELECTED))
00988 uuecount++;
00989 ep++;
00990 }
00991 if((vve=(vertexvertexedge *)X__Malloc(uuecount*sizeof(vertexvertexedge)))
00992 == NULL){
00993 open=1; uuecount=0;
00994 }
00995 else{
00996 uuecount=0;
00997 for(i=0,ep=MainEp;i<Nedge;i++){
00998 v0=(MainVp+ep->V[0]); v1=(MainVp+ep->V[1]);
00999 if((v0->status == DESELECTED && v1->status == SELECTED) ||
01000 (v1->status == DESELECTED && v0->status == SELECTED)){
01001 if(v0->status == SELECTED){
01002 vve[uuecount].vs=ep->V[0];
01003 vve[uuecount].vd=ep->V[1];
01004 }
01005 else{
01006 vve[uuecount].vs=ep->V[1];
01007 vve[uuecount].vd=ep->V[0];
01008 }
01009 uuecount++;
01010 }
01011 ep++;
01012 }
01013 }
01014 }
01015 if(!UpdateVertexHeap(Nvert+Nvert1))return FALSE;
01016 if(!UpdateEdgeHeap(Nedge+Nvert1+Nedge1*2+uuecount))return FALSE;
01017 if(!UpdateFaceHeap(Nface+Nface1+Nedge1*2+uuecount))return FALSE;
01018 Nvert1=Nvert; Nedge1=Nedge; Nface1=Nface;
01019 vp=MainVp; for(j=0;j<Nvert1;j++){
01020 if(vp->status == SELECTED) {
01021 addit=0;
01022 if(ne > 0)for(i=0;i<ne;i++){
01023 if((
01024 (MainEp+xp[i].ep)->V[0] == j || (MainEp+xp[i].ep)->V[1] == j)
01025 && (xp[i].nc < 2))addit=1;
01026 }
01027 else addit=1;
01028 CreateVertex();
01029 Vp=(MainVp+Nvert-1);
01030 Vp->xyz[0]=vp->xyz[0];
01031 Vp->xyz[1]=vp->xyz[1];
01032 Vp->xyz[2]=vp->xyz[2];
01033 Vp->gp=vp->gp;
01034 if(Vp->gp == 1){
01035 Vp->x=vp->x;
01036 Vp->y=vp->y;
01037 }
01038 if(addit)CreateEdge(j,Nvert-1);
01039 Vp->status=DESELECTED;
01040 vp->id=Nvert-1;
01041 NvertSelect--;NvertDeselect++;
01042 }
01043 vp++;
01044 }
01045 i=0; if(Nedge > 0)for(ep=MainEp,j=0;j<Nedge1;j++){
01046 v0=(MainVp+ep->V[0]); v1=(MainVp+ep->V[1]);
01047 if(v0->status == SELECTED &&
01048 v1->status == SELECTED){
01049 CreateEdge(v0->id,v1->id);
01050 if(xp[i].nc < 2){
01051 CreateEdge(v0->id,ep->V[1]);
01052 CreateFace(v0->id,v1->id,ep->V[1]);
01053 CreateFace(v0->id,ep->V[1],ep->V[0]);
01054 }
01055 i++;
01056 }
01057 ep++;
01058 }
01059 if(Nface1 > 0)for(fp=MainFp,j=0;j<Nface1;j++){
01060 v0=(MainVp+fp->V[0]); v1=(MainVp+fp->V[1]); v2=(MainVp+fp->V[2]);
01061 if(v0->status == SELECTED &&
01062 v1->status == SELECTED &&
01063 v2->status == SELECTED) {
01064 CreateFace(v0->id,v1->id,v2->id);
01065 CopyFaceProp(fp,(MainFp+Nface-1));
01066 }
01067 fp++;
01068 }
01069 if(open == 2 && uuecount > 0){
01070 for(i=0;i<uuecount;i++){
01071 k=(MainVp+vve[i].vs)->id;
01072 CreateEdge(vve[i].vd,k);
01073 CreateFace(vve[i].vd,vve[i].vs,k);
01074 }
01075 X__Free(vve);
01076 }
01077 vp=MainVp; for(j=0;j<Nvert1;j++){
01078 if(vp->status == SELECTED){
01079 vp->status=DESELECTED;
01080 (MainVp+vp->id)->status=SELECTED;
01081 }
01082 vp++;
01083 }
01084 UpdateFaceHeap(Nface);
01085 UpdateEdgeHeap(Nedge);
01086 if(ne > 0)X__Free(xp);
01087 return TRUE;
01088 }
01089
01090 BOOL Extrude(int command){
01091 HCURSOR hSave;
01092 static double dx_extrude=0.0,dy_extrude=0.0,dz_extrude=0.0;
01093 long Vstart,i,com,loop_count=1;
01094 double dmap=1.0;
01095 vertex *vp;
01096 long x,y,z;
01097 if(NvertSelect < 1)return FALSE;
01098 if(NvertSelect > 32000){
01099 SendPrgmQuery(IDQ_WIRETOOBIG,0);
01100 return FALSE;
01101 }
01102 Vstart=Nvert;
01103
01104
01105
01106
01107
01108
01109 hSave=SetCursor(ghcurWait);
01110
01111
01112 com=1;
01113 NEXT_LOOP:
01114 if(!CreateAttachedCopy(com)){
01115 SetCursor(hSave);
01116 return FALSE;
01117 }
01118 if(command == 0){
01119 if(Nvert > Vstart){
01120 for(i=Vstart,vp=(MainVp+Vstart);i<Nvert;i++,vp++){
01121 if(vp->status == SELECTED && vp->gp == 1){
01122 vp->y += 1.0;
01123 }
01124 }
01125 }
01126 return TRUE;
01127 }
01128 x=(long)(dx_extrude*ruler)+lrulerx;
01129 y=(long)(dy_extrude*ruler)+lrulery;
01130 z=(long)(dz_extrude*ruler)+lrulerz;
01131 if(Nvert > Vstart)for(i=Vstart,vp=(MainVp+Vstart);i<Nvert;i++,vp++){
01132 if(vp->status == SELECTED){
01133 vp->xyz[0] += x; vp->xyz[1] += y; vp->xyz[2] += z;
01134 if(vp->gp == 1){
01135 vp->y += dmap;
01136 }
01137 }
01138 }
01139 loop_count--; if(loop_count > 0)goto NEXT_LOOP;
01140 SetCursor(hSave);
01141 do_NOT_abort=TRUE;
01142 DrawModel();
01143 do_NOT_abort=FALSE;
01144 return FALSE;
01145 }
01146
01147 static void Ixpand(void){
01148 double s,sx,sy,sz,sxx,syy,szz;
01149 int x,xo,MickeyX,I,flag=0;
01150 POINT pt;
01151 long evTime;
01152 GetCursorPos(&pt); xo=pt.x;
01153 sxx=syy=szz=1.0;
01154 ClipCursor(NULL);
01155 if(!Mxpand){
01156 GrabonX=NpointerX; GrabonY=NpointerY; GrabonZ=NpointerZ;
01157 }
01158 evTime=GetTickCount()+TIME_DELAY;
01159 do {
01160 if(evTime > GetTickCount())continue;
01161 GetCursorPos(&pt); x=pt.x;
01162 MickeyX = x-xo; xo=x;
01163 if(MickeyX != 0){
01164 flag=1;
01165 if(MickeyX > 0)I=max( 1,min( 50,MickeyX));
01166 else I=min(-1,max(-50,MickeyX));
01167 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,
01168 grab_xmax,grab_ymax,grab_zmax);
01169 sx=sy=sz=1.0; s=(double)(I)/55.0;
01170 if (GetAsyncKeyState(VK_SHIFT) & 0x8000)sy += s;
01171 else if(GetAsyncKeyState(VK_CONTROL) & 0x8000)sz += s;
01172 else if(GetAsyncKeyState(VK_MENU) & 0x8000)sx += s;
01173 else {sx += s; sy += s; sz += s;}
01174 grab_xmin = (long)((double)(grab_xmin-GrabonX)*sx)+GrabonX;
01175 grab_xmax = (long)((double)(grab_xmax-GrabonX)*sx)+GrabonX;
01176 grab_ymin = (long)((double)(grab_ymin-GrabonY)*sy)+GrabonY;
01177 grab_ymax = (long)((double)(grab_ymax-GrabonY)*sy)+GrabonY;
01178 grab_zmin = (long)((double)(grab_zmin-GrabonZ)*sz)+GrabonZ;
01179 grab_zmax = (long)((double)(grab_zmax-GrabonZ)*sz)+GrabonZ;
01180 sxx *= sx; syy *= sy; szz *= sz;
01181 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,
01182 grab_xmax,grab_ymax,grab_zmax);
01183 XpandNurbsSurface(ActiveView,0,sx,sy,sz);
01184 }
01185 evTime=GetTickCount()+TIME_DELAY;
01186 }
01187 while (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
01188 if(flag && !(GetAsyncKeyState(VK_RBUTTON) & 0x8000)){
01189 int i;
01190 vertex *vp;
01191 flag=0;
01192 grab_xmin=grab_ymin=grab_zmin = MAXUNIT;
01193 grab_xmax=grab_ymax=grab_zmax = -MAXUNIT;
01194 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++){
01195 if(vp->status == SELECTED){
01196 vp->xyz[0]=(long)((double)(vp->xyz[0]-GrabonX)*sxx)+GrabonX;
01197 vp->xyz[1]=(long)((double)(vp->xyz[1]-GrabonY)*syy)+GrabonY;
01198 vp->xyz[2]=(long)((double)(vp->xyz[2]-GrabonZ)*szz)+GrabonZ;
01199 if(vp->xyz[0] > grab_xmax)grab_xmax=vp->xyz[0];
01200 if(vp->xyz[0] < grab_xmin)grab_xmin=vp->xyz[0];
01201 if(vp->xyz[1] > grab_ymax)grab_ymax=vp->xyz[1];
01202 if(vp->xyz[1] < grab_ymin)grab_ymin=vp->xyz[1];
01203 if(vp->xyz[2] > grab_zmax)grab_zmax=vp->xyz[2];
01204 if(vp->xyz[2] < grab_zmin)grab_zmin=vp->xyz[2];
01205 }
01206 vp++;
01207 }
01208 RecalibrateAllBezier(); RecalibrateMapLocks();
01209 do_NOT_abort=1;
01210 DrawModel();
01211 do_NOT_abort=0;
01212 sxx=syy=szz=1.0;
01213 }
01214 else{
01215 DrawRubberBoundBox(grab_xmin,grab_ymin,grab_zmin,
01216 grab_xmax,grab_ymax,grab_zmax);
01217 XpandNurbsSurface(ActiveView,-1,0.0,0.0,0.0);
01218 }
01219 return;
01220 }
01221
01222 static void Irotate(void){
01223 double beta=0.0,ctheta=0.0,stheta=0.0;
01224 int angle=0,bngle=0,x,xo,MickeyX,I,flag=0;
01225 POINT pt;
01226 long xp,yp,evTime;
01227 GetCursorPos(&pt); xo=pt.x;
01228 RotatorTheta=0.0;
01229 ClipCursor(NULL);
01230 if(!Mxpand){
01231 GrabonX=NpointerX; GrabonY=NpointerY; GrabonZ=NpointerZ;
01232 }
01233 evTime=GetTickCount()+TIME_DELAY;
01234 do {
01235 if(evTime > GetTickCount())continue;
01236 GetCursorPos(&pt); x=pt.x;
01237 MickeyX = x-xo; xo=x;
01238 if(MickeyX != 0){
01239 flag=1;
01240 if(MickeyX > 0)I=max( 1,min( 45,MickeyX));
01241 else I=min(-1,max(-45,MickeyX));
01242 if((GetAsyncKeyState(VK_SHIFT) & 0x8000) == 0x8000){
01243
01244 if(abs(I) < 22)I=0;
01245 else{
01246 if(I < 0)I = -45;
01247 else I = 45;
01248 }
01249 }
01250 DrawIrotateBoundBox(ActiveView,RotatorTheta);
01251 angle -= I;
01252 if (angle > 180)angle -= 360;
01253 else if(angle < -180)angle += 360;
01254 RotatorTheta = angle*PI/180.0;
01255 bngle -= I;
01256 if (bngle > 180)bngle -= 360;
01257 else if(bngle < -180)bngle += 360;
01258 DrawIrotateBoundBox(ActiveView,RotatorTheta);
01259 RotateNurbsSurface(ActiveView,0,RotatorTheta);
01260 }
01261 evTime=GetTickCount()+TIME_DELAY;
01262 }
01263 while (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
01264 if(flag && !(GetAsyncKeyState(VK_RBUTTON) & 0x8000)){
01265 int i;
01266 vertex *vp;
01267 flag=0;
01268 beta = bngle*PI/180.0; bngle=0;
01269 ctheta=cos(beta); stheta=sin(beta);
01270 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++){
01271 if(vp->status == SELECTED){
01272 if(ActiveView == TRITOP){
01273 RotatePointAbout(vp->xyz[0],vp->xyz[1],GrabonX,GrabonY,
01274 &xp,&yp,ctheta,stheta);
01275 vp->xyz[0]=xp; vp->xyz[1]=yp;
01276 }
01277 else if(ActiveView == TRIFRONT){
01278 RotatePointAbout(vp->xyz[0],vp->xyz[2],GrabonX,GrabonZ,
01279 &xp,&yp,ctheta,stheta);
01280 vp->xyz[0]=xp; vp->xyz[2]=yp;
01281 }
01282 else if(ActiveView == TRIRIGHT){
01283 RotatePointAbout(vp->xyz[1],vp->xyz[2],GrabonY,GrabonZ,
01284 &xp,&yp,ctheta,stheta);
01285 vp->xyz[1]=xp; vp->xyz[2]=yp;
01286 }
01287 }
01288 vp++;
01289 }
01290 RecalibrateAllBezier(); RecalibrateMapLocks();
01291 do_NOT_abort=1;
01292 DrawModel();
01293 do_NOT_abort=0;
01294 }
01295 else {
01296 DrawIrotateBoundBox(ActiveView,RotatorTheta);
01297 RotateNurbsSurface(ActiveView,-1,0.0);
01298 }
01299 return;
01300 }
01301
01302 static void RotatePointAbout(long x, long y, long X, long Y, long *tx,
01303 long *ty, double ctheta, double stheta){
01304 double dx,dy;
01305 dx=(double)(x-X);
01306 dy=(double)(y-Y);
01307 *tx = X+(long)(ctheta*dx-stheta*dy);
01308 *ty = Y+(long)(stheta*dx+ctheta*dy);
01309 }
01310
01311 static void DrawIrotateBoundBox(int i, double theta){
01312 int xs1,xs2,xs3,xs4,ys1,ys2,ys3,ys4;
01313 long xp,yp;
01314 double c,s;
01315 RECT rc;
01316 HDC hDC;
01317 hDC=GetDC(ghwnd_triview[i]);
01318 SelectObject(hDC,ghInvertPen);
01319 SetROP2(hDC,R2_XORPEN);
01320 SelectPalette(hDC,ghpaletteScreen,FALSE);
01321 RealizePalette(hDC);
01322 c=cos(theta); s=sin(theta);
01323 if(i == TRITOP){
01324 RotatePointAbout(grab_xmin,grab_ymin,GrabonX,GrabonY,&xp,&yp,c,s);
01325 GetWindowCoords(i,xp,yp,GrabonZ,&xs1,&ys1);
01326 RotatePointAbout(grab_xmax,grab_ymin,GrabonX,GrabonY,&xp,&yp,c,s);
01327 GetWindowCoords(i,xp,yp,GrabonZ,&xs2,&ys2);
01328 RotatePointAbout(grab_xmax,grab_ymax,GrabonX,GrabonY,&xp,&yp,c,s);
01329 GetWindowCoords(i,xp,yp,GrabonZ,&xs3,&ys3);
01330 RotatePointAbout(grab_xmin,grab_ymax,GrabonX,GrabonY,&xp,&yp,c,s);
01331 GetWindowCoords(i,xp,yp,GrabonZ,&xs4,&ys4);
01332 }
01333 else if(i == TRIFRONT){
01334 RotatePointAbout(grab_xmin,grab_zmin,GrabonX,GrabonZ,&xp,&yp,c,s);
01335 GetWindowCoords(i,xp,GrabonY,yp,&xs1,&ys1);
01336 RotatePointAbout(grab_xmax,grab_zmin,GrabonX,GrabonZ,&xp,&yp,c,s);
01337 GetWindowCoords(i,xp,GrabonY,yp,&xs2,&ys2);
01338 RotatePointAbout(grab_xmax,grab_zmax,GrabonX,GrabonZ,&xp,&yp,c,s);
01339 GetWindowCoords(i,xp,GrabonY,yp,&xs3,&ys3);
01340 RotatePointAbout(grab_xmin,grab_zmax,GrabonX,GrabonZ,&xp,&yp,c,s);
01341 GetWindowCoords(i,xp,GrabonY,yp,&xs4,&ys4);
01342 }
01343 else if(i == TRIRIGHT){
01344 RotatePointAbout(grab_ymin,grab_zmin,GrabonY,GrabonZ,&xp,&yp,c,s);
01345 GetWindowCoords(i,GrabonY,xp,yp,&xs1,&ys1);
01346 RotatePointAbout(grab_ymax,grab_zmin,GrabonY,GrabonZ,&xp,&yp,c,s);
01347 GetWindowCoords(i,GrabonY,xp,yp,&xs2,&ys2);
01348 RotatePointAbout(grab_ymax,grab_zmax,GrabonY,GrabonZ,&xp,&yp,c,s);
01349 GetWindowCoords(i,GrabonY,xp,yp,&xs3,&ys3);
01350 RotatePointAbout(grab_ymin,grab_zmax,GrabonY,GrabonZ,&xp,&yp,c,s);
01351 GetWindowCoords(i,GrabonY,xp,yp,&xs4,&ys4);
01352 }
01353 DrawOne3dCursor(hDC,i);
01354 MoveToEx(hDC,xs1,ys1,NULL);
01355 LineTo(hDC,xs2,ys2); LineTo(hDC,xs3,ys3);
01356 LineTo(hDC,xs4,ys4); LineTo(hDC,xs1,ys1);
01357 DrawOne3dCursor(hDC,i);
01358 ReleaseDC(ghwnd_triview[i],hDC);
01359 }
01360
01361 static void ShapeShape(int id){
01362 int x,xo,MickeyX,I;
01363 POINT pt;
01364 long xp,yp,evTime;
01365 double c;
01366 GetCursorPos(&pt); xo=pt.x;
01367 RotatorTheta=0.0;
01368 ClipCursor(NULL);
01369 evTime=GetTickCount()+TIME_DELAY;
01370 do {
01371 if(evTime > GetTickCount())continue;
01372 GetCursorPos(&pt); x=pt.x;
01373 MickeyX = x-xo; xo=x;
01374 if(MickeyX != 0){
01375 if(MickeyX > 0)I=max( 1,min( 50,MickeyX));
01376 else I=min(-1,max(-50,MickeyX));
01377 DrawShaperSphere(GrabonX,GrabonY,GrabonZ,
01378 shaper_angle_theta,shaper_angle_phi,shaper_size);
01379 c=(1.0-(double)I/50.0); c=min(c,1.2); c=max(c,0.8);
01380 if(id == 0){
01381 shaper_size *= c;
01382 if(shaper_size < 0.3)shaper_size=0.3;
01383 if(shaper_size > 50.)shaper_size=50.;
01384 }
01385 else if(id == 1){
01386 shaper_angle_phi += I*PI/180;
01387 if(shaper_angle_phi > PI)shaper_angle_phi -= PI*2;
01388 if(shaper_angle_phi < -PI)shaper_angle_phi += PI*2;
01389 }
01390 else if(id == 2){
01391 shaper_angle_theta += I*PI/180;;
01392 if(shaper_angle_theta > PI)shaper_angle_theta -= PI*2;
01393 if(shaper_angle_theta < -PI)shaper_angle_theta += PI*2;
01394 }
01395 DrawShaperSphere(GrabonX,GrabonY,GrabonZ,
01396 shaper_angle_theta,shaper_angle_phi,shaper_size);
01397 }
01398 evTime=GetTickCount()+TIME_DELAY;
01399 }
01400 while (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
01401 return;
01402 }
01403
01404 static void Shape(void){
01405 long i;
01406 vector shaper_direction={0.0,0.0,1.0};
01407 vertex *vp;
01408 double mu1,mu2,r2,sx,sy,sz,b,c,rt;
01409 vector vnc;
01410 shaper_direction[2]=cos(shaper_angle_theta);
01411 shaper_direction[0]=cos(shaper_angle_phi)*sin(shaper_angle_theta);
01412 shaper_direction[1]=sin(shaper_angle_phi)*sin(shaper_angle_theta);
01413 r2=((double)TVsizeX/shaper_size)*((double)TVsizeX/shaper_size);
01414 vp=MainVp; if(MainVp != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
01415 if(vp->status != SELECTED)continue;
01416 vnc[0]=(double)(vp->xyz[0]-GrabonX);
01417 vnc[1]=(double)(vp->xyz[1]-GrabonY);
01418 vnc[2]=(double)(vp->xyz[2]-GrabonZ);
01419 b=2*DOT(vnc,shaper_direction);
01420 c=DOT(vnc,vnc)-r2;
01421 rt=(b*b-4.0*c);
01422 if(rt > 0.0){
01423 rt=sqrt(rt);
01424 mu1 = (-b+rt)*0.5;
01425 mu2 = (-b-rt)*0.5;
01426 if(mu1 > mu2){
01427 c=mu1; mu1=mu2; mu2=c;
01428 }
01429 if(mu1 < 0.0 && mu2 > 0.0){
01430 vp->xyz[0] += (long)(mu2*shaper_direction[0]);
01431 vp->xyz[1] += (long)(mu2*shaper_direction[1]);
01432 vp->xyz[2] += (long)(mu2*shaper_direction[2]);
01433 }
01434 }
01435 vp++;
01436 }
01437 RecalibrateAllBezier(); RecalibrateMapLocks();
01438 do_NOT_abort=TRUE;
01439 DrawModel();
01440 do_NOT_abort=FALSE;
01441 DrawShaperSphere(GrabonX,GrabonY,GrabonZ,
01442 shaper_angle_theta,shaper_angle_phi,shaper_size);
01443 }
01444
01445 static void FormerDown(void){
01446 long i,j;
01447 vertex *vp;
01448 shaper_list=NULL;
01449 bShaperMoved=FALSE;
01450 if(NvertSelect < 1)return;
01451 if((shaper_list=X__Malloc(NvertSelect*sizeof(point))) != NULL){
01452 for(i=0,j=0,vp=MainVp;i<Nvert;i++,vp++){
01453 if(vp->status != SELECTED)continue;
01454 VECCOPY(vp->xyz,shaper_list[j])
01455 j++;
01456 }
01457 }
01458 return;
01459 }
01460
01461 static void FormerUp(void){
01462 if(shaper_list !=NULL)X__Free(shaper_list);
01463 shaper_list=NULL;
01464 if(!bShaperMoved)return;
01465 RecalibrateAllBezier(); RecalibrateMapLocks();
01466 if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,(WM_USER+2),0,0);
01467 do_NOT_abort=TRUE;
01468 DrawModel();
01469 do_NOT_abort=FALSE;
01470 }
01471
01472 static void FormerMove(void){
01473 long i,j;
01474 double z,zmax,scale;
01475 vertex *vp;
01476 vector po,dx,gon;
01477 bShaperMoved=TRUE;
01478 if(shaper_list == NULL)return;
01479 zmax=((double)TVsizeX/shaper_size);
01480 zmax=zmax*zmax;
01481 dx[0]=NpointerX-(gon[0]=GrabonX);
01482 dx[1]=NpointerY-(gon[1]=GrabonY);
01483 dx[2]=NpointerZ-(gon[2]=GrabonZ);
01484 for(i=0,j=0,vp=MainVp;i<Nvert;i++,vp++){
01485 if(vp->status != SELECTED)continue;
01486 VECCOPY((double)shaper_list[j],po)
01487 z=(po[0]-gon[0])*(po[0]-gon[0])+
01488 (po[1]-gon[1])*(po[1]-gon[1])+
01489 (po[2]-gon[2])*(po[2]-gon[2]);
01490 if(z < zmax){
01491 scale=(1.0-z/zmax);
01492 if(GetAsyncKeyState(VK_SHIFT) & 0x8000){scale = scale*scale*scale*scale;}
01493 else scale *= scale;
01494 VECSUM(po,scale*dx,vp->xyz)
01495 }
01496 j++;
01497 }
01498 DrawQuickModel();
01499 }
01500
01501 static void ShearerDown(void){
01502 long i,j,id,c,cc;
01503 vertex *vp;
01504 shaper_list=NULL;
01505 bShaperMoved=FALSE;
01506 if(NvertSelect < 1)return;
01507 if (ActiveView == TRITOP) {id=2; c=NpointerZ;}
01508 else if(ActiveView == TRIFRONT){id=1; c=NpointerY;}
01509 else if(ActiveView == TRIRIGHT){id=0; c=NpointerX;}
01510 GrabDx=0;
01511 if((shaper_list=X__Malloc(NvertSelect*sizeof(point))) != NULL){
01512 for(i=0,j=0,vp=MainVp;i<Nvert;i++,vp++){
01513 if(vp->status != SELECTED)continue;
01514 if((cc=labs(vp->xyz[id]-c)) > GrabDx)GrabDx=cc;
01515 VECCOPY(vp->xyz,shaper_list[j])
01516 j++;
01517 }
01518 }
01519 return;
01520 }
01521
01522 static void ShearerUp(void){
01523 if(shaper_list !=NULL)X__Free(shaper_list);
01524 shaper_list=NULL;
01525 if(!bShaperMoved)return;
01526 RecalibrateAllBezier(); RecalibrateMapLocks();
01527 if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,(WM_USER+2),0,0);
01528 do_NOT_abort=TRUE;
01529 DrawModel();
01530 do_NOT_abort=FALSE;
01531 }
01532
01533 static void ShearerMove(int x, int y){
01534 long i,j,id,type;
01535 vertex *vp;
01536 vector po,dx,gon;
01537 double z,l;
01538 bShaperMoved=TRUE;
01539 if(shaper_list == NULL)return;
01540
01541 if((GetAsyncKeyState(VK_MENU) & 0x8000) &&
01542 (GetAsyncKeyState(VK_CONTROL) & 0x8000)){
01543 long id1,id2,c1,c2,cc;
01544 l=(double)(x-x_down);
01545 if(l > 0.0)l=min(360.0,l*1.5);
01546 else l=max(-360.0,l*1.5);
01547 if (ActiveView == TRITOP) {id1=1; c1=GrabonY;}
01548 else if(ActiveView == TRIFRONT){id1=2; c1=GrabonZ;}
01549 else if(ActiveView == TRIRIGHT){id1=2; c1=GrabonZ;}
01550 GrabDx=0;
01551 for(i=0,j=0,vp=MainVp;i<Nvert;i++,vp++){
01552 if(vp->status != SELECTED)continue;
01553 if((cc=labs((long)shaper_list[j][id1]-c1)) > GrabDx)GrabDx=cc;
01554 j++;
01555 }
01556 gon[0]=GrabonX;
01557 gon[1]=GrabonY;
01558 gon[2]=GrabonZ;
01559 for(i=0,j=0,vp=MainVp;i<Nvert;i++,vp++){
01560 if(vp->status != SELECTED)continue;
01561 VECCOPY((double)shaper_list[j],po)
01562 z=fabs(po[id1]-gon[id1]);
01563 if(GrabDx > 1.0){
01564 long xp,yp;
01565 double beta,ctheta,stheta;
01566 if(GetAsyncKeyState(VK_SHIFT) & 0x8000)z=(1.0 - z/(double)GrabDx);
01567 else z=z/(double)GrabDx;
01568 beta = l*z*PI/180.0;
01569 ctheta=cos(beta); stheta=sin(beta);
01570 if(ActiveView == TRITOP){
01571 RotatePointAbout((long)po[0],(long)po[1],GrabonX,GrabonY,
01572 &xp,&yp,ctheta,stheta);
01573 vp->xyz[0]=xp; vp->xyz[1]=yp;
01574 }
01575 else if(ActiveView == TRIFRONT){
01576 RotatePointAbout((long)po[0],(long)po[2],GrabonX,GrabonZ,
01577 &xp,&yp,ctheta,stheta);
01578 vp->xyz[0]=xp; vp->xyz[2]=yp;
01579 }
01580 else if(ActiveView == TRIRIGHT){
01581 RotatePointAbout((long)po[1],(long)po[2],GrabonY,GrabonZ,
01582 &xp,&yp,ctheta,stheta);
01583 vp->xyz[1]=xp; vp->xyz[2]=yp;
01584 }
01585 }
01586 j++;
01587 }
01588 DrawQuickModel();
01589 return;
01590 }
01591
01592
01593 dx[0]=NpointerX-(gon[0]=GrabonX);
01594 dx[1]=NpointerY-(gon[1]=GrabonY);
01595 dx[2]=NpointerZ-(gon[2]=GrabonZ);
01596 if (ActiveView == TRITOP) {dx[2]=0; id=2;}
01597 else if(ActiveView == TRIFRONT){dx[1]=0; id=1;}
01598 else if(ActiveView == TRIRIGHT){dx[0]=0; id=0;}
01599 if(GetAsyncKeyState(VK_MENU) & 0x8000){
01600 l=(double)(x-x_down);
01601 if(l < 0.0)l = min(1.0,fabs(l)/100.0);
01602 else l = -min(1.0,l/100.0);
01603 type=1;
01604 }
01605 else if(GetAsyncKeyState(VK_CONTROL) & 0x8000){
01606 l=(double)(x-x_down);
01607 if(l > 0.0)l=min(360.0,l*1.5);
01608 else l=max(-360.0,l*1.5);
01609 type=2;
01610 }
01611 else{
01612 type=0;
01613 }
01614 for(i=0,j=0,vp=MainVp;i<Nvert;i++,vp++){
01615 if(vp->status != SELECTED)continue;
01616 VECCOPY((double)shaper_list[j],po)
01617 z=fabs(po[id]-gon[id]);
01618 if(GrabDx > 1.0){
01619 z=(1.0 - z/(double)GrabDx);
01620 if(GetAsyncKeyState(VK_SHIFT) & 0x8000)z=z*z;
01621 if(type == 1){
01622 vector d;
01623 VECSUB(gon,po,d)
01624 if (ActiveView == TRITOP) d[2]=0;
01625 else if(ActiveView == TRIFRONT)d[1]=0;
01626 else if(ActiveView == TRIRIGHT)d[0]=0;
01627 VECSUM(po,l*z*d,vp->xyz)
01628 }
01629 else if(type == 2){
01630 long xp,yp;
01631 double beta,ctheta,stheta;
01632 beta = l*z*PI/180.0;
01633 ctheta=cos(beta); stheta=sin(beta);
01634 if(ActiveView == TRITOP){
01635 RotatePointAbout((long)po[0],(long)po[1],GrabonX,GrabonY,
01636 &xp,&yp,ctheta,stheta);
01637 vp->xyz[0]=xp; vp->xyz[1]=yp;
01638 }
01639 else if(ActiveView == TRIFRONT){
01640 RotatePointAbout((long)po[0],(long)po[2],GrabonX,GrabonZ,
01641 &xp,&yp,ctheta,stheta);
01642 vp->xyz[0]=xp; vp->xyz[2]=yp;
01643 }
01644 else if(ActiveView == TRIRIGHT){
01645 RotatePointAbout((long)po[1],(long)po[2],GrabonY,GrabonZ,
01646 &xp,&yp,ctheta,stheta);
01647 vp->xyz[1]=xp; vp->xyz[2]=yp;
01648 }
01649 }
01650 else{
01651 VECSUM(po,z*dx,vp->xyz)
01652 }
01653 }
01654 j++;
01655 }
01656 DrawQuickModel();
01657 }
01658
01659 static int PanX,PanY,ZoomX,ZoomY,ZoomRX,ZoomRY;
01660 static BOOL ZoomInFlag=FALSE,PanMoveFlag=FALSE;
01661 static HDC hDCzoom;
01662
01663 void PanToolUp(int x, int y, BOOL ctrl, BOOL shift, HWND hwnd){
01664 double zf=2.0;
01665 long a,b,c,d,e,f,stor;
01666 if(ZoomInFlag){
01667 Rectangle(hDCzoom,ZoomX,ZoomY,ZoomRX,ZoomRY);
01668 ReleaseDC(hwnd,hDCzoom);
01669 ZoomInFlag=FALSE;
01670 if(!ctrl)return;
01671 if(TVsizeX <= MINUNIT || TVsizeY <= MINUNIT || TVsizeZ <= MINUNIT){
01672
01673 MessageBeep(MB_OK);
01674 return;
01675 }
01676 if(ActiveView == TRITOP){
01677 stor=NpointerZ; NpointerZ=(TVpointZ+TVsizeZ/2);
01678 }
01679 else if(ActiveView == TRIFRONT){
01680 stor=NpointerY; NpointerY=(TVpointY+TVsizeY/2);
01681 }
01682 else{
01683 stor=NpointerX; NpointerX=(TVpointX+TVsizeX/2);
01684 }
01685 GetWorldCoords(ActiveView,&a,&b,&c,(ZoomX+ZoomRX)/2,(ZoomY+ZoomRY)/2);
01686 zf=(double)max(abs(ZoomX-ZoomRX),abs(ZoomY-ZoomRY))/
01687 (double)(max(WindowSizeX[ActiveView],WindowSizeY[ActiveView]));
01688 TVsizeX=(long)((double)TVsizeX*zf);
01689 TVsizeY=(long)((double)TVsizeY*zf);
01690 TVsizeZ=(long)((double)TVsizeZ*zf);
01691 WindowPixelSize=(double)TVsizeZ/(double)WindowSizeY[1];
01692 TVpointX=a-TVsizeX/2; TVcentreX=a;
01693 TVpointY=b-TVsizeY/2; TVcentreY=b;
01694 TVpointZ=c-TVsizeZ/2; TVcentreZ=c;
01695 if(ActiveView == TRITOP)NpointerZ=stor;
01696 else if(ActiveView == TRIFRONT)NpointerY=stor;
01697 else NpointerX=stor;
01698 }
01699 else if(ctrl){
01700 if(TVsizeX <= MINUNIT || TVsizeY <= MINUNIT || TVsizeZ <= MINUNIT){
01701
01702 MessageBeep(MB_OK);
01703 }
01704 else{
01705 if(ActiveView == TRITOP){
01706 stor=NpointerZ; NpointerZ=(TVpointZ+TVsizeZ/2);
01707 }
01708 else if(ActiveView == TRIFRONT){
01709 stor=NpointerY; NpointerY=(TVpointY+TVsizeY/2);
01710 }
01711 else{
01712 stor=NpointerX; NpointerX=(TVpointX+TVsizeX/2);
01713 }
01714 GetWorldCoords(ActiveView,&a,&b,&c,x,y);
01715 TVsizeX=(long)((double)TVsizeX/zf);
01716 TVsizeY=(long)((double)TVsizeY/zf);
01717 TVsizeZ=(long)((double)TVsizeZ/zf);
01718 WindowPixelSize=(double)TVsizeZ/(double)WindowSizeY[1];
01719 TVpointX=a-TVsizeX/2; TVcentreX=a;
01720 TVpointY=b-TVsizeY/2; TVcentreY=b;
01721 TVpointZ=c-TVsizeZ/2; TVcentreZ=c;
01722 if(ActiveView == TRITOP)NpointerZ=stor;
01723 else if(ActiveView == TRIFRONT)NpointerY=stor;
01724 else NpointerX=stor;
01725 }
01726 }
01727 else if(shift){
01728 if(TVsizeX >= MAXUNIT || TVsizeY >= MAXUNIT || TVsizeZ >= MAXUNIT){
01729
01730 MessageBeep(MB_OK);
01731 }
01732 else{
01733 if(ActiveView == TRITOP){
01734 stor=NpointerZ; NpointerZ=(TVpointZ+TVsizeZ/2);
01735 }
01736 else if(ActiveView == TRIFRONT){
01737 stor=NpointerY; NpointerY=(TVpointY+TVsizeY/2);
01738 }
01739 else{
01740 stor=NpointerX; NpointerX=(TVpointX+TVsizeX/2);
01741 }
01742 GetWorldCoords(ActiveView,&a,&b,&c,x,y);
01743 TVsizeX=(long)((double)TVsizeX*zf);
01744 TVsizeY=(long)((double)TVsizeY*zf);
01745 TVsizeZ=(long)((double)TVsizeZ*zf);
01746 WindowPixelSize=(double)TVsizeZ/(double)WindowSizeY[1];
01747 TVpointX=a-TVsizeX/2; TVcentreX=a;
01748 TVpointY=b-TVsizeY/2; TVcentreY=b;
01749 TVpointZ=c-TVsizeZ/2; TVcentreZ=c;
01750 if(ActiveView == TRITOP)NpointerZ=stor;
01751 else if(ActiveView == TRIFRONT)NpointerY=stor;
01752 else NpointerX=stor;
01753 }
01754 }
01755 if(NpointerX < TVpointX)NpointerX=TVpointX+TVsizeX/2;
01756 if(NpointerX > TVpointX+TVsizeX)NpointerX=TVpointX+TVsizeX/2;
01757 if(NpointerY < TVpointY)NpointerY=TVpointY+TVsizeY/2;
01758 if(NpointerY > TVpointY+TVsizeY)NpointerY=TVpointY+TVsizeY/2;
01759 if(NpointerZ < TVpointZ)NpointerZ=TVpointZ+TVsizeZ/2;
01760 if(NpointerZ > TVpointZ+TVsizeZ)NpointerZ=TVpointZ+TVsizeZ/2;
01761 if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,(WM_USER+2),0,0);
01762 do_NOT_abort=TRUE;
01763 DrawModel();
01764 do_NOT_abort=FALSE;
01765 UpdateCounters();
01766 }
01767
01768 BOOL PanToolDown(int x, int y, BOOL ctrl, BOOL shift, HWND hwnd){
01769 PanX=x; PanY=y;
01770 ZoomInFlag=FALSE; PanMoveFlag=FALSE;
01771 ZoomX=x; ZoomY=y;
01772 return TRUE;
01773 }
01774
01775 void PanToolMove(int x, int y, BOOL ctrl, BOOL shift,HWND hwnd){
01776 long a,b,c,d,e,f,gqd;
01777 if(ctrl || ZoomInFlag){
01778 if(!ZoomInFlag && (abs(x-ZoomX) > 2 || abs(y-ZoomY) > 2)){
01779 ZoomInFlag=TRUE;
01780 hDCzoom=GetDC(hwnd);
01781 SelectObject(hDCzoom,GetStockObject(NULL_BRUSH));
01782 SelectObject(hDCzoom,ghSelectedPen);
01783 SetROP2(hDCzoom,R2_XORPEN);
01784 SelectPalette(hDCzoom,ghpaletteScreen,FALSE);
01785 RealizePalette(hDCzoom);
01786 Rectangle(hDCzoom,ZoomX,ZoomY,ZoomRX,ZoomRY);
01787 }
01788 if(ZoomInFlag){
01789 Rectangle(hDCzoom,ZoomX,ZoomY,ZoomRX,ZoomRY);
01790 ZoomRX=x; ZoomRY=y;
01791 Rectangle(hDCzoom,ZoomX,ZoomY,ZoomRX,ZoomRY);
01792 }
01793 return;
01794 }
01795 else if(shift)return;
01796 PanMoveFlag=TRUE;
01797 GetWorldCoords(ActiveView,&a,&b,&c,PanX,PanY);
01798 GetWorldCoords(ActiveView,&d,&e,&f,x,y);
01799 TVpointX += (a-d);
01800 TVpointY += (b-e);
01801 TVpointZ += (c-f);
01802 TVcentreX += (a-d);
01803 TVcentreY += (b-e);
01804 TVcentreZ += (c-f);
01805 PanX=x; PanY=y;
01806 DrawQuickModel();
01807 }
01808
01809 void ZoomView(int x, int y){
01810 BOOL bRedraw=FALSE,bUpdate=FALSE;
01811 unsigned int SaveDrawStatus;
01812 int xo;
01813 POINT pt;
01814 long gqd,evTime;
01815 double zf,dx,dy,dz;
01816 GetCursorPos(&pt); xo=pt.x;
01817
01818 do {
01819 Sleep(10);
01820
01821 if(!(GetAsyncKeyState(VK_LBUTTON) & 0x8000))break;
01822 GetCursorPos(&pt); y=pt.x;
01823 if(y < 1){
01824 x= 0; SetCursorPos(pt.x+20,pt.y); xo=pt.x+20;
01825 }
01826 else if(y > Xres-2){
01827 x= 0; SetCursorPos(pt.x-20,pt.y); xo=pt.x-20;
01828 }
01829 else{
01830 x = y-xo; xo=y;
01831 }
01832 if(x != 0){
01833 dx=(double)(NpointerX-TVpointX)/(double)TVsizeX;
01834 dy=(double)(NpointerY-TVpointY)/(double)TVsizeY;
01835 dz=(double)(NpointerZ-TVpointZ)/(double)TVsizeZ;
01836 if(x > 0){
01837 zf=1.1;
01838 }
01839 else{
01840 zf=0.9090909;
01841 }
01842 if(zf < 1.0 &&
01843 (TVsizeX >= MAXUNIT || TVsizeY >= MAXUNIT || TVsizeZ >= MAXUNIT)){
01844 MessageBeep(MB_OK);
01845 }
01846 else{
01847 TVsizeX=(long)((double)TVsizeX/zf);
01848 TVsizeY=(long)((double)TVsizeY/zf);
01849 TVsizeZ=(long)((double)TVsizeZ/zf);
01850 WindowPixelSize=(double)TVsizeZ/(double)WindowSizeY[1];
01851 TVpointX=NpointerX-(long)(dx*(double)TVsizeX); TVcentreX=TVpointX+TVsizeX/2;
01852 TVpointY=NpointerY-(long)(dy*(double)TVsizeY); TVcentreY=TVpointY+TVsizeY/2;
01853 TVpointZ=NpointerZ-(long)(dz*(double)TVsizeZ); TVcentreZ=TVpointZ+TVsizeZ/2;
01854 DrawQuickModel();
01855 bRedraw=TRUE;
01856 bUpdate=TRUE;
01857 }
01858 }
01859
01860 {MSG msg;
01861 if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
01862 TranslateMessage(&msg);
01863 DispatchMessage(&msg);
01864 }
01865 }
01866 if(bUpdate){
01867 DrawQuickModel();
01868 bUpdate=FALSE;
01869 }
01870 }
01871 while(1);
01872 if(bRedraw){
01873 if(ghwndOpenGLview != NULL)PostMessage(ghwndOpenGLview,(WM_USER+2),0,0);
01874 do_NOT_abort=TRUE;
01875 DrawModel();
01876 do_NOT_abort=FALSE;
01877 UpdateCounters();
01878 }
01879 return;
01880 }