00001
00002
00003
00004
00005
00006
00007
00008 #define MODULE_TOOLS3 1
00009
00010 #include "design.h"
00011
00012
00013 void ShatterEffect(void){
00014 face *fp;
00015 FILE *tf;
00016 vertex *vp1,*vp2,*vp3;
00017 long count,i,k,v1,v2,v3;
00018 char workfile[64];
00019 char t1[64],t2[64];
00020 Save_Undo(2);
00021 if(NvertSelect == 0 || MainFp == NULL){
00022 SendPrgmQuery(IDQ_NOSHATTER,0);
00023 return;
00024 }
00025 if(NvertSelect > 32000){
00026 SendPrgmQuery(IDQ_WIRETOOBIG,0);
00027 return;
00028 }
00029 LoadString(ghinst_main,IDX_MISC_CONFIRM,t1,63);
00030 LoadString(ghinst_main,IDS_DEFAULT,t2,63);
00031 if(MessageBox(NULL,t1,t2,
00032 MB_YESNO|MB_ICONQUESTION|MB_TASKMODAL) != IDYES)return;
00033 count=0;
00034 sprintf(workfile,"%swork_$.$$$",TempPath);
00035 if((tf=fopen(workfile,"wb")) == NULL){
00036 SendPrgmQuery(IDQ_TFWE,0);
00037 return;
00038 }
00039 fp=MainFp; for(k=0;k<Nface;k++){
00040 vp1=(MainVp+fp->V[0]); vp2=(MainVp+fp->V[1]); vp3=(MainVp+fp->V[2]);
00041 if(vp1->status == SELECTED ||
00042 vp1->status == SELECTED ||
00043 vp1->status == SELECTED){
00044 count++;
00045 if((fwrite(vp1->xyz,sizeof(long),3,tf) != 3) ||
00046 (fwrite(vp2->xyz,sizeof(long),3,tf) != 3) ||
00047 (fwrite(vp3->xyz,sizeof(long),3,tf) != 3) ||
00048 (fwrite(fp->color,sizeof(unsigned char),3,tf) != 3) ||
00049 (fwrite(&fp->bSmooth,sizeof(unsigned char),1,tf) != 1) ||
00050 (fwrite(&fp->imagemap,sizeof(short),1,tf) != 1) ||
00051 (fwrite(&fp->material,sizeof(short),1,tf) != 1)){
00052 SendPrgmQuery(IDQ_TFWE,0);
00053 fclose(tf);
00054 remove(workfile);
00055 return;
00056 }
00057 }
00058 fp++;
00059 }
00060 fclose(tf);
00061 if(count > 0){
00062 if((tf=fopen(workfile,"rb")) == NULL){
00063 SendPrgmQuery(IDQ_NOOPENWORKFILE,0);
00064 return;
00065 }
00066 EraseVertex(0);
00067 if(!UpdateVertexHeap(Nvert+count*3))goto EP1;
00068 if(!UpdateEdgeHeap(Nedge+count*3))goto EP1;
00069 if(!UpdateFaceHeap(Nface+count))goto EP1;
00070 for(i=0;i<count;i++){
00071 CreateVertex(); v1=Nvert-1; vp1=(MainVp+v1);
00072 CreateVertex(); v2=Nvert-1; vp2=(MainVp+v2);
00073 CreateVertex(); v3=Nvert-1; vp3=(MainVp+v3);
00074 CreateEdge(v1,v2);
00075 CreateEdge(v2,v3);
00076 CreateEdge(v3,v1);
00077 CreateFace(v1,v2,v3); fp=(MainFp+Nface-1);
00078 fread(vp1->xyz,sizeof(long),3,tf);
00079 fread(vp2->xyz,sizeof(long),3,tf);
00080 fread(vp3->xyz,sizeof(long),3,tf);
00081 fread(fp->color,sizeof(unsigned char),3,tf);
00082 fread(&fp->bSmooth,sizeof(unsigned char),1,tf);
00083 fread(&fp->imagemap,sizeof(short),1,tf);
00084 fread(&fp->material,sizeof(short),1,tf);
00085 }
00086 UpdateCounters();
00087 fclose(tf);
00088 }
00089 remove(workfile);
00090 return;
00091 EP1:
00092 SendPrgmQuery(IDQ_NOMEM1,0);
00093 DrawModel();
00094 UpdateCounters();
00095 fclose(tf);
00096 remove(workfile);
00097 return;
00098 }
00099
00100 long *GetPathList(long *np){
00101 vertex *Vp;
00102 long vp,vf,*va;
00103 double d,dmin,drange;
00104 long Npath=0;
00105 if(NvertSelect < 1)return NULL;
00106 dmin=(double)TVsizeX*(double)TVsizeX;
00107 drange=dmin/1024;
00108 vf= -1; vp=0; while(vp < Nvert){
00109 Vp=(MainVp+vp);
00110 if(Vp->status == SELECTED && intriview(Vp)){
00111 d=(double)(Vp->xyz[0]-NpointerX)*(double)(Vp->xyz[0]-NpointerX)
00112 +(double)(Vp->xyz[1]-NpointerY)*(double)(Vp->xyz[1]-NpointerY)
00113 +(double)(Vp->xyz[2]-NpointerZ)*(double)(Vp->xyz[2]-NpointerZ);
00114 if(d < dmin && d < drange){
00115 dmin=d;
00116 vf=vp;
00117 }
00118 }
00119 Vp->id=0;
00120 vp++;
00121 }
00122 if(vf < 0){
00123 SendPrgmQuery(IDQ_NOPATHSTART,0);
00124 return NULL;
00125 }
00126 if((va=(long *)X__Malloc(NvertSelect*sizeof(long))) == NULL){
00127 SendPrgmQuery(IDQ_NOMEM2,0);
00128 return NULL;
00129 }
00130 Npath=0; va[0]=vf; (MainVp+va[0])->id=1;
00131 (MainVp+vf)->status=DESELECTED; NvertSelect--; NvertDeselect++;
00132 vp=0; while(vp < Nvert){
00133 Vp=(MainVp+vp);
00134 if(Vp->status == SELECTED && Vp->id == 0 && connected(va[Npath],vp)){
00135 Npath++;
00136 va[Npath]=vp;
00137 Vp->id=1;
00138 Vp->status=DESELECTED;
00139 NvertSelect--; NvertDeselect++;
00140 vp=0;
00141 }
00142 else vp++;
00143 }
00144 Npath++;
00145 *np=Npath;
00146 return va;
00147 }
00148
00149 static void SetAccurateControl(HWND hwnd,int ID, double value){
00150 char tempstr[16];
00151 sprintf(tempstr,"%.2lf",value);
00152 SendDlgItemMessage(hwnd,ID,WM_SETTEXT,0,(LPARAM)tempstr);
00153 SendDlgItemMessage(hwnd,ID,EM_LIMITTEXT,(WPARAM)12,0);
00154 }
00155
00156 static double GetAccurateControl(HWND hwnd,int ID, double value){
00157 char tempstr[16];
00158 if(GetDlgItemText(hwnd,ID,tempstr,12) == 0)return value;
00159 value=atof(tempstr);
00160 return value;
00161 }
00162
00163 BOOL CALLBACK BuildAccurateCurveDlgProc(HWND hwnd, UINT msg,
00164 WPARAM wparam, LPARAM lparam){
00165 static double x,y,z,rx,ry,rz,x0,y0,z0;
00166 static long LastAccurateVertex= -1;
00167 static BOOL locked;
00168 switch( msg ) {
00169 case WM_PAINT:
00170 PaintDialogBackground(hwnd,ghinst_main);
00171 break;
00172 case WM_INITDIALOG:
00173 x0=x=(double)(NpointerX-rulerx)/ruler; rx=0.0;
00174 y0=y=(double)(NpointerY-rulery)/ruler; ry=0.0;
00175 z0=z=(double)(NpointerZ-rulerz)/ruler; rz=0.0;
00176 locked=TRUE;
00177 SetAccurateControl(hwnd,DLG_BUILD_AX,x);
00178 SetAccurateControl(hwnd,DLG_BUILD_AY,y);
00179 SetAccurateControl(hwnd,DLG_BUILD_AZ,z);
00180 SetAccurateControl(hwnd,DLG_BUILD_RX,rx);
00181 SetAccurateControl(hwnd,DLG_BUILD_RY,ry);
00182 SetAccurateControl(hwnd,DLG_BUILD_RZ,rz);
00183 locked=FALSE;
00184 CentreDialogOnCursor(hwnd);
00185 return (TRUE);
00186 case WM_COMMAND:
00187 switch(HIWORD(wparam)){
00188 case EN_CHANGE:
00189 if(LOWORD(wparam) == DLG_BUILD_AX && !locked){
00190 locked=TRUE;
00191 x=GetAccurateControl(hwnd,DLG_BUILD_AX,x);
00192 rx=x-x0;
00193 SetAccurateControl(hwnd,DLG_BUILD_RX,rx);
00194 locked=FALSE;
00195 }
00196 else if(LOWORD(wparam) == DLG_BUILD_RX && !locked){
00197 locked=TRUE;
00198 rx=GetAccurateControl(hwnd,DLG_BUILD_RX,rx);
00199 x=x0+rx;
00200 SetAccurateControl(hwnd,DLG_BUILD_AX,x);
00201 locked=FALSE;
00202 }
00203 if(LOWORD(wparam) == DLG_BUILD_AY && !locked){
00204 locked=TRUE;
00205 y=GetAccurateControl(hwnd,DLG_BUILD_AY,y);
00206 ry=y-y0;
00207 SetAccurateControl(hwnd,DLG_BUILD_RY,ry);
00208 locked=FALSE;
00209 }
00210 else if(LOWORD(wparam) == DLG_BUILD_RY && !locked){
00211 locked=TRUE;
00212 ry=GetAccurateControl(hwnd,DLG_BUILD_RY,ry);
00213 y=y0+ry;
00214 SetAccurateControl(hwnd,DLG_BUILD_AY,y);
00215 locked=FALSE;
00216 }
00217 if(LOWORD(wparam) == DLG_BUILD_AZ && !locked){
00218 locked=TRUE;
00219 z=GetAccurateControl(hwnd,DLG_BUILD_AZ,z);
00220 rz=z-z0;
00221 SetAccurateControl(hwnd,DLG_BUILD_RZ,rz);
00222 locked=FALSE;
00223 }
00224 else if(LOWORD(wparam) == DLG_BUILD_RZ && !locked){
00225 locked=TRUE;
00226 rz=GetAccurateControl(hwnd,DLG_BUILD_RZ,rz);
00227 z=z0+rz;
00228 SetAccurateControl(hwnd,DLG_BUILD_AZ,z);
00229 locked=FALSE;
00230 }
00231 break;
00232 default: break;
00233 }
00234 switch(LOWORD(wparam)){
00235 case DLG_BUILD_START:
00236 LastAccurateVertex= -1;
00237 case DLG_BUILD_MAKE:
00238 UpdateVertexHeap(Nvert+1); CreateVertex();
00239 (MainVp+Nvert-1)->xyz[0]=(long)(x*ruler)+rulerx;
00240 (MainVp+Nvert-1)->xyz[1]=(long)(y*ruler)+rulery;
00241 (MainVp+Nvert-1)->xyz[2]=(long)(z*ruler)+rulerz;
00242 DrawVerticesOnly((MainVp+Nvert-1));
00243 if(LastAccurateVertex >= 0){
00244 UpdateEdgeHeap(Nedge+1);
00245 CreateEdge(Nvert-1,LastAccurateVertex);
00246 DrawOneEdgeOnly((MainVp+Nvert-1),(MainVp+LastAccurateVertex));
00247 }
00248 LastAccurateVertex=Nvert-1;
00249 rx=ry=rz=0.0; x0=x; y0=y; z0=z;
00250 UpdateCounters();
00251 locked=TRUE;
00252 SetAccurateControl(hwnd,DLG_BUILD_AX,x);
00253 SetAccurateControl(hwnd,DLG_BUILD_AY,y);
00254 SetAccurateControl(hwnd,DLG_BUILD_AZ,z);
00255 SetAccurateControl(hwnd,DLG_BUILD_RX,rx);
00256 SetAccurateControl(hwnd,DLG_BUILD_RY,ry);
00257 SetAccurateControl(hwnd,DLG_BUILD_RZ,rz);
00258 locked=FALSE;
00259 break;
00260 case DLG_BUILD_DONE:
00261 LastAccurateVertex= -1;
00262 EndDialog(hwnd,0);
00263 return(TRUE);
00264 default:
00265 break;
00266 }
00267 break;
00268 default: break;
00269 }
00270 return(FALSE);
00271 }
00272
00273 typedef struct FACEEDGE {
00274 long v;
00275 long last,next,inc;
00276 vector n;
00277 vector p;
00278 } faceedge;
00279
00280 typedef struct FACEEDGELIST {
00281 struct FACEEDGE *f;
00282 long n,I,done_count;
00283 vector normal;
00284 } faceedgelist;
00285
00286 typedef struct NORMALS {
00287 vector n,nav;
00288 } normals;
00289
00290 static void ReverseCurve(faceedge *af, long Npath);
00291 static int CurveNormal(faceedgelist *fli);
00292 static void MakeNewCurveNormals(long i, faceedgelist *facelist);
00293 static long CurveInside(faceedgelist *fl, long i, long Ncurves);
00294 static void RemakeTheCurve(long i, long Ncurves,faceedgelist *facelist);
00295 static int edge_is_internal(faceedge *af, long Npath,
00296 long te, long ne, long fe,
00297 vector new_normal, vector N,
00298 int allow_all);
00299 static int edge_is_ok(long n,faceedge *f, vector ph, vector po,
00300 long ex1, long ex2);
00301 static void BevelCurve(long Ncurves, faceedgelist *facelist, double d,
00302 double angle, vector direction);
00303 static int point_inside_curve(vector v2, vector Nav, faceedge *af,
00304 long Npath, vector N);
00305 double GetDistanceFromCurves(point c_point, long Ncurves,
00306 faceedgelist *facelist);
00307
00308 static double bevel_angle=45.0;
00309
00310 static void MakeNewCurveNormals(long i, faceedgelist *facelist){
00311 long j,k,Npath;
00312 faceedge *af;
00313 vector v1,v2,v3;
00314 Npath=facelist[i].n;
00315 af=facelist[i].f;
00316 for(j=0;j<Npath;j++){
00317 VECCOPY(af[j].p,v1)
00318 k=af[j].next;
00319 VECCOPY(af[k].p,v2)
00320 VECSUB(v2,v1,v3)
00321 O_normalize(v3);
00322 CROSS(v3,facelist[i].normal,af[j].n)
00323 O_normalize(af[j].n);
00324 }
00325 }
00326
00327 static int edge_is_internal(faceedge *af, long Npath,
00328 long te, long ne, long fe,
00329 vector new_normal, vector N,
00330 int allow_all){
00331 vector p0,p1,pa,pb,p10,pba,pc;
00332 vector pte,pne,pac,n,vi,da,db,p01,vilast;
00333 vector vj,pn,pnb;
00334 long i,j,k,le,cross_count=0,last_allowed;
00335 double mu,mu1,dmin,d0,d1,d01;
00336 VECCOPY(af[te].p,pa)
00337 VECCOPY(af[ne].p,pb)
00338 VECSUB(pb,pa,pte)
00339 if(O_normalize(pte) == FAIL)return 0;
00340 VECCOPY(af[ne].p,pa)
00341 VECCOPY(af[fe].p,pb)
00342 VECSUB(pb,pa,pne)
00343 if(O_normalize(pne) == FAIL)return 0;
00344 if((d0=DOT(pte,pne)) > 0.9999){
00345 return 0;
00346 }
00347 else if(allow_all == 0 && d0 < -0.95){
00348 return 0;
00349 }
00350 VECCOPY(af[te].p,p0)
00351 VECCOPY(af[fe].p,p1)
00352 VECSUB(p1,p0,p10)
00353 VECCOPY(p10,p01)
00354 if(O_normalize(p01) == FAIL)return 0;
00355 CROSS(p01,N,new_normal)
00356 if(O_normalize(new_normal) == FAIL)return 0;
00357 VECSCALE(0.5,p10,pc)
00358 VECSUM(p0,pc,pc)
00359 last_allowed = -1;
00360 for(i=0;i<Npath;i++){
00361 if(af[i].inc == 1){
00362 VECCOPY(af[i].p,pa)
00363 j=af[i].next;
00364 VECCOPY(af[j].p,pb)
00365 VECCOPY(af[i].n,n)
00366 VECSUB(pa,pc,pac)
00367 mu1=DOT(n,new_normal);
00368 if(fabs(mu1) > 0.0001){
00369 mu=DOT(pac,n)/mu1;
00370 if(mu > 0.0000){
00371 VECSCALE(mu,new_normal,vi)
00372 VECSUM(pc,vi,vi)
00373 VECSUB(pb,pa,pba)
00374 k = -1; dmin = 1.0;
00375 if(fabs(pba[0]) > dmin){k=0; dmin =fabs(pba[0]);}
00376 if(fabs(pba[1]) > dmin){k=1; dmin =fabs(pba[1]);}
00377 if(fabs(pba[2]) > dmin){k=2; dmin =fabs(pba[2]);}
00378 if(k >= 0){
00379 mu1=(vi[k]-pa[k])/pba[k];
00380 if(fabs(mu1) < 0.0000001){
00381 k=af[i].last;
00382 VECCOPY(af[k].p,pn)
00383 VECSUB(pa,pn,pnb)
00384 d0=DOT(pba,p01); d1=DOT(pnb,p01);
00385 if(d0*d1 > 0.0 && k != last_allowed){
00386 cross_count++;
00387 }
00388 }
00389 else if(fabs(1.0-mu1) < 0.0000001){
00390 k=af[j].next;
00391 VECCOPY(af[k].p,pn)
00392 VECSUB(pn,pb,pnb)
00393 d0=DOT(pba,p01); d1=DOT(pnb,p01);
00394 if(d0*d1 > 0.0){
00395 cross_count++; last_allowed=i;
00396 }
00397 }
00398 else if(mu1 > 0.0 && mu1 < 1.0){
00399 cross_count++;
00400 }
00401 }
00402 }
00403 }
00404 }
00405 }
00406 if(cross_count%2 == 0)return 0;
00407 le = af[te].last;
00408 for(i=0;i<Npath;i++){
00409
00410
00411
00412
00413 if( !( i == le || i == te || i == ne || i == fe) && af[i].inc == 1){
00414 j=af[i].next;
00415 VECCOPY(af[i].p,pa)
00416 VECCOPY(af[j].p,pb)
00417 VECCOPY(af[i].n,n)
00418 VECSUB(pa,p0,da) d0=DOT(da,n);
00419 VECSUB(pa,p1,db) d1=DOT(db,n);
00420 d01=d0*d1;
00421 if(d01 < 0.0){
00422 mu1=DOT(p10,n);
00423 if(fabs(mu1) > 1.0){
00424 mu=d0/mu1;
00425 VECSCALE(mu,p10,vi)
00426 VECSUM(p0,vi,vi)
00427 VECSUB(pb,pa,pba)
00428 k = -1; dmin = 1.0;
00429 if(fabs(pba[0]) > dmin){k=0; dmin =fabs(pba[0]);}
00430 if(fabs(pba[1]) > dmin){k=1; dmin =fabs(pba[1]);}
00431 if(fabs(pba[2]) > dmin){k=2; dmin =fabs(pba[2]);}
00432 if(k >= 0){
00433 mu1=(vi[k]-pa[k])/pba[k];
00434 if(mu1 >= -0.0001 && mu1 < 1.0001){
00435 return 0;
00436 }
00437 }
00438 }
00439 }
00440 }
00441 }
00442 return 1;
00443 }
00444
00445 static int CurveNormal(faceedgelist *fli){
00446
00447
00448
00449
00450 long i,j,Npath;
00451 faceedge *af;
00452 vector v1,v2,v3,new_normal;
00453 Npath=fli->n;
00454 af=fli->f;
00455 POINT2VECTOR((MainVp+(af[0].v))->xyz,v1)
00456 j=1;
00457 RETRY:
00458 for(i=1;i<Npath-j;i++){
00459 POINT2VECTOR((MainVp+(af[i ].v))->xyz,v2)
00460 POINT2VECTOR((MainVp+(af[i+j].v))->xyz,v3)
00461 VECSUB(v2,v1,v2)
00462 VECSUB(v3,v1,v3)
00463 if(O_normalize(v2) != FAIL && O_normalize(v3) != FAIL &&
00464 fabs(DOT(v2,v3)) < 0.9){
00465 CROSS(v2,v3,new_normal)
00466 if(O_normalize(new_normal) != FAIL){
00467 goto GOTNORMAL;
00468 }
00469 }
00470 }
00471 if(j < Npath-3){
00472 j++;
00473 goto RETRY;
00474 }
00475 SendPrgmQuery(IDQ_NOTSUITABLECURVE,0);
00476 return FAIL;
00477 GOTNORMAL:
00478 VECCOPY(new_normal,fli->normal);
00479 return OK;
00480 }
00481
00482 static long CurveInside(faceedgelist *fl, long ii, long Ncurves){
00483
00484
00485 vector pc,p0,p1,p10,p01,new_normal,pa,pb,n,pac,pn,pnb,pba,vi;
00486 long i,j,k,l,cross_count,Npath,curvid = -1;
00487 double mu,mu1,dmin,mumin,mumumin=1.0e35;
00488 faceedge *af;
00489 af=fl[ii].f;
00490 POINT2VECTOR((MainVp+(af[0].v))->xyz,p0)
00491 POINT2VECTOR((MainVp+(af[1].v))->xyz,p1)
00492 VECSUB(p1,p0,p10)
00493 VECCOPY(p10,p01)
00494 if(O_normalize(p01) == FAIL)return -1;
00495 CROSS(p01,fl[ii].normal,new_normal)
00496 if(O_normalize(new_normal) == FAIL)return -1;
00497 VECSCALE(0.5,p10,pc)
00498 VECSUM(p0,pc,pc)
00499 for(l=0;l<Ncurves;l++){
00500 if(l == ii)continue;
00501 cross_count=0;
00502 af=fl[l].f;
00503 Npath=fl[l].n;
00504 mumin=1.0e35;
00505 for(i=0;i<Npath;i++){
00506 POINT2VECTOR((MainVp+(af[i].v))->xyz,pa)
00507 j=af[i].next;
00508 POINT2VECTOR((MainVp+(af[j].v))->xyz,pb)
00509 VECCOPY(af[i].n,n)
00510 VECSUB(pa,pc,pac)
00511 mu1=DOT(n,new_normal);
00512 if(fabs(mu1) > 0.0001){
00513 mu=DOT(pac,n)/mu1;
00514 if(mu > 0.0000){
00515 VECSCALE(mu,new_normal,vi)
00516 VECSUM(pc,vi,vi)
00517 VECSUB(pb,pa,pba)
00518 k = -1; dmin = 1.0;
00519 if(fabs(pba[0]) > dmin){k=0; dmin =fabs(pba[0]);}
00520 if(fabs(pba[1]) > dmin){k=1; dmin =fabs(pba[1]);}
00521 if(fabs(pba[2]) > dmin){k=2; dmin =fabs(pba[2]);}
00522 if(k >= 0){
00523 mu1=(vi[k]-pa[k])/pba[k];
00524 if(fabs(mu1) < 0.0000001){
00525 k=af[i].last;
00526 POINT2VECTOR((MainVp+(af[k].v))->xyz,pn)
00527 VECSUB(pa,pn,pnb)
00528 if(DOT(pba,p01)*DOT(pnb,p01) > 0.0)cross_count++;
00529 }
00530 else if(fabs(1.0-mu1) < 0.0000001){
00531 k=af[j].next;
00532 POINT2VECTOR((MainVp+(af[k].v))->xyz,pn)
00533 VECSUB(pn,pb,pnb)
00534 if(DOT(pba,p01)*DOT(pnb,p01) > 0.0)cross_count++;
00535 }
00536 else if(mu1 > 0.0 && mu1 < 1.0){
00537 cross_count++;
00538 }
00539 if(mu < mumin)mumin=mu;
00540 }
00541 }
00542 }
00543 }
00544 if(cross_count%2 == 1 && mumin <= mumumin){curvid=l; mumumin=mumin;}
00545 }
00546 return curvid;
00547 }
00548
00549 static int edge_is_ok(long Npath, faceedge *af, vector p0, vector p1,
00550 long ex1, long ex2){
00551
00552
00553 vector n,pa,pb,pba,vi,da,db,p10;
00554 double d0,d1,d01,mu,mu1,dmin;
00555 long i,j,k;
00556 VECSUB(p1,p0,p10)
00557 for(i=0;i<Npath;i++){
00558 if(i != ex1 && i != ex2){
00559 VECCOPY(af[i].p,pa)
00560 j=af[i].next;
00561 VECCOPY(af[j].p,pb)
00562 VECCOPY(af[i].n,n)
00563 VECSUB(pa,p0,da) d0=DOT(da,n);
00564 VECSUB(pa,p1,db) d1=DOT(db,n);
00565 d01=d0*d1;
00566 if(d01 < 0.0){
00567 mu1=DOT(p10,n);
00568 if(fabs(mu1) > 1.0){
00569 mu=d0/mu1;
00570 VECSCALE(mu,p10,vi)
00571 VECSUM(p0,vi,vi)
00572 VECSUB(pb,pa,pba)
00573 k = -1; dmin = 1.0;
00574 if(fabs(pba[0]) > dmin){k=0; dmin =fabs(pba[0]);}
00575 if(fabs(pba[1]) > dmin){k=1; dmin =fabs(pba[1]);}
00576 if(fabs(pba[2]) > dmin){k=2; dmin =fabs(pba[2]);}
00577 if(k >= 0){
00578 mu1=(vi[k]-pa[k])/pba[k];
00579 if(mu1 >= -0.0001 && mu1 < 1.0001){
00580 return 0;
00581 }
00582 }
00583 }
00584 }
00585 }
00586 }
00587 return 1;
00588 }
00589
00590 static void RemakeTheCurve(long ii, long Ncurves, faceedgelist *fl){
00591
00592
00593
00594 vector ph,po,pho,jv;
00595 long vh,vo;
00596 long i,j,k,id,nph,npo,npk,idh = -1,ido = -1,NNpath,je1,je2,j0,j1,j2,j3;
00597 faceedge *afh,*afo,*afk,*afn;
00598 double d,dmin=1.e35;
00599 nph=fl[ii].n;
00600 afh=fl[ii].f;
00601 id=fl[ii].I;
00602 npo=fl[id].n;
00603 afo=fl[id].f;
00604 for(i=0;i<nph;i++){
00605 for(j=0;j<npo;j++){
00606 vh=afh[i].v; vo=afo[j].v;
00607 VECCOPY(afh[i].p,ph)
00608 VECCOPY(afo[j].p,po)
00609 if(edge_is_ok(nph,afh,ph,po,i,afh[i].last) &&
00610 edge_is_ok(npo,afo,ph,po,j,afo[j].last) ){
00611 for(k=0;k<Ncurves;k++){
00612 if(k != ii && fl[k].I == id){
00613 npk=fl[k].n;
00614 afk=fl[k].f;
00615 if( ! edge_is_ok(npk,afk,ph,po, -1, -1))goto NOTOK;
00616 }
00617 }
00618 d=(po[0]-ph[0])*(po[0]-ph[0]) +
00619 (po[1]-ph[1])*(po[1]-ph[1]) +
00620 (po[2]-ph[2])*(po[2]-ph[2]);
00621 if(d < dmin){
00622 dmin=d; idh=i, ido=j;
00623 }
00624 NOTOK:;
00625 }
00626 }
00627 }
00628 if(idh == -1 || ido == -1)return;
00629 fl[ii].done_count=YES;
00630 NNpath=nph+npo+2;
00631
00632 if((afn=(faceedge *)X__Malloc(NNpath*sizeof(faceedge))) == NULL)return;
00633 j=0;
00634 if(ido > 0)for(i=0;i<ido;i++){
00635 afn[j].v=afo[i].v; VECCOPY(afo[i].n,afn[j].n) VECCOPY(afo[i].p,afn[j].p)
00636 j++;
00637 }
00638 afn[j].v=afo[ido].v; je1=j; VECCOPY(afo[ido].p,afn[j].p) j++;
00639 if(idh < nph)for(i=idh;i<nph;i++){
00640 afn[j].v=afh[i].v; VECCOPY(afh[i].n,afn[j].n) VECCOPY(afh[i].p,afn[j].p)
00641 j++;
00642 }
00643 if(idh > 0)for(i=0;i<idh;i++){
00644 afn[j].v=afh[i].v; VECCOPY(afh[i].n,afn[j].n) VECCOPY(afh[i].p,afn[j].p)
00645 j++;
00646 }
00647 afn[j].v=afh[idh].v; je2=j; VECCOPY(afh[idh].p,afn[j].p) j++;
00648 if(ido < npo)for(i=ido;i<npo;i++){
00649 afn[j].v=afo[i].v; VECCOPY(afo[i].n,afn[j].n) VECCOPY(afo[i].p,afn[j].p)
00650 j++;
00651 }
00652
00653 for(j=0;j<NNpath;j++){
00654 afn[j].inc=1;
00655 if (j == 0) {afn[j].last=NNpath-1; afn[j].next=1; }
00656 else if(j == NNpath-1){afn[j].last=j-1; afn[j].next=0; }
00657 else {afn[j].last=j-1; afn[j].next=j+1;}
00658 }
00659
00660
00661 for(j1=0;j1<NNpath;j1++){
00662 if(j1 == je1 || j1== je2){
00663 j0=afn[j1].last; j2=afn[j1].next; j3=afn[j2].next;
00664 VECSUB(afn[j1].p,afn[j0].p,pho)
00665 d=(pho[0]*pho[0])+(pho[1]*pho[1])+(pho[2]*pho[2]);
00666 if(d > 5.0e4){
00667 VECSCALE((1.0 - 200.0/sqrt(d)),pho,pho)
00668 VECSUM(afn[j0].p,pho,afn[j1].p)
00669 }
00670 VECSUB(afn[j3].p,afn[j2].p,pho)
00671 d=(pho[0]*pho[0])+(pho[1]*pho[1])+(pho[2]*pho[2]);
00672 if(d > 5.0e4){
00673 VECSCALE((1.0 - 200.0/sqrt(d)),pho,pho)
00674 VECSUB(afn[j3].p,pho,afn[j2].p)
00675 }
00676 VECSUB(afn[j2].p,afn[j1].p,pho)
00677 CROSS(pho,fl[id].normal,afn[j1].n)
00678 O_normalize(afn[j1].n);
00679 }
00680 }
00681 vh=afh[idh].v; vo=afo[ido].v;
00682
00683
00684 X__Free(afo); fl[id].f=afn; fl[id].n=NNpath;
00685 X__Free(afh); fl[ii].f=NULL; fl[ii].n=0; fl[ii].I = -1;
00686
00687 MakeNewCurveNormals(id,fl);
00688 CreateEdge(vh,vo);
00689
00690 return;
00691 }
00692
00693 int AutoFacetCurveWithHoles(int function, int visible, int atm,
00694 double ba, double bd){
00695 HCURSOR hSave;
00696 long vp,vf,lastface[3],vstart,vrestart;
00697 long i,j,k,Ncurves,Npath,NpathMax,te,ne,fe,iteration_count,iteration_max;
00698 int allow_all,loop_count,hole_cross_count,round_count,nround,ifail=OK;
00699 faceedgelist *facelist,*newfacelist;
00700 faceedge *af;
00701 double d,dx,angle;
00702 point c_point;
00703 vector v1,v2,v3,N,new_normal,bevel_normal;
00704 if(NvertSelect < 1 || NvertSelect > 32000)return FAIL;
00705 vrestart=-1;
00706 round_count=0; nround=0;
00707 if(function == 1){
00708 angle=(double)RequestNumEntry((short)bevel_angle,
00709 5,90,"Bevel angle"," Angle");
00710 if(angle < 0)return FAIL;
00711 bevel_angle=angle;
00712 }
00713 else if(function == 2){
00714 angle=90;
00715 nround=4;
00716 angle /= nround;
00717 }
00718 else if(function == 3){
00719 bevel_angle=ba;
00720 }
00721 EDIT_ACTION=YES;
00722 if(visible){
00723 hSave=SetCursor(ghcurWait);
00724 Save_Undo(0);
00725 }
00726 STARTAGAIN:
00727 vstart=vrestart;
00728 vrestart=Nvert-1;
00729 vp=Nvert-1; while(vp != vstart){(MainVp+vp)->id=0; vp--;}
00730 Ncurves=0; facelist=NULL; newfacelist=NULL;
00731 STILLCOUNTING:
00732 vp=Nvert-1; vf = -1; while(vp != vstart){
00733 if((MainVp+vp)->status == SELECTED && (MainVp+vp)->id == 0){vf=vp; break;}
00734 vp--;
00735 }
00736 if(vf < 0){
00737 if(Ncurves > 0)goto PROCESSNOW;
00738 else {ifail=FAIL; goto EXIT;}
00739 }
00740 Ncurves++;
00741 if(facelist == NULL)newfacelist=
00742 (faceedgelist *)X__Malloc(sizeof(faceedgelist)*Ncurves);
00743 else newfacelist=(faceedgelist *)X__Realloc(facelist,
00744 sizeof(faceedgelist)*Ncurves);
00745 if(newfacelist == NULL){
00746 if(facelist != NULL){
00747 for(i=0;i<Ncurves-1;i++){
00748 if(facelist[i].n > 0 && facelist[i].f != NULL)X__Free(facelist[i].f);
00749 }
00750 X__Free(facelist);
00751 SendPrgmQuery(IDQ_NOMEM2,0);
00752 }
00753 ifail=FAIL;
00754 goto EXIT;
00755 }
00756 facelist=newfacelist; facelist[Ncurves-1].n=0;
00757 if((af =
00758 (faceedge *)X__Malloc(NvertSelect*sizeof(faceedge))) == NULL){
00759 for(i=0;i<Ncurves;i++){
00760 if(facelist[i].n > 0 && facelist[i].f != NULL)X__Free(facelist[i].f);
00761 }
00762 X__Free(facelist);
00763 SendPrgmQuery(IDQ_NOMEM2,0);
00764 ifail=FAIL;
00765 goto EXIT;
00766 }
00767 facelist[Ncurves-1].f=af;
00768 af[0].v=vf; (MainVp+(af[0].v))->id=1; Npath=1;
00769 vp=Nvert-1; while(vp != vstart){
00770 if((MainVp+vp)->status == SELECTED &&
00771 (MainVp+vp)->id == 0 && connected(af[Npath-1].v,vp)){
00772 af[Npath ].v=vp;
00773 (MainVp+vp)->id=1;
00774 vp=Nvert-1;
00775 Npath++;
00776 }
00777 else vp--;
00778 }
00779 facelist[Ncurves-1].n=Npath;
00780 facelist[Ncurves-1].f = (faceedge *)X__Realloc(facelist[Ncurves-1].f,
00781 Npath*sizeof(faceedge));
00782 goto STILLCOUNTING;
00783 PROCESSNOW:
00784 for(k=0;k<Ncurves;k++){
00785 if(CurveNormal(&(facelist[k])) == FAIL){
00786 goto TERMINATE;
00787 ifail=FAIL;
00788 }
00789 Npath=facelist[k].n;
00790 af=facelist[k].f;
00791 for(i=0;i<Npath;i++){
00792 af[i].inc=1;
00793 if (i == 0) {af[i].next=1; af[i].last=Npath-1;}
00794 else if(i == Npath-1){af[i].next=0; af[i].last=i-1; }
00795 else {af[i].next=i+1; af[i].last=i-1; }
00796 POINT2VECTOR((MainVp+(af[i].v))->xyz,v1)
00797 VECCOPY(v1,af[i].p)
00798 j=af[i].next;
00799 POINT2VECTOR((MainVp+(af[j].v))->xyz,v2)
00800 VECSUB(v2,v1,v3)
00801 if(O_normalize(v3) == FAIL){
00802 SendPrgmQuery(IDQ_NOTSUITABLECURVE,0);
00803 ifail=FAIL; goto TERMINATE;
00804 }
00805 if(fabs(DOT(v3,facelist[k].normal)) > 0.05){
00806 SendPrgmQuery(IDQ_NOTPLANECURVE,0);
00807 ifail=FAIL; goto TERMINATE;
00808 }
00809 CROSS(v3,facelist[k].normal,af[i].n)
00810 if(O_normalize(af[i].n) == FAIL){
00811 SendPrgmQuery(IDQ_NOTSUITABLECURVE,0);
00812 ifail=FAIL; goto TERMINATE;
00813 }
00814 }
00815 }
00816 if(Ncurves > 1){
00817 for(i=0;i<Ncurves-1;i++)for(j=i+1;j<Ncurves;j++){
00818 if(fabs(DOT(facelist[i].normal,facelist[j].normal)) < 0.99999){
00819 SendPrgmQuery(IDQ_NOTSUITABLECURVE,0);
00820 ifail=FAIL; goto TERMINATE;
00821 }
00822 }
00823 }
00824 for(i=0;i<Ncurves;i++){
00825 facelist[i].I=CurveInside(facelist,i,Ncurves);
00826 facelist[i].done_count=NO;
00827 }
00828 for(i=0;i<Ncurves;i++){
00829 hole_cross_count=0;
00830 if((j=facelist[i].I) >= 0)while(j >= 0){
00831 hole_cross_count++;
00832 j=facelist[j].I;
00833 }
00834 if(hole_cross_count %2 == 0)facelist[i].I = -1;
00835 }
00836 for(i=0;i<Ncurves;i++){
00837 if(facelist[i].I < 0){
00838 Npath=facelist[i].n;
00839 af=facelist[i].f;
00840 for(j=0;j<Npath;j++){
00841 te=j; ne=af[te].next; fe=af[ne].next;
00842 if(edge_is_internal(af,Npath,te,ne,fe,v1,facelist[i].normal,1)){
00843 goto FOUNDPLANENORMAL1;
00844 }
00845 }
00846 SendPrgmQuery(IDQ_NOTSUITABLECURVE,0);
00847 ifail=FAIL;
00848 goto TERMINATE;
00849 FOUNDPLANENORMAL1:
00850 VECCOPY(af[te].p,v1)
00851 VECCOPY(af[ne].p,v2)
00852 VECCOPY(af[fe].p,v3)
00853 VECSUB(v2,v1,v2)
00854 VECSUB(v3,v1,v3)
00855 CROSS(v2,v3,v1)
00856 if(O_normalize(v1) == FAIL){
00857 SendPrgmQuery(IDQ_NOTSUITABLECURVE,0);
00858 ifail=FAIL; goto TERMINATE;
00859 }
00860 VECCOPY(v1,facelist[i].normal)
00861
00862 MakeNewCurveNormals(i,facelist);
00863 }
00864 }
00865 for(i=0;i<Ncurves;i++){
00866 if(facelist[i].I >= 0){
00867 Npath=facelist[i].n;
00868 af=facelist[i].f;
00869 for(j=0;j<Npath;j++){
00870 te=j; ne=af[te].next; fe=af[ne].next;
00871 if(edge_is_internal(af,Npath,te,ne,fe,v1,facelist[i].normal,1)){
00872 goto FOUNDPLANENORMAL2;
00873 }
00874 }
00875 SendPrgmQuery(IDQ_NOTSUITABLECURVE,0);
00876 ifail=FAIL;
00877 goto TERMINATE;
00878 FOUNDPLANENORMAL2:
00879 VECCOPY(af[te].p,v1)
00880 VECCOPY(af[ne].p,v2)
00881 VECCOPY(af[fe].p,v3)
00882 VECSUB(v2,v1,v2)
00883 VECSUB(v3,v1,v3)
00884 CROSS(v2,v3,v1)
00885 if(O_normalize(v1) == FAIL){
00886 SendPrgmQuery(IDQ_NOTSUITABLECURVE,0);
00887 ifail=FAIL; goto TERMINATE;
00888 }
00889 if(DOT(v1,facelist[facelist[i].I].normal) > 0.0){
00890 ReverseCurve(af,Npath);
00891 VECSCALE( -1.0,v1,facelist[i].normal)
00892 }
00893 else VECCOPY(v1,facelist[i].normal)
00894
00895 MakeNewCurveNormals(i,facelist);
00896 }
00897 }
00898 if(function > 0){
00899 if(function == 3){
00900 dx=bd;
00901 if(bevel_angle >= 0.0)bevel_normal[0]=1.0;
00902 else{
00903 bevel_normal[0] = -1.0;
00904 bevel_angle *= -1.0;
00905 }
00906 bevel_normal[1]=0.0;
00907 bevel_normal[2]=0.0;
00908 }
00909 else if(round_count == 0){
00910 c_point[0]=NpointerX; c_point[1]=NpointerY; c_point[2]=NpointerZ;
00911 dx=d=GetDistanceFromCurves(c_point,Ncurves,facelist);
00912 v1[0]= (double)NpointerX - facelist[0].f[0].p[0];
00913 v1[1]= (double)NpointerY - facelist[0].f[0].p[1];
00914 v1[2]= (double)NpointerZ - facelist[0].f[0].p[2];
00915 VECCOPY(facelist[0].normal,bevel_normal);
00916 if(DOT(bevel_normal,v1) < 0.0)VECSCALE(-1.0,bevel_normal,bevel_normal);
00917 }
00918 if(function == 2){
00919 dx=d*(cos((double)(round_count)*angle*PI/180.0) -
00920 cos((double)(round_count+1)*angle*PI/180.0));
00921 bevel_angle=angle*((double)round_count+0.5);
00922 }
00923 BevelCurve(Ncurves,facelist,dx,bevel_angle,bevel_normal);
00924 goto TERMINATE;
00925 }
00926
00927 Npath=2*Ncurves;
00928 for(k=0;k<Ncurves;k++){
00929 i=facelist[k].n+1;
00930 Npath += ((i+1)*i)/2;
00931 }
00932 if(!UpdateEdgeHeap(Nedge+Npath))goto TERMINATE;
00933 if(!UpdateFaceHeap(Nface+Npath+2))goto TERMINATE;
00934
00935
00936
00937 for(k=0;k<2;k++){
00938 for(i=0;i<Ncurves;i++){
00939 if(facelist[i].I >= 0 && facelist[i].done_count == NO)
00940 RemakeTheCurve(i,Ncurves,facelist);
00941 }
00942 }
00943
00944 for(k=0;k<Ncurves;k++){
00945 Npath=facelist[k].n;
00946 if(Npath >=4){
00947 af=facelist[k].f;
00948 VECCOPY(facelist[k].normal,N);
00949 NpathMax=Npath;
00950 te=0; loop_count=0; allow_all=0;
00951 iteration_count=0; iteration_max=2*Npath;
00952 while(Npath > 3){
00953 ne=af[te].next; fe=af[ne].next;
00954 if(edge_is_internal(af,NpathMax,te,ne,fe,new_normal,N,allow_all)){
00955 CreateEdge(af[te].v,af[fe].v);
00956 CreateFace(af[te].v,af[ne].v,af[fe].v);
00957
00958 af[ne].inc=0;
00959 af[te].next=fe;
00960 af[fe].last=te;
00961 VECCOPY(new_normal,af[te].n)
00962 Npath--;
00963 loop_count=0;
00964 allow_all=0;
00965 iteration_count=0;
00966 te=fe;
00967 }
00968 else{
00969 te=ne;
00970 }
00971 loop_count++;
00972 if(loop_count > Npath+3)allow_all=1;
00973 if(allow_all)iteration_count++;
00974 if(iteration_count > iteration_max){
00975 if(atm)SendPrgmQuery(IDQ_ATMFILLFAIL,0);
00976 else SendPrgmQuery(IDQ_FAILED,0);
00977 ifail=FAIL; goto TERMINATE;
00978 }
00979 if(GetAsyncKeyState(VK_ESCAPE) & 0x8000){ifail=FAIL; goto TERMINATE;}
00980 }
00981 for(j=0,i=0;i<NpathMax;i++){
00982 if(af[i].inc == 1){
00983 if(j > 2){
00984 if(atm)SendPrgmQuery(IDQ_ATMFILLFAIL,0);
00985 else SendPrgmQuery(IDQ_FAILED,0);
00986 ifail=FAIL; goto TERMINATE;
00987 }
00988 lastface[j++]=af[i].v;
00989 }
00990 }
00991 CreateFace(lastface[0],lastface[1],lastface[2]);
00992 }
00993 }
00994 TERMINATE:
00995 for(i=0;i<Ncurves;i++){
00996 if(facelist[i].n > 0 && facelist[i].f != NULL)X__Free(facelist[i].f);
00997 }
00998 X__Free(facelist);
00999 UpdateEdgeHeap(Nedge);
01000 UpdateFaceHeap(Nface);
01001 if(++round_count < nround)goto STARTAGAIN;
01002 if(visible){
01003 DrawModel();
01004 UpdateCounters();
01005 }
01006 EXIT:
01007 if(visible){
01008 SetCursor(hSave);
01009 }
01010 return ifail;
01011 }
01012
01013 static void ReverseCurve(faceedge *af, long Npath){
01014 long i;
01015 long vt;
01016 vector pt;
01017 for(i=0;i<Npath/2;i++){
01018 vt=af[i].v; af[i].v = af[Npath-1-i].v; af[Npath-1-i].v=vt;
01019 VECCOPY(af[i].p,pt)
01020 VECCOPY(af[Npath-1-i].p,af[i].p)
01021 VECCOPY(pt,af[Npath-1-i].p)
01022 }
01023 }
01024
01025 static void BevelCurve(long Ncurves, faceedgelist *facelist, double d,
01026 double angle, vector direction){
01027 long i,j,k,Npath;
01028 faceedge *af;
01029 normals *VV;
01030 vector N,Nav,v1,v2,v3,vab;
01031 double dd,dplane;
01032 int inside,add_point,first_vertex;
01033 long lv,fv,sv,vp;
01034
01035 Npath=1; for(k=0;k<Ncurves;k++)Npath +=facelist[k].n+1;
01036 if(!UpdateVertexHeap(Nvert+Npath*2))return;
01037 if(!UpdateEdgeHeap(Nedge+Npath*4))return;
01038 if(!UpdateFaceHeap(Nface+Npath*4))return;
01039
01040 sv=Nvert-1;
01041 for(i=0;i<Ncurves;i++){
01042 Npath=facelist[i].n;
01043 af=facelist[i].f;
01044 VECCOPY(facelist[i].normal,N)
01045 if((VV=(normals *)X__Malloc(Npath*sizeof(normals))) == NULL){
01046 SendPrgmQuery(IDQ_NOMEM2,0);
01047 continue;
01048 }
01049 for(j=0;j<Npath;j++){
01050 POINT2VECTOR((MainVp+(af[j].v))->xyz,v1)
01051 k=af[j].next;
01052 POINT2VECTOR((MainVp+(af[k].v))->xyz,v2)
01053 VECSUB(v2,v1,v3)
01054 O_normalize(v3);
01055 CROSS(v3,N,af[j].n)
01056 O_normalize(af[j].n);
01057 }
01058 for(j=0;j<Npath;j++){
01059 k=af[j].last;
01060 VECSUM(af[j].n,af[k].n,Nav);
01061 O_normalize(Nav);
01062 POINT2VECTOR((MainVp+(af[j].v))->xyz,v1)
01063 VECSUM(v1,Nav,v2)
01064 inside=point_inside_curve(v2,Nav,af,Npath,N);
01065 if((inside && facelist[i].I >= 0) || ((! inside) && facelist[i].I < 0)){
01066 VECSCALE(-1.0,Nav,VV[j].nav)
01067 VECSCALE(-1.0,af[j].n,VV[j].n)
01068 }
01069 else{
01070 VECCOPY(Nav,VV[j].nav)
01071 VECCOPY(af[j].n,VV[j].n)
01072 }
01073 }
01074 lv = -1, fv = -1; first_vertex=YES;
01075 for(j=0;j<Npath;j++){
01076 POINT2VECTOR((MainVp+(af[j].v))->xyz,v1)
01077 k=af[j].next;
01078 POINT2VECTOR((MainVp+(af[k].v))->xyz,v2)
01079 VECSUB(v2,v1,vab)
01080 O_normalize(vab);
01081 k=af[j].last;
01082 #define OBTUSE_A -0.7071
01083 if(DOT(vab,VV[j].nav) < OBTUSE_A){
01084 VECSCALE(d,VV[k].n,v2)
01085 VECSUM(v1,v2,v3)
01086 CreateVertex(); if(fv < 0)fv=Nvert-1;
01087 VECTOR2POINT(v3,(MainVp+Nvert-1)->xyz)
01088 CreateEdge(af[j].v,Nvert-1);
01089 if(lv >= 0){
01090 CreateEdge(Nvert-1,lv);
01091 CreateEdge(Nvert-1,af[k].v);
01092 CreateFace(Nvert-1,af[k].v,af[j].v);
01093 CreateFace(Nvert-1,lv,af[k].v);
01094 }
01095 lv=Nvert-1;
01096 VECSCALE(d,VV[j].n,v2)
01097 VECSUM(v1,v2,v3)
01098 CreateVertex(); if(fv < 0)fv=Nvert-1;
01099 VECTOR2POINT(v3,(MainVp+Nvert-1)->xyz)
01100 CreateEdge(af[j].v,Nvert-1);
01101 CreateEdge(lv,Nvert-1);
01102 CreateFace(lv,Nvert-1,af[j].v);
01103 lv=Nvert-1;
01104 }
01105 else{
01106 dd=fabs(DOT(VV[j].nav,VV[j].n));
01107 if(dd < 1.e-10)dd=d;
01108 else dd=d/dd;
01109 POINT2VECTOR((MainVp+(af[k].v))->xyz,v2)
01110 CROSS(N,VV[k].nav,Nav)
01111 O_normalize(Nav);
01112 dplane=DOT(VV[j].nav,Nav);
01113 if(fabs(dplane) < 1.e-10)add_point=YES;
01114 else{
01115 VECSUB(v2,v1,v3);
01116 dplane=DOT(v3,Nav)/dplane;
01117 if(dplane < 0.0 || dplane >= dd)add_point=YES;
01118 else add_point=NO;
01119 }
01120 if(add_point == YES){
01121 VECSCALE(dd,VV[j].nav,v2)
01122 VECSUM(v1,v2,v3)
01123 CreateVertex(); if(fv < 0)fv=Nvert-1;
01124 if(lv >= 0){
01125 CreateEdge(lv,Nvert-1);
01126 CreateEdge(Nvert-1,af[k].v);
01127 CreateFace(Nvert-1,af[k].v,af[j].v);
01128 CreateFace(Nvert-1,lv,af[k].v);
01129 }
01130 lv=Nvert-1;
01131 VECTOR2POINT(v3,(MainVp+Nvert-1)->xyz)
01132 CreateEdge(af[j].v,Nvert-1);
01133 }
01134 else{
01135 if(lv >= 0){
01136 CreateEdge(af[j].v,lv);
01137 CreateFace(af[j].v,lv,af[k].v);
01138
01139
01140 VV[j].nav[0]=(double)((MainVp+lv)->xyz[0] - (MainVp+af[j].v)->xyz[0]);
01141 VV[j].nav[1]=(double)((MainVp+lv)->xyz[1] - (MainVp+af[j].v)->xyz[1]);
01142 VV[j].nav[2]=(double)((MainVp+lv)->xyz[2] - (MainVp+af[j].v)->xyz[2]);
01143 O_normalize(VV[j].nav);
01144 }
01145 if(j == 0)first_vertex=NO;
01146 }
01147 }
01148 (MainVp+af[j].v)->status=DESELECTED; NvertSelect--; NvertDeselect++;
01149 }
01150
01151 if(fv >= 0 && lv >= 0){
01152 CreateEdge(lv,fv);
01153 CreateEdge(lv,af[0].v);
01154 CreateFace(lv,fv,af[0].v);
01155 CreateFace(lv,af[0].v,af[Npath-1].v);
01156 if(first_vertex == NO){
01157 CreateEdge(fv,af[0].v);
01158 CreateFace(fv,af[1].v,af[0].v);
01159 }
01160 }
01161 X__Free(VV);
01162 }
01163 if(angle < 89){
01164 d=d/tan(angle/180.0*PI);
01165 vp=Nvert-1; while(vp != sv){
01166 (MainVp+vp)->xyz[0]=(long)((double)(MainVp+vp)->xyz[0] + d*direction[0]);
01167 (MainVp+vp)->xyz[1]=(long)((double)(MainVp+vp)->xyz[1] + d*direction[1]);
01168 (MainVp+vp)->xyz[2]=(long)((double)(MainVp+vp)->xyz[2] + d*direction[2]);
01169 vp--;
01170 }
01171 }
01172 UpdateVertexHeap(Nvert);
01173 return;
01174 }
01175
01176 static int point_inside_curve(vector v2, vector Nav, faceedge *af,
01177 long Npath, vector N){
01178
01179 vector pa,pb,pba,pav,n,vi,pn,pnb,p01;
01180 double mu,mu1,dmin;
01181 long i,j,k,cross_count=0;
01182 CROSS(Nav,N,p01)
01183 for(i=0;i<Npath;i++){
01184 POINT2VECTOR((MainVp+(af[i].v))->xyz,pa)
01185 j=af[i].next;
01186 POINT2VECTOR((MainVp+(af[j].v))->xyz,pb)
01187 VECCOPY(af[i].n,n)
01188 VECSUB(pa,v2,pav)
01189 mu1=DOT(n,Nav);
01190 if(fabs(mu1) > 0.0001){
01191 mu=DOT(pav,n)/mu1;
01192 if(mu > 0.0000){
01193 VECSCALE(mu,Nav,vi)
01194 VECSUM(v2,vi,vi)
01195 VECSUB(pb,pa,pba)
01196 k = -1; dmin = 1.0;
01197 if(fabs(pba[0]) > dmin){k=0; dmin =fabs(pba[0]);}
01198 if(fabs(pba[1]) > dmin){k=1; dmin =fabs(pba[1]);}
01199 if(fabs(pba[2]) > dmin){k=2; dmin =fabs(pba[2]);}
01200 if(k >= 0){
01201 mu1=(vi[k]-pa[k])/pba[k];
01202
01203 if(fabs(mu1) < 0.0001){
01204 k=af[j].last;
01205 POINT2VECTOR((MainVp+(af[k].v))->xyz,pn)
01206 VECSUB(pa,pn,pnb)
01207 if(DOT(pba,p01)*DOT(pnb,p01) > 0.0)cross_count++;
01208 }
01209 else if(fabs(1.0-mu1) < 0.0001){
01210 k=af[j].next;
01211 POINT2VECTOR((MainVp+(af[k].v))->xyz,pn)
01212 VECSUB(pn,pb,pnb)
01213 if(DOT(pba,p01)*DOT(pnb,p01) > 0.0)cross_count++;
01214 }
01215 else if(mu1 >= 0.0001 && mu1 <= 0.9999)cross_count++;
01216 }
01217 }
01218 }
01219 }
01220 if(cross_count%2 == 1)return 1;
01221 return 0;
01222 }
01223
01224 double GetDistanceFromCurves(point c_point, long Ncurves,
01225 faceedgelist *facelist){
01226
01227 vector dp;
01228 double a,b,c,d,dmin=1.e35,mu;
01229 long i,j,Npath,found=0;
01230 faceedge *af;
01231 vertex *vp1,*vp2;
01232 for(i=0;i<Ncurves;i++){
01233 Npath=facelist[i].n;
01234 af=facelist[i].f;
01235 for(j=0;j<Npath;j++){
01236 vp1=(MainVp+af[j].v); vp2=(MainVp+af[af[j].next].v);
01237 a=(double)(vp2->xyz[0]-vp1->xyz[0]);
01238 b=(double)(vp2->xyz[1]-vp1->xyz[1]);
01239 c=(double)(vp2->xyz[2]-vp1->xyz[2]);
01240 mu=(a*((double)c_point[0]-(double)(vp1->xyz[0]))
01241 +b*((double)c_point[1]-(double)(vp1->xyz[1]))
01242 +c*((double)c_point[2]-(double)(vp1->xyz[2])))/(a*a+b*b+c*c);
01243 if(mu > 0.0 && mu < 1.0){
01244 found=1;
01245 dp[0]=(double)(vp1->xyz[0] - c_point[0]);
01246 dp[1]=(double)(vp1->xyz[1] - c_point[1]);
01247 dp[2]=(double)(vp1->xyz[2] - c_point[2]);
01248 d=fabs(DOT(af[j].n,dp));
01249 if(d < dmin)dmin=d;
01250 }
01251 }
01252 }
01253 if(found)return dmin;
01254 else return TVsizeX/20;
01255 }
01256
01257
01258
01259 static int sort_sections(long *i, long *j){
01260 if (*i < *j)return -1;
01261 else if(*i > *j)return 1;
01262 else return 0;
01263 }
01264
01265 static long section_intersect(long x, long x1, long x2, long y1, long y2){
01266 double grad;
01267 grad = (double)(y2-y1)/(double)(x2-x1);
01268 return (long)( (double)y1 + grad*((double)(x-x1)) );
01269 }
01270
01271 void UnPlan(void){
01272 HCURSOR hSave;
01273 vertex *Vp,*V0,*V1;
01274 long vp,vx,*vo=NULL,vlast,vend;
01275 double d,dmin,drange,zscale,xscale,zdif,xdif;
01276 long NpathX,Nsections=0,i,j,k,l,m,ymin1,ymax1,ymin2,ymax2,
01277 ymax,ymin,xmin,xmax,zmin,zmax,zcentre,xcentre,zc,xc,
01278 y,z1,z2,x1,x2,*sections=NULL,Ne1=0,Ne2=0,Nvo=0,TOLL=MINUNIT;
01279 long ep,*el1=NULL,*el2=NULL;
01280 int p,special=0;
01281 if(NvertSelect > 32000){
01282 SendPrgmQuery(IDQ_WIRETOOBIG,0);
01283 return;
01284 }
01285 if(NvertSelect == 0){
01286 #if 0
01287 vlast=MainVp;
01288 LoadDXF(0);
01289 if(MainVp == vlast)goto EXIT;
01290 special=1;
01291 vp=vlast; while(vp != NULL){
01292 if(vp->status == DESELECTED)vp->status=INEDITOR;
01293 vp->id=0;
01294 vp=vp->last;
01295 }
01296 vend=MainVp;
01297 HideCursor(); DrawCursor(waiticon); ShowCursor();
01298 j=k=l=0;
01299 vp=MainVp; while(vp != vlast){
01300 if(vp->id == 20){
01301 m=vp->xyz[0]; vp->xyz[0]=vp->xyz[1]; vp->xyz[1] = -m;
01302 vp->id=0; j++;
01303 }
01304 else if(vp->id == 40){
01305 m=vp->xyz[0]; vp->xyz[0]=vp->xyz[1]; vp->xyz[1] = -m;
01306 m=vp->xyz[2]; vp->xyz[2]=vp->xyz[1]; vp->xyz[1] = m;
01307 vp->id=1; k++;
01308 }
01309 else if(vp->id == 30){
01310 m=vp->xyz[0]; vp->xyz[0]=vp->xyz[1]; vp->xyz[1] = -m;
01311 m=vp->xyz[0]; vp->xyz[0]=vp->xyz[2]; vp->xyz[2] = -m;
01312 vp->id=0; vp->status=DESELECTED; NvertSelect--; NvertDeselect++; l++;
01313 }
01314 else{
01315 vp->id=0; vp->status=INEDITOR; NvertSelect--; NvertDeselect++;
01316 }
01317 vp=vp->last;
01318 }
01319 if(j == 0 || k == 0 || l == 0)goto EXIT;
01320 TOLL = MINUNIT/4;
01321 goto DOIT;
01322 #endif
01323 }
01324 if(NvertSelect < 4 || NvertDeselect < 4 || Nedge < 12)return;
01325 dmin=(double)TVsizeX*(double)TVsizeX; drange=dmin/1024;
01326 vx=-1;
01327 vp=0; Vp=MainVp;
01328 while(vp < Nvert){
01329 if(Vp->status == SELECTED && intriview(Vp)){
01330 d=(double)(Vp->xyz[0]-NpointerX)*(double)(Vp->xyz[0]-NpointerX)
01331 +(double)(Vp->xyz[1]-NpointerY)*(double)(Vp->xyz[1]-NpointerY)
01332 +(double)(Vp->xyz[2]-NpointerZ)*(double)(Vp->xyz[2]-NpointerZ);
01333 if(d < dmin && d < drange){
01334 dmin=d;
01335 vx=vp;
01336 }
01337 }
01338 Vp->id=0;
01339 vp++; Vp++;
01340 }
01341 if(vx < 0){
01342 SendPrgmQuery(IDQ_NOPATHSTART,0);
01343 return;
01344 }
01345 else if(SendPrgmQuery(IDQ_UNPLAN,2) != IDYES)return;
01346 if (GetAsyncKeyState(VK_SHIFT) & 0x8000)TOLL = MINUNIT/2;
01347 else if(GetAsyncKeyState(VK_CONTROL) & 0x8000)TOLL = MINUNIT/4;
01348 else if(GetAsyncKeyState(VK_MENU) & 0x8000)TOLL = MINUNIT/8;
01349 else TOLL = MINUNIT;
01350 hSave=SetCursor(ghcurWait);
01351 Save_Undo(0);
01352 (MainVp+vx)->id=1;
01353 vp=0; while(vp < Nvert){
01354 Vp=(MainVp+vp);
01355 if(Vp->status == SELECTED && Vp->id == 0 && connected(vx,vp)){
01356 vx=vp;
01357 Vp->id=1;
01358 vp=0;
01359 }
01360 else vp++;
01361 }
01362
01363 vp=0; while(vp < Nvert){
01364 Vp=(MainVp+vp);
01365 if((Vp->status == SELECTED && Vp->id == 0) ||
01366 Vp->status == DESELECTED){
01367 if(Nsections == 0){
01368 if((sections=(long *)X__Malloc(sizeof(long))) == NULL)goto ABRT;
01369 *(sections) = Vp->xyz[1];
01370 Nsections=1;
01371 }
01372 else{
01373 for(i=0;i<Nsections;i++){
01374 if(abs(Vp->xyz[1] - *(sections+i)) < TOLL)goto BYPASS;
01375 }
01376 if((sections=(long *)X__Realloc(sections,(Nsections+1)*sizeof(long)))
01377 == NULL)goto ABRT;
01378 *(sections+Nsections)=Vp->xyz[1];
01379 Nsections++;
01380 BYPASS:;
01381 }
01382 }
01383 vp++;
01384 }
01385 qsort(sections,Nsections,sizeof(long),(void *)sort_sections);
01386 ep=0; while(ep < Nedge){
01387 V0=(MainVp+(MainEp+ep)->V[0]); V1=(MainVp+(MainEp+ep)->V[1]);
01388 if(V0->status == DESELECTED &&
01389 V1->status == DESELECTED){
01390 if(el1 == NULL){
01391 if( (el1=(long *)X__Malloc((long)sizeof(long)) ) == NULL)goto ABRT;
01392 }
01393 else{
01394 if( (el1=(long *)X__Realloc(el1,(Ne1+1)*(long)sizeof(long)) )
01395 == NULL)goto ABRT;
01396 }
01397 el1[Ne1]=ep;
01398 Ne1++;
01399 }
01400 else if(V0->status == SELECTED && V0->id == 0 &&
01401 V1->status == SELECTED && V1->id == 0){
01402 if(el2 == NULL){
01403 if( (el2=(long *)X__Malloc((long)sizeof(long)) ) == NULL)goto ABRT;
01404 }
01405 else {
01406 if( (el2=(long *)X__Realloc(el2,(Ne2+1)*(long)sizeof(long)) )
01407 == NULL)goto ABRT;
01408 }
01409 el2[Ne2]=ep;
01410 Ne2++;
01411 }
01412 ep++;
01413 }
01414 xmin = zmin = MAXUNIT;
01415 xmax = zmax = -MAXUNIT;
01416 vp=0; Vp=MainVp; while(vp < Nvert){
01417 if(Vp->status == SELECTED){
01418 if(Vp->id == 0){
01419 Vp->status=DESELECTED; NvertSelect--; NvertDeselect++;
01420 }
01421 else{
01422 if(Vp->xyz[0] < xmin)xmin=Vp->xyz[0];
01423 if(Vp->xyz[0] > xmax)xmax=Vp->xyz[0];
01424 if(Vp->xyz[2] < zmin)zmin=Vp->xyz[2];
01425 if(Vp->xyz[2] > zmax)zmax=Vp->xyz[2];
01426 if(vo == NULL){
01427 if( (vo=(long *)X__Malloc((Nvo+1)*(long)sizeof(long)) )
01428 == NULL)goto ABRT;
01429 }
01430 else {
01431 if( (vo=(long *)X__Realloc(vo,(Nvo+1)*(long)sizeof(long)) )
01432 == NULL)goto ABRT;
01433 }
01434 vo[Nvo++]=vp;
01435 }
01436 }
01437 vp++; Vp++;
01438 }
01439 zcentre=(zmax+zmin)/2; xcentre=(xmax+xmin)/2;
01440 if(zmax == zmin || xmax == xmin)goto EXIT;
01441 zdif=(double)(zmax-zmin); xdif=(double)(xmax-xmin);
01442 ymax1 = -MAXUNIT; ymin1 = MAXUNIT;
01443 for(i=0;i<Ne1;i++){
01444 ep=el1[i];
01445 V0=(MainVp+(MainEp+ep)->V[0]); V1=(MainVp+(MainEp+ep)->V[1]);
01446 if(V0->xyz[1] < ymin1)ymin1=V0->xyz[1];
01447 if(V1->xyz[1] < ymin1)ymin1=V1->xyz[1];
01448 if(V0->xyz[1] > ymax1)ymax1=V0->xyz[1];
01449 if(V1->xyz[1] > ymax1)ymax1=V1->xyz[1];
01450 }
01451 ymax2 = -MAXUNIT; ymin2 = MAXUNIT;
01452 for(i=0;i<Ne2;i++){
01453 ep=el2[i];
01454 V0=(MainVp+(MainEp+ep)->V[0]); V1=(MainVp+(MainEp+ep)->V[1]);
01455 if(V0->xyz[1] < ymin2)ymin2=V0->xyz[1];
01456 if(V1->xyz[1] < ymin2)ymin2=V1->xyz[1];
01457 if(V0->xyz[1] > ymax2)ymax2=V0->xyz[1];
01458 if(V1->xyz[1] > ymax2)ymax2=V1->xyz[1];
01459 }
01460 ymin=max(ymin1,ymin2); ymax=min(ymax1,ymax2);
01461 for(i=0,p=0;i<Nsections;i++){
01462 y=sections[i];
01463 if(y >= ymin && y <= ymax){
01464 z1 = MAXUNIT; z2 = -MAXUNIT;
01465 for(j=0;j<Ne1;j++){
01466 ep=el1[j];
01467 V0=(MainVp+(MainEp+ep)->V[0]); V1=(MainVp+(MainEp+ep)->V[1]);
01468 if( (V0->xyz[1] <= y && V1->xyz[1] >= y ) ||
01469 (V1->xyz[1] <= y && V0->xyz[1] >= y ) ){
01470 if(!(V0->xyz[1] == y && V1->xyz[1] == y)){
01471 m=section_intersect(y,V0->xyz[1],V1->xyz[1],
01472 V0->xyz[2],V1->xyz[2]);
01473 if(m <= z1)z1=m;
01474 if(m >= z2)z2=m;
01475 }
01476 }
01477 }
01478 x1 = MAXUNIT; x2 = -MAXUNIT;
01479 for(j=0;j<Ne2;j++){
01480 ep=el2[j];
01481 V0=(MainVp+(MainEp+ep)->V[0]); V1=(MainVp+(MainEp+ep)->V[1]);
01482 if( (V0->xyz[1] <= y && V1->xyz[1] >= y ) ||
01483 (V1->xyz[1] <= y && V0->xyz[1] >= y ) ){
01484 if(!(V0->xyz[1] == y && V1->xyz[1] == y)){
01485 m=section_intersect(y,V0->xyz[1],V1->xyz[1],
01486 V0->xyz[0],V1->xyz[0]);
01487 if(m <= x1)x1=m;
01488 if(m >= x2)x2=m;
01489 }
01490 }
01491 }
01492 if(z1 == MAXUNIT || x1 == MAXUNIT || z2 == -MAXUNIT || x2 == -MAXUNIT)
01493 goto OMIT;
01494 zc=(z1+z2)/2; xc=(x1+x2)/2;
01495 if (p == 0)AddCopy(0);
01496 else if(!CreateAttachedCopy(1))goto ABRT;
01497 if(zmax-zmin == 0)zscale=0.0;
01498 zscale=(double)(z2-z1)/zdif;
01499 xscale=(double)(x2-x1)/xdif;
01500 m=0;
01501 vp=0; Vp=MainVp; while(vp < Nvert){
01502 if(Vp->status == SELECTED){
01503 Vp->xyz[1]=y;
01504 Vp->xyz[2]=(long)(zscale*(double)((MainVp+vo[m])->xyz[2]-zcentre)
01505 +(double)zc);
01506 Vp->xyz[0]=(long)(xscale*(double)((MainVp+vo[m])->xyz[0]-xcentre)
01507 +(double)xc);
01508 m++;
01509 }
01510 vp++; Vp++;
01511 }
01512 p++;
01513 OMIT:;
01514 }
01515 }
01516 goto EXIT;
01517 ABRT:;
01518 EXIT:;
01519 vp=0; Vp=MainVp; while(vp < Nvert){
01520 if(Vp->status == SELECTED){
01521 Vp->status=DESELECTED; NvertSelect--; NvertDeselect++;
01522 }
01523 vp++; Vp++;
01524 }
01525 if(vo != NULL)X__Free(vo);
01526 if(sections != NULL)X__Free(sections);
01527 if(el1 != NULL)X__Free(el1);
01528 if(el2 != NULL)X__Free(el2);
01529 if(special){
01530 #if 0
01531 vp=vend; while(vp != NULL){
01532 if(vp->status == INEDITOR)vp->status=DESELECTED;
01533 vp=vp->last;
01534 }
01535 vp=vend; while(vp != vlast){
01536 if(vp->status == DESELECTED){
01537 vp->status=SELECTED; NvertSelect++; NvertDeselect--;
01538 }
01539 vp=vp->last;
01540 }
01541 EraseVertex(0);
01542 #endif
01543 }
01544 SetCursor(hSave);
01545 reset_mod_maxview(1);
01546 DrawModel(); UpdateCounters();
01547 }