00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 #include <stdlib.h>
00168 #include <stdio.h>
00169 #include <math.h>
00170 #include <windows.h>
00171
00172 #include "struct.h"
00173 #include "dstruct.h"
00174
00175 #include "joins.h"
00176
00177 #define NO 0
00178 #define YES 1
00179 #define FAIL -1
00180 #define OK 1
00181 #define DESELECTED 0
00182 #define SELECTED 1
00183
00184 static HWND hParent;
00185 static HINSTANCE hThisInstance;
00186
00187 static void JoinCurves(void);
00188
00189 #if __WATCOMC__
00190 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00191 #else
00192 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00193 #endif
00194 switch (dwReason) {
00195 case DLL_PROCESS_ATTACH: {
00196 hThisInstance=hDLL;
00197 if(hDLL == NULL)MessageBox( GetFocus()," NULL instance",NULL, MB_OK);
00198 break;
00199 }
00200 case DLL_PROCESS_DETACH:
00201 break;
00202 }
00203 return TRUE;
00204 }
00205
00206 #if __SC__
00207 #pragma startaddress(DllMain)
00208 #endif
00209
00210 static BOOL CALLBACK JoinCurvesDlgProc(HWND hwnd, UINT msg,
00211 WPARAM wparam, LPARAM lparam){
00212 switch( msg ) {
00213 case WM_INITDIALOG:
00214 CentreDlgOnS(hwnd);
00215 return (TRUE);
00216 case WM_COMMAND:
00217 switch(LOWORD(wparam)){
00218 case IDCANCEL:
00219 EndDialog(hwnd,FALSE);
00220 return(TRUE);
00221 case IDOK:
00222 EndDialog(hwnd,TRUE);
00223 return(TRUE);
00224 default:
00225 break;
00226 }
00227 break;
00228 default: break;
00229 }
00230 return(FALSE);
00231 }
00232
00233 BOOL _Xmodeler
00234 (HWND parent_window,HWND info_window,X__STRUCTURE *lpevi){
00235 HCURSOR hSave;
00236 lpEVI=lpevi;
00237 hParent=parent_window;
00238 if(DialogBox(hThisInstance,MAKEINTRESOURCE(DLG_JOIN),hParent,
00239 (DLGPROC)JoinCurvesDlgProc) == FALSE)return FALSE;
00240 hSave=SetCursor(LoadCursor(NULL,IDC_WAIT));
00241 JoinCurves();
00242 SetCursor(hSave);
00243 return TRUE;
00244 }
00245
00246 static double dspacing(long Va1, long Va2){
00247 vertex *va1,*va2;
00248 double d;
00249 va1=(MainVp+Va1); va2=(MainVp+Va2);
00250 d=(double)(va1->xyz[0] - va2->xyz[0]) *
00251 (double)(va1->xyz[0] - va2->xyz[0]) +
00252 (double)(va1->xyz[1] - va2->xyz[1]) *
00253 (double)(va1->xyz[1] - va2->xyz[1]) +
00254 (double)(va1->xyz[2] - va2->xyz[2]) *
00255 (double)(va1->xyz[2] - va2->xyz[2]);
00256 return sqrt(d);
00257 }
00258
00259 static long get_next_closest(long vf1){
00260 vertex *vp;
00261 long i,vf;
00262 double dmin,d;
00263 dmin=1.e30;
00264 vf = -1;
00265 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++){
00266 if(vp->status == SELECTED){
00267 d=(double)(vp->xyz[0]-(MainVp+vf1)->xyz[0])*
00268 (double)(vp->xyz[0]-(MainVp+vf1)->xyz[0])
00269 +(double)(vp->xyz[1]-(MainVp+vf1)->xyz[1])*
00270 (double)(vp->xyz[1]-(MainVp+vf1)->xyz[1])
00271 +(double)(vp->xyz[2]-(MainVp+vf1)->xyz[2])*
00272 (double)(vp->xyz[2]-(MainVp+vf1)->xyz[2]);
00273 if(d < dmin){
00274 dmin=d;
00275 vf=i;
00276 }
00277 }
00278 vp++;
00279 }
00280 return vf;
00281 }
00282
00283 static void JoinCurves(void){
00284 BOOL bSwapped;
00285 vertex *Vp;
00286 long vp,vf1,vf2,*va1,*va2,*tempva,tempv,vactive,vnext,vcurrent;
00287 double d,dmin=1e32;
00288 long Npath1,Npath2,i,j,k0,k1,k2,flag,lc;
00289 if(NvertSelect<6){MessageBeep(MB_OK); return; }
00290 if(NvertSelect > 32000){ MessageBeep(MB_OK); return; }
00291 vf1=vf2=-1;
00292 if((vf1=get_closest_vertex()) < 0){
00293 MessageBeep(MB_OK); goto GETOUT;
00294 }
00295 lc=0;
00296
00297
00298
00299
00300 MAINLOOP:
00301 vp=0; while(vp < Nvert){ Vp=(MainVp+vp); Vp->id=0; vp++; }
00302 va1=va2=NULL;
00303 if((va1=(long *)X__Malloc(NvertSelect*sizeof(long))) == NULL){
00304 MessageBeep(MB_OK);
00305 goto GETOUT;
00306 }
00307 Npath1=0; va1[0]=vf1; (MainVp+va1[0])->id=1;
00308 (MainVp+vf1)->status=DESELECTED; NvertSelect--; NvertDeselect++;
00309 vp=0; while(vp < Nvert){
00310 Vp=(MainVp+vp);
00311 if(Vp->status == SELECTED && Vp->id == 0 && Connected(va1[Npath1],vp)){
00312 Npath1++;
00313 va1[Npath1]=vp;
00314 Vp->id=1;
00315 Vp->status=DESELECTED;
00316 NvertSelect--; NvertDeselect++;
00317 vp=0;
00318 }
00319 else vp++;
00320 }
00321 if((vf2=get_next_closest(vf1)) < 0){
00322 MessageBeep(MB_OK);
00323 X__Free(va1);
00324 goto GETOUT;
00325 }
00326 if((va2=(long *)X__Malloc(NvertSelect*sizeof(long))) == NULL){
00327 MessageBeep(MB_OK);
00328 X__Free(va1);
00329 goto GETOUT;
00330 }
00331 Npath2=0; va2[0]=vf2; (MainVp+va2[0])->id=2;
00332 (MainVp+vf2)->status=DESELECTED; NvertSelect--; NvertDeselect++;
00333 vp=0; while(vp < Nvert){
00334 Vp=(MainVp+vp);
00335 if(Vp->status == SELECTED && Vp->id == 0 && Connected(va2[Npath2],vp)){
00336 Npath2++;
00337 va2[Npath2]=vp;
00338 Vp->id=2;
00339 Vp->status=DESELECTED;
00340 NvertSelect--; NvertDeselect++;
00341 vp=0;
00342 }
00343 else vp++;
00344 }
00345 Npath1++; Npath2++;
00346
00347
00348
00349
00350 if(Npath1 < 3 || Npath2 < 3){
00351 MessageBeep(MB_OK);
00352 X__Free(va1);
00353 X__Free(va2);
00354 goto GETOUT;
00355 }
00356
00357
00358
00359 for(i=0;i<Npath1;i++)
00360 for(j=0;j<Npath2;j++){
00361 if((d=dspacing(va1[i],va2[j])) < dmin){
00362 dmin=d; vf1=va1[i]; vf2=va2[j];
00363 }
00364 }
00365
00366
00367
00368 Npath1=0; va1[0]=vf1; (MainVp+va1[0])->id=0;
00369 vp=0; while(vp < Nvert){
00370 Vp=(MainVp+vp);
00371 if(Vp->id == 1 && Connected(va1[Npath1],vp)){
00372 Npath1++;
00373 va1[Npath1]=vp;
00374 Vp->id=0;
00375 vp=0;
00376 }
00377 else vp++;
00378 }
00379 Npath2=0; va2[0]=vf2; (MainVp+va2[0])->id=0;
00380 vp=0; while(vp < Nvert){
00381 Vp=(MainVp+vp);
00382 if(Vp->id == 2 && Connected(va2[Npath2],vp)){
00383 Npath2++;
00384 va2[Npath2]=vp;
00385 Vp->id=0;
00386 vp=0;
00387 }
00388 else vp++;
00389 }
00390
00391
00392
00393 if(Npath1 == 0 || Npath2 == 0){
00394 MessageBox(NULL,"Fatal Fail",NULL,MB_OK);
00395 goto GETOUT;
00396 }
00397
00398
00399
00400 Npath1++; Npath2++;
00401 if(Npath2 < Npath1){
00402 tempv=vf1; vf1=vf2; vf2=tempv;
00403 tempva=va1; va1=va2; va2=tempva;
00404 i=Npath1; Npath1=Npath2; Npath2=i;
00405 bSwapped=TRUE;
00406 }
00407 else bSwapped=FALSE;
00408
00409
00410
00411 if(dspacing(va1[1],va2[1]) > dspacing(va1[1],va2[Npath2-1])){
00412 for(i=1;i<=(Npath2-1)/2;i++){
00413 tempv=va2[i];
00414 va2[i]=va2[Npath2-i];
00415 va2[Npath2-i]=tempv;
00416 }
00417 }
00418 if(!UpdateEdgeHeap(Nedge+2*(Npath1+Npath2+1)))goto UPDATE_HEAP;
00419 if(!UpdateFaceHeap(Nface+2*(Npath1+Npath2+4)))goto UPDATE_HEAP;
00420 k0=1;
00421
00422
00423
00424 CreateEdge(va1[0],va2[0]);
00425 (MainVp+va1[0])->id=0;
00426 for(i=1;i<Npath1;i++){
00427 dmin=1e32; k1= -1;
00428 if(k0 < Npath2)for(j=k0;j<Npath2;j++){
00429 if((d=dspacing(va1[i],va2[j])) < dmin){dmin=d; k1=j;}
00430 }
00431 if(k1 >= 0){
00432 k0=k1;
00433 (MainVp+va1[i])->id=k0;
00434 CreateEdge(va1[i],va2[k0]);
00435 }
00436 }
00437
00438
00439
00440 for(i=0;i<Npath1;i++){
00441 flag=0;
00442 vactive=va1[i];
00443 k0=(long)((MainVp+va1[i])->id);
00444 vcurrent=va2[k0];
00445 if(i < Npath1-1){
00446 vnext=va1[i+1];
00447 k1=(long)((MainVp+va1[i+1])->id);
00448 k2=k1;
00449 }
00450 else{
00451 vnext=va1[0]; k1=Npath2; k2=0;
00452 }
00453 if(k1 > k0){
00454 if(k1 > k0+1){
00455 for(j=k0+1;j<k1;j++){
00456 vcurrent=va2[j];
00457 if(flag == 0){
00458 CreateEdge(vcurrent,vactive);
00459 CreateFace(vactive,vcurrent,va2[j-1]);
00460 if(dspacing(vcurrent,va2[k0]) > dspacing(vcurrent,va2[k2])){
00461 CreateEdge(vcurrent,vnext);
00462 CreateFace(vactive,vcurrent,vnext);
00463 flag=1;
00464 }
00465 }
00466 else{
00467 CreateEdge(vcurrent,vnext);
00468 CreateFace(va2[j-1],vnext,vcurrent);
00469 }
00470 }
00471 }
00472 if(flag == 0){
00473 CreateEdge(vcurrent,vnext);
00474 CreateFace(vactive,vnext,vcurrent);
00475 }
00476 CreateFace(vcurrent,vnext,va2[k2]);
00477 }
00478 else{
00479 CreateFace(vactive,vcurrent,vnext);
00480 }
00481 }
00482
00483
00484
00485
00486 if(NvertSelect > 3){
00487 if(bSwapped){
00488 for(i=0;i<Npath1;i++){
00489 (MainVp+va1[i])->status = SELECTED;
00490 NvertSelect++; NvertDeselect--;
00491 }
00492 }
00493 else{
00494 vf1=vf2;
00495 for(i=0;i<Npath2;i++){
00496 (MainVp+va2[i])->status = SELECTED;
00497 NvertSelect++; NvertDeselect--;
00498 }
00499 }
00500 if(va1 != NULL)X__Free(va1); va1=NULL;
00501 if(va2 != NULL)X__Free(va2); va2=NULL;
00502 lc++;
00503 goto MAINLOOP;
00504 }
00505 UPDATE_HEAP:
00506 UpdateFaceHeap(Nface);
00507 UpdateEdgeHeap(Nedge);
00508 if(va1 != NULL)X__Free(va1);
00509 if(va2 != NULL)X__Free(va2);
00510 GETOUT:
00511 return;
00512 }