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 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <math.h>
00029 #include <windows.h>
00030
00031 #include "struct.h"
00032 #include "dstruct.h"
00033
00034 #include "simplify.h"
00035
00036 static HWND hParent;
00037 static HINSTANCE hThisInstance;
00038
00039 #if __WATCOMC__
00040 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00041 #else
00042 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00043 #endif
00044 switch (dwReason) {
00045 case DLL_PROCESS_ATTACH: {
00046 hThisInstance=hDLL;
00047 if(hDLL == NULL)MessageBox( GetFocus()," NULL instance",NULL, MB_OK);
00048 break;
00049 }
00050 case DLL_PROCESS_DETACH:
00051 break;
00052 }
00053 return TRUE;
00054 }
00055
00056 BOOL _Xmodeler
00057 (HWND parent_window,HWND info_window,X__STRUCTURE *lpevi){
00058 HCURSOR hSave;
00059 static struct bp {long iter; double ean,fan;} d;
00060 double fan=5.0,ean=5.0;
00061 long nloop=5;
00062 lpEVI=lpevi;
00063 hParent=parent_window;
00064 d.iter=nloop; d.fan=fan; d.ean=ean;
00065 if(DialogBoxParam(hThisInstance,MAKEINTRESOURCE(DLG_SIM),hParent,
00066 (DLGPROC)SimplifyDlgProc,(LPARAM)&d) == FALSE)return FALSE;
00067 nloop=d.iter; ean=d.ean; fan=d.fan;
00068 hSave=SetCursor(LoadCursor(NULL,IDC_WAIT));
00069 SimplifyObject(nloop,fan,ean);
00070 SetCursor(hSave);
00071 return TRUE;
00072 }
00073
00074 static BOOL CALLBACK SimplifyDlgProc(HWND hwnd, UINT msg,
00075 WPARAM wparam, LPARAM lparam){
00076 BOOL err;
00077 int i;
00078 static struct bp {long iter; double ean,fan;} *dp;
00079 double angle;
00080 char str[32];
00081 switch( msg ) {
00082 case WM_INITDIALOG:
00083 dp=(struct bp *)lparam;
00084 SetDlgItemInt(hwnd,DLG_SIM_ITER,dp->iter,FALSE);
00085 sprintf(str,"%.2lf",dp->fan);
00086 SetDlgItemText(hwnd,DLG_SIM_FACE,(LPCTSTR)str);
00087 SendDlgItemMessage(hwnd,DLG_SIM_FACE,EM_LIMITTEXT,(WPARAM)12,0);
00088 sprintf(str,"%.2lf",dp->ean);
00089 SetDlgItemText(hwnd,DLG_SIM_EDGE,(LPCTSTR)str);
00090 SendDlgItemMessage(hwnd,DLG_SIM_EDGE,EM_LIMITTEXT,(WPARAM)12,0);
00091 CentreDlgOnS(hwnd);
00092 return (TRUE);
00093 case WM_COMMAND:
00094 switch(LOWORD(wparam)){
00095 case IDCANCEL:
00096 EndDialog(hwnd,FALSE);
00097 return(TRUE);
00098 case IDOK:
00099 if(GetDlgItemText(hwnd,DLG_SIM_FACE,str,10) == 0){
00100 EndDialog(hwnd,FAIL);
00101 return TRUE;
00102 }
00103 angle=atof(str);
00104 if(angle < 0.1 || angle > 45.0){
00105 EndDialog(hwnd,FAIL);
00106 return TRUE;
00107 }
00108 dp->fan=angle;
00109 if(GetDlgItemText(hwnd,DLG_SIM_EDGE,str,10) == 0){
00110 EndDialog(hwnd,FAIL);
00111 return TRUE;
00112 }
00113 angle=atof(str);
00114 if(angle < 0.1 || angle > 45.0){
00115 EndDialog(hwnd,FAIL);
00116 return TRUE;
00117 }
00118 dp->ean=angle;
00119 i=GetDlgItemInt(hwnd,DLG_SIM_ITER,&err,FALSE);
00120 if(err)dp->iter=i;
00121 EndDialog(hwnd,TRUE);
00122 return(TRUE);
00123 default:
00124 break;
00125 }
00126 break;
00127 default: break;
00128 }
00129 return(FALSE);
00130 }
00131
00132 static vtyadj *ListAdjFaces(selectedface *wf, long nf,
00133 selectededge *we, long ne, long *nvll){
00134 edge *e;
00135 face *f;
00136 vertex *vp;
00137 vtyadj *vl=NULL;
00138 long c,nvl=0;
00139 long *fl,i,j,k,id,id0,id1,id2,fjd,fkd,n,m,kk,nl[3],ml[3];
00140 vp=MainVp; for(c=0;c<Nvert;c++){
00141 if(vp->status == DESELECTED){
00142 vp->id=nvl;
00143 nvl++;
00144 }
00145 else vp->id = -10;
00146 vp++;
00147 }
00148 if((vl=(vtyadj *)X__Malloc(nvl*sizeof(vtyadj))) == NULL)return 0;
00149 for(i=0;i<nvl;i++){
00150 vl[i].nf=0; vl[i].ne=0;
00151 vl[i].flist=NULL; vl[i].elist=NULL;
00152 }
00153 i=0; vp=MainVp; for(c=0;c<Nvert;c++){
00154 if(vp->status == DESELECTED){
00155 vl[i].v=c;
00156 i++;
00157 }
00158 vp++;
00159 }
00160 for(i=0;i<nf;i++){
00161 f=(MainFp+wf[i].f);
00162 for(j=0;j<3;j++){
00163 id=(MainVp+(f->V[j]))->id;
00164 fl=vl[id].flist;
00165 n=vl[id].nf;
00166 if(fl == NULL){
00167 if((fl=(long *)X__Malloc(sizeof(long))) == NULL)return NULL;
00168 }
00169 else{
00170 if((fl=(long *)X__Realloc(fl,(n+1)*sizeof(long))) == NULL)return NULL;
00171 }
00172 fl[n]=i;
00173 vl[id].flist=fl;
00174 vl[id].nf=n+1;
00175 }
00176 }
00177 for(i=0;i<nf;i++){
00178 f=(MainFp+wf[i].f);
00179 id0=(MainVp+(f->V[0]))->id;
00180 id1=(MainVp+(f->V[1]))->id;
00181 id2=(MainVp+(f->V[2]))->id;
00182 nl[0]=id0; ml[0]=id1;
00183 nl[1]=id1; ml[1]=id2;
00184 nl[2]=id2; ml[2]=id0;
00185 for(kk=0;kk<3;kk++){
00186 wf[i].fa[kk] = -1;
00187 if((n=vl[nl[kk]].nf) > 0 && (m=vl[ml[kk]].nf) > 0){
00188 for(j=0;j<n;j++){
00189 fjd=vl[nl[kk]].flist[j];
00190 for(k=0;k<m;k++){
00191 fkd=vl[ml[kk]].flist[k];
00192 if(fkd == fjd && fkd != i){
00193 wf[i].fa[kk]=fkd;
00194 goto ENDF;
00195 }
00196 }
00197 }
00198 }
00199 ENDF:;
00200 }
00201 }
00202 for(i=0;i<ne;i++){
00203 e=(MainEp+we[i].e);
00204 id0=(MainVp+(e->V[0]))->id; id1=(MainVp+(e->V[1]))->id;
00205 kk=0; we[i].ea[0] = we[i].ea[1] = -1;
00206 if((n=vl[id0].nf) > 0 && (m=vl[id1].nf) > 0){
00207 for(j=0;j<n;j++){
00208 fjd=vl[id0].flist[j];
00209 for(k=0;k<m;k++){
00210 fkd=vl[id1].flist[k];
00211 if(fkd == fjd){
00212 we[i].ea[kk]=fkd;
00213 kk++;
00214 if(kk == 2)goto ENDEE;
00215 }
00216 }
00217 }
00218 ENDEE:;
00219 }
00220 }
00221 for(i=0;i<ne;i++){
00222 e=(MainEp+we[i].e);
00223 for(j=0;j<2;j++){
00224 id=(MainVp+(e->V[j]))->id;
00225 fl=vl[id].elist;
00226 n=vl[id].ne;
00227 if(fl == NULL){
00228 if((fl=(long *)X__Malloc(sizeof(long))) == NULL)return NULL;
00229 }
00230 else {
00231 if((fl=(long *)X__Realloc(fl,(n+1)*sizeof(long))) == NULL)return NULL;
00232 }
00233 fl[n]=i;
00234 vl[id].elist=fl;
00235 vl[id].ne=n+1;
00236 }
00237 }
00238 for(i=0;i<nf;i++){
00239 f=(MainFp+wf[i].f);
00240 id0=(MainVp+(f->V[0]))->id;
00241 id1=(MainVp+(f->V[1]))->id;
00242 id2=(MainVp+(f->V[2]))->id;
00243 nl[0]=id0; ml[0]=id1;
00244 nl[1]=id1; ml[1]=id2;
00245 nl[2]=id2; ml[2]=id0;
00246 for(kk=0;kk<3;kk++){
00247 wf[i].ea[kk] = -1;
00248 if((n=vl[nl[kk]].ne) > 0 && (m=vl[ml[kk]].ne) > 0){
00249 for(j=0;j<n;j++){
00250 fjd=vl[nl[kk]].elist[j];
00251 for(k=0;k<m;k++){
00252 fkd=vl[ml[kk]].elist[k];
00253 if(fkd == fjd){
00254 wf[i].ea[kk]=fkd;
00255 goto ENDE;
00256 }
00257 }
00258 }
00259 }
00260 ENDE:;
00261 }
00262 }
00263 *nvll=nvl;
00264 return vl;
00265 }
00266
00267 static void FreeAdjFaces(vtyadj *vl,long nvl){
00268 int i;
00269 if(vl != NULL && nvl > 0){
00270 for(i=0;i<nvl;i++){
00271 if(vl[i].flist != NULL)X__Free(vl[i].flist);
00272 if(vl[i].elist != NULL)X__Free(vl[i].elist);
00273 }
00274 X__Free(vl);
00275 }
00276 }
00277
00278 static void SimplifyObject(long nloop, double fan, double ean){
00279 selectededge *we;
00280 selectedface *w;
00281 face *f;
00282 vertex *vp,*v0,*v1,*v2;
00283 edge *e;
00284 vector du,dv,n,p0,p1,p2;
00285 long c,i,loop,n_work_face,n_work_edge,phase,nvl;
00286 vtyadj *vl;
00287 if(NvertSelect == 0)return;
00288 if(NvertSelect > 32000)return;
00289 if(MainFp == NULL)return;
00290 fan=cos(fan*0.0174532);
00291 ean=cos(ean*0.0174532);
00292 vp=MainVp; for(i=0;i<Nvert;i++){
00293 if(vp->status == SELECTED){
00294 vp->status=DESELECTED;
00295 NvertSelect--; NvertDeselect++;
00296 }
00297 else if(vp->status == DESELECTED){
00298 vp->status=INEDITOR;
00299 }
00300 vp->id=0;
00301 vp++;
00302 }
00303 phase=0;
00304 PHASE:
00305 n_work_face=0,n_work_edge=0;
00306 w=NULL; we=NULL;
00307 f=MainFp; for(c=0;c<Nface;c++){
00308 v0=(MainVp+f->V[0]); v1=(MainVp+f->V[1]); v2=(MainVp+f->V[2]);
00309 if(v0->status == DESELECTED &&
00310 v1->status == DESELECTED &&
00311 v1->status == DESELECTED)n_work_face++;
00312 f++;
00313 }
00314 e=MainEp; for(c=0;c<Nedge;c++){
00315 v0=(MainVp+e->V[0]); v1=(MainVp+e->V[1]);
00316 if(v0->status == DESELECTED && v1->status == DESELECTED)n_work_edge++;
00317 e++;
00318 }
00319 if((w=(selectedface *)X__Malloc((n_work_face+1)*(long)sizeof(selectedface)))
00320 == NULL)goto BERR;
00321 if((we=(selectededge *)X__Malloc((n_work_edge+1)*(long)sizeof(selectededge)))
00322 == NULL)goto BERR;
00323 n_work_face=0; n_work_edge=0;
00324 f=MainFp; for(c=0;c<Nface;c++){
00325 v0=(MainVp+f->V[0]); v1=(MainVp+f->V[1]); v2=(MainVp+f->V[2]);
00326 POINT2VECTOR(v0->xyz,p0)
00327 POINT2VECTOR(v1->xyz,p1)
00328 POINT2VECTOR(v2->xyz,p2)
00329 VECSUB(p1,p0,dv)
00330 VECSUB(p2,p0,du)
00331 if(v0->status == DESELECTED &&
00332 v1->status == DESELECTED &&
00333 v2->status == DESELECTED){
00334 w[n_work_face].f=c;
00335 w[n_work_face].del=0;
00336 for(i=0;i<3;i++){
00337 w[n_work_face].fa[i] = -1;
00338 w[n_work_face].ea[i] = -1;
00339 }
00340 CROSS(dv,du,n)
00341 if(O_normalize(n) == FAIL){
00342 VECSUB(p0,p1,dv)
00343 VECSUB(p2,p1,du)
00344 CROSS(dv,du,n)
00345 if(O_normalize(n) == FAIL){
00346 VECSUB(p0,p2,dv)
00347 VECSUB(p1,p2,du)
00348 CROSS(dv,du,n)
00349 if(O_normalize(n) == FAIL)goto BERR2;
00350 }
00351 }
00352 VECCOPY(n,w[n_work_face].n)
00353 n_work_face++;
00354 }
00355 f++;
00356 }
00357 e=MainEp; for(c=0;c<Nedge;c++){
00358 v0=(MainVp+e->V[0]); v1=(MainVp+e->V[1]);
00359 if(v0->status == DESELECTED && v1->status == DESELECTED){
00360 we[n_work_edge].e=c;
00361 we[n_work_edge].ea[0] = we[n_work_edge].ea[1] = -1;
00362 n_work_edge++;
00363 }
00364 e++;
00365 }
00366 if(n_work_face == 0)goto QUIT;
00367 vl=ListAdjFaces(w,n_work_face,we,n_work_edge,&nvl);
00368
00369 if(phase == 0)for(loop=0;loop<nloop;loop++){
00370 if(!Simplify1(vl,nvl,w,n_work_face,we,n_work_edge,fan,ean))break;
00371 }
00372
00373 if(phase == 1)for(loop=0;loop<nloop;loop++){
00374 if(!DeTesselate(vl,nvl,w,n_work_face,we,n_work_edge,fan))break;
00375 }
00376
00377 EraseVertex(1);
00378 FreeAdjFaces(vl,nvl);
00379 goto QUIT;
00380 BERR2:
00381 MessageBox(NULL,"Normal - Problem",NULL,MB_OK); goto QUIT;
00382 goto QUIT;
00383 BERR:
00384 MessageBox(NULL,"Memory Error",NULL,MB_OK);
00385 QUIT:
00386 if(w != NULL)X__Free(w);
00387 if(we != NULL)X__Free(we);
00388 if(phase == 0){phase=1; goto PHASE;}
00389 vp=MainVp; for(c=0;c<Nvert;c++){
00390 if(vp->status == INEDITOR)vp->status=DESELECTED;
00391 vp++;
00392 }
00393 return;
00394 }
00395
00396 static int co_attrib(long if1, long if2){
00397 int i;
00398 face *f1,*f2;
00399 f1=(MainFp+if1); f2=(MainFp+if2);
00400 if(f1->material != f2->material)return 0;
00401 if(f1->imagemap != f2->imagemap)return 0;
00402 return 1;
00403 }
00404
00405 static int co_planar(vector n1, vector n2, double angle){
00406 if(fabs(DOT(n1,n2)) > angle)return 1;
00407 return 0;
00408 }
00409
00410 static int co_linear(long e1, long e2, selectededge *we, double angle){
00411 vertex *v0,*v1;
00412 vector a,b;
00413 edge *ep;
00414 if(e1 < 0 || e2 < 0){
00415 return 0;
00416 }
00417 ep=(MainEp+we[e1].e);
00418 v0=(MainVp+ep->V[0]); v1=(MainVp+ep->V[1]);
00419 VECSUB((double)v0->xyz,(double)v1->xyz,a)
00420 if(O_normalize(a) == FAIL)return 0;
00421 ep=(MainEp+we[e2].e);
00422 v0=(MainVp+ep->V[0]); v1=(MainVp+ep->V[1]);
00423 VECSUB((double)v0->xyz,(double)v1->xyz,b)
00424 if(O_normalize(b) == FAIL)return 0;
00425 if(fabs(DOT(a,b)) > angle)return 1;
00426 return 0;
00427 }
00428
00429 static void IdentifyGeometry(long i, long j,
00430 long *f0, long *f1, long *f2,
00431 long *e0, long *e1, long *e2,
00432 long *fx, long *ex,
00433 long *fxx, long *exx,
00434 long *fxxx, long *exxx,
00435 long *v0, long *v1, long *v2,
00436 long *vll, long *vlll,
00437 selectedface *wf,selectededge *we){
00438 face *f;
00439 long va,vb;
00440 long k,l,ll,e,m[3]={1,2,0},n[3]={2,0,1};
00441 *f0=wf[i].fa[j]; *f1=wf[i].fa[m[j]]; *f2=wf[i].fa[n[j]];
00442 *e0=wf[i].ea[j]; *e1=wf[i].ea[m[j]]; *e2=wf[i].ea[n[j]];
00443 f=(MainFp+wf[i].f);
00444 *v0 = f->V[j]; *v1 = f->V[m[j]]; *v2=f->V[n[j]];
00445 *fx = -1; *ex = -1; *fxx = -1; *exx = -1; *vll = -1;
00446 *fxxx = -1; *exxx = -1; *vlll = -1;
00447 if(*f1 >= 0){
00448 for(k=0;k<3;k++){
00449 if(wf[*f1].fa[k] != i){
00450 e=wf[*f1].ea[k]; if(e < 0)return;
00451 va=(MainEp+(we[e].e))->V[0]; vb=(MainEp+(we[e].e))->V[1];
00452 if(*v1 == va || *v1 == vb){
00453 *ex=e; *fx=wf[*f1].fa[k];
00454 if(*fx < 0 || e < 0)return;
00455 if((MainEp+(we[e].e))->V[0] != *v1) *vll = (MainEp+(we[e].e))->V[0];
00456 else *vll = (MainEp+(we[e].e))->V[1];
00457 for(l=0;l<3;l++){
00458 if(wf[*fx].fa[l] != *f1){
00459 e=wf[*fx].ea[l];
00460 if(e >= 0){
00461 va=(MainEp+(we[e].e))->V[0]; vb=(MainEp+(we[e].e))->V[1];
00462 if(*v1 == va || *v1 == vb){
00463 if(e != *e0){
00464 *exx=e; *fxx=wf[*fx].fa[l];
00465 if(*fxx < 0 || e < 0)return;
00466 if((MainEp+(we[e].e))->V[0] != *v1)
00467 *vlll = (MainEp+(we[e].e))->V[0];
00468 else
00469 *vlll = (MainEp+(we[e].e))->V[1];
00470 for(ll=0;ll<3;ll++){
00471 if(wf[*fxx].fa[ll] != *f1){
00472 e=wf[*fxx].ea[ll];
00473 if(e >= 0){
00474 va=(MainEp+(we[e].e))->V[0];
00475 vb=(MainEp+(we[e].e))->V[1];
00476 if(*v1 == va || *v1 == vb){
00477 if(e != *e0){
00478 *exxx=e; *fxxx=wf[*fxx].fa[ll];
00479 return;
00480 }
00481 }
00482 }
00483 }
00484 }
00485 return;
00486 }
00487 }
00488 }
00489 }
00490 }
00491 return;
00492 }
00493 }
00494 }
00495 }
00496 return;
00497 }
00498
00499 static void IdentifyAdjacent(long i,long f0, long v0, long v1,
00500 long *fl, long *el, long *fn, long *en,
00501 long *fnn, long *vn, long *vnn,
00502 selectedface *wf,selectededge *we){
00503 long k,l;
00504 face *f;
00505 edge *e;
00506 *vn = -1; *vnn = -1;
00507 *fl = *fn = *el = *en = *fnn = -1;
00508 for(k=0;k<3;k++){
00509 f=(MainFp+wf[f0].f);
00510 if(f->V[k] != v0 && f->V[k] != v1)*vn=f->V[k];
00511 if((l=wf[f0].fa[k]) != i){
00512 if(l >= 0){
00513 f=(MainFp+wf[l].f);
00514 if(f->V[0] == v0 || f->V[1] == v0 || f->V[2] == v0) *fl = l;
00515 if(f->V[0] == v1 || f->V[1] == v1 || f->V[2] == v1) *fn = l;
00516 }
00517 if(wf[f0].ea[k] >= 0){
00518 e=(MainEp+we[wf[f0].ea[k]].e);
00519 if(e->V[0] == v0 || e->V[1] == v0) *el = wf[f0].ea[k];
00520 if(e->V[0] == v1 || e->V[1] == v1) *en = wf[f0].ea[k];
00521 }
00522 }
00523 }
00524 if(*fn >= 0){
00525 for(k=0;k<3;k++){
00526 f=(MainFp+wf[*fn].f);
00527 if(f->V[k] != v1 && f->V[k] != *vn)*vnn=f->V[k];
00528 if((l=wf[*fn].fa[k]) != f0){
00529 if(l >= 0){
00530 f=(MainFp+wf[l].f);
00531 if(f->V[0] == v1 || f->V[1] == v1 || f->V[2] == v1) *fnn = l;
00532 }
00533 }
00534 }
00535 }
00536 }
00537
00538 static int BadAngle(long iv0, long iv1, long ivn, long ivnn){
00539 vector a,b,c;
00540 double c1,c2;
00541 vertex *v0,*v1,*vn,*vnn;
00542 if(iv0 < 0 || iv1 < 0 || ivn < 0 || ivnn < 0)return 1;
00543 v0=(MainVp+iv0); v1=(MainVp+iv1); vn=(MainVp+ivn); vnn=(MainVp+ivnn);
00544 if(v0 == NULL || v1 == NULL || vn == NULL || vnn == NULL)return 1;
00545 VECSUB((double)vnn->xyz,(double)vn->xyz,a)
00546 VECSUB((double)v1->xyz,(double)vn->xyz,b)
00547 VECSUB((double)v0->xyz,(double)vn->xyz,c)
00548 if(O_normalize(a) == FAIL)return 1;
00549 if(O_normalize(b) == FAIL)return 1;
00550 if(O_normalize(c) == FAIL)return 1;
00551 if(acos(DOT(b,a))+acos(DOT(b,c)) > PI - 0.1)return 1;
00552 return 0;
00553 }
00554
00555 static int Simplify1(vtyadj *vl, long nvl,
00556 selectedface *w, long nf,
00557 selectededge *we, long ne,
00558 double fan, double ean){
00559 face *ff;
00560 edge *ee;
00561 long f,e;
00562 long vp,v0,v1,v2,vn,vnn,vll,vlll;
00563 long c,h,i,j,k,l,m,n,second_type=0;
00564 long f0,f1,f2,e0,e1,e2,fx,ex,fxx,exx,fxxx,exxx,fl,fn,el,en,fnn,ev;
00565 int reduc;
00566 reduc=0;
00567 for(i=0;i<nf;i++){
00568 if(w[i].del)continue;
00569 for(h=0;h<2;h++){
00570 for(j=0;j<3;j++){
00571 IdentifyGeometry(i,j,&f0,&f1,&f2,&e0,&e1,&e2,
00572 &fx,&ex,&fxx,&exx,&fxxx,&exxx,
00573 &v0,&v1,&v2,&vll,&vlll,
00574 w,we);
00575 if(f1 >= 0){
00576 if(co_planar(w[i].n,w[f1].n,fan) &&
00577 co_attrib(w[i].f,w[f1].f)){
00578 if(co_linear(e0,ex,we,ean)){
00579 second_type=0;
00580 SECONDTYPE:
00581 if(f0 < 0 && fx >= 0)goto LOOP;
00582 if(f0 >= 0 && fx < 0)goto LOOP;
00583 if(f0 >= 0){
00584 IdentifyAdjacent(i,f0,v0,v1,&fl,&el,&fn,&en,&fnn,&vn,&vnn,w,we);
00585 if(fn == fx)fnn = -1;
00586 else if(BadAngle(v0,v1,vn,vnn))goto LOOP;
00587 if(fn != fx && fnn != fx)goto LOOP;
00588 if(fn < 0)goto LOOP;
00589 if(!co_attrib(w[f0].f,w[fn].f))goto LOOP;
00590 if(fnn >= 0 && !co_attrib(w[fn].f,w[fnn].f))goto LOOP;
00591 }
00592 w[i].del=1;
00593 if(e2 < 0)goto LOOP;
00594 for(k=0;k<2;k++){
00595 if(we[e2].ea[k] == i)we[e2].ea[k]=f1;
00596 }
00597 for(k=0;k<3;k++){
00598 if(w[f1].fa[k] == i)w[f1].fa[k]=f2;
00599 if(w[f1].ea[k] == e1)w[f1].ea[k]=e2;
00600 if(f2 >= 0){
00601 if(w[f2].fa[k] == i)w[f2].fa[k]=f1;
00602 }
00603 }
00604
00605
00606
00607
00608 f=w[f1].f; ff=(MainFp+f);
00609 for(k=0;k<3;k++){
00610 if(ff->V[k] == v1)ff->V[k]=v0;
00611 }
00612 e=we[ex].e; ee=(MainEp+e);
00613 for(k=0;k<2;k++){
00614 if(ee->V[k] == v1)ee->V[k]=v0;
00615 }
00616 (MainVp+v1)->status=SELECTED;
00617 NvertSelect++; NvertDeselect--; reduc=1;
00618 if(second_type > 0){
00619 f=w[fxx].f; ff=(MainFp+f);
00620 for(k=0;k<3;k++){
00621 if(ff->V[k] == v1)ff->V[k]=v0;
00622 }
00623 e=we[exx].e; ee=(MainEp+e);
00624 for(k=0;k<2;k++){
00625 if(ee->V[k] == v1)ee->V[k]=v0;
00626 }
00627 if(second_type > 1){
00628 f=w[fxxx].f; ff=(MainFp+f);
00629 for(k=0;k<3;k++){
00630 if(ff->V[k] == v1)ff->V[k]=v0;
00631 }
00632 e=we[exxx].e; ee=(MainEp+e);
00633 for(k=0;k<2;k++){
00634 if(ee->V[k] == v1)ee->V[k]=v0;
00635 }
00636 }
00637 }
00638
00639
00640
00641 if(f0 >= 0){
00642 w[f0].del=1;
00643 f=w[fn].f; ff=(MainFp+f);
00644 for(k=0;k<3;k++){
00645 if(fl >= 0)if(w[fl].fa[k] == f0)w[fl].fa[k]=fn;
00646 if(fn >= 0)if(w[fn].fa[k] == f0)w[fn].fa[k]=fl;
00647 if(fn >= 0)if(w[fn].ea[k] == en)w[fn].ea[k]=el;
00648 if(ff->V[k] == v1)ff->V[k]=v0;
00649 }
00650 for(k=0;k<2;k++){
00651 if(we[el].ea[k] == f0)we[el].ea[k]=fn;
00652 }
00653 if(fnn >= 0){
00654 f=w[fnn].f; ff=(MainFp+f);
00655 for(k=0;k<3;k++){
00656 if((l=w[fnn].ea[k]) >= 0){
00657 e=we[l].e; ee=(MainEp+e);
00658 if(ee->V[0] == v1)ee->V[0]=v0;
00659 if(ee->V[1] == v1)ee->V[1]=v0;
00660 }
00661 if(ff->V[k] == v1)ff->V[k]=v0;
00662 }
00663 }
00664 }
00665 goto BREAKOUT;
00666 }
00667 else{
00668 if(fx >= 0 && ex >= 0 && e0 >= 0 && exx >= 0 && vll >= 0){
00669 if(co_planar(w[i].n,w[fx].n,fan) &&
00670 co_attrib(w[i].f,w[fx].f) &&
00671 !BadAngle(v0,v1,v2,vll)){
00672 if(co_linear(e0,exx,we,ean)){
00673 m=fx; fx=fxx; fxx=m;
00674 m=ex; ex=exx; exx=m;
00675 second_type=1;
00676 goto SECONDTYPE;
00677 }
00678 else if(fxx >= 0 && exxx >= 0 && vlll >= 0){
00679 if(co_planar(w[i].n,w[fxx].n,fan) &&
00680 co_attrib(w[i].f,w[fxx].f) &&
00681 !BadAngle(v2,v1,vll,vlll) &&
00682 co_linear(e0,exxx,we,ean)){
00683 m=fx; fx=fxxx; n=fxx; fxx=m; fxxx=n;
00684 m=ex; ex=exxx; n=exx; exx=m; exxx=n;
00685 second_type=2;
00686 goto SECONDTYPE;
00687 }
00688 }
00689 }
00690 }
00691 }
00692 }
00693 }
00694 LOOP:;
00695 }
00696 f=w[i].f; ff=(MainFp+f);
00697 vp=ff->V[0]; ff->V[0]=ff->V[2]; ff->V[2]=vp;
00698 k=w[i].fa[0]; w[i].fa[0]=w[i].fa[1]; w[i].fa[1]=k;
00699 k=w[i].ea[0]; w[i].ea[0]=w[i].ea[1]; w[i].ea[1]=k;
00700 }
00701 BREAKOUT:;
00702 }
00703 return reduc;
00704 }
00705
00706
00707 static int VertexAdj(vtyadj vl, selectedface *wf, selectededge *we,
00708 long *f0, long *f1, long *f2,
00709 long *e0, long *e1, long *e2){
00710 face *f;
00711 edge *e;
00712 long i,j,l,nf=0,ne=0;
00713 *f0 = *f1 = *f2 = *e0 = *e1 =*e2 = -1;
00714 if((MainVp+(vl.v))->status == SELECTED)goto XXIT;
00715 if(vl.nf < 3 || vl.ne < 3)goto XXIT;
00716 for(i=0;i<vl.nf;i++){
00717 l=vl.flist[i]; f=(MainFp+wf[l].f);
00718 for(j=0;j<3;j++){
00719 if((MainVp+f->V[j])->status == SELECTED)goto JUMPIT;
00720 }
00721 if(l == *f0 || l == *f1 || l == *f2)goto JUMPIT;
00722 if(nf == 0) *f0 = l;
00723 if(nf == 1) *f1 = l;
00724 if(nf == 2) *f2 = l;
00725 nf++;
00726 JUMPIT:
00727 if(nf > 3)goto XXIT;
00728 }
00729 for(i=0;i<vl.ne;i++){
00730 l=vl.elist[i]; e=(MainEp+we[l].e);
00731 if((MainVp+e->V[0])->status == DESELECTED &&
00732 (MainVp+e->V[1])->status == DESELECTED){
00733 if(ne == 0) *e0 = l;
00734 if(ne == 1) *e1 = l;
00735 if(ne == 2) *e2 = l;
00736 ne++;
00737 if(ne > 3){ nf=0; goto XXIT; }
00738 }
00739 }
00740 XXIT:
00741 return nf;
00742 }
00743
00744 static void GetOppositeFaceEdge(long v, long f, selectedface *wf,
00745 long *fo, long *eo){
00746 long i,m[3]={1,2,0};
00747 face *ff;
00748 *fo = *eo = -1;
00749 ff= (MainFp+wf[f].f);
00750 for(i=0;i<3;i++){
00751 if(ff->V[i] == v){
00752 *fo = wf[f].fa[m[i]];
00753 *eo = wf[f].ea[m[i]];
00754 }
00755 }
00756 return;
00757 }
00758
00759
00760 static long GetCommonVertex(long v, long f1, long f2){
00761 long i,j;
00762 long vp;
00763 for(i=0;i<3;i++){
00764 vp=(MainFp+f1)->V[i];
00765 for(j=0;j<3;j++){
00766 if((MainFp+f2)->V[j] == vp){
00767 if(vp != v)return vp;
00768 }
00769 }
00770 }
00771 return -1;
00772 }
00773
00774 static int DeTesselate(vtyadj *vl, long nvl,
00775 selectedface *wf, long nf,
00776 selectededge *we, long ne,
00777 double angle){
00778 int reduc=0;
00779 long i,j,k,l;
00780 long f0,f1,f2,e0,e1,e2,fo1,fo2,eo1,eo2;
00781 long v,vid;
00782 face *f;
00783 for(i=0;i<nvl;i++){
00784 if(VertexAdj(vl[i],wf,we,&f0,&f1,&f2,&e0,&e1,&e2) == 3 &&
00785 co_planar(wf[f0].n,wf[f1].n,angle) && co_attrib(wf[f0].f,wf[f1].f) &&
00786 co_planar(wf[f0].n,wf[f2].n,angle) && co_attrib(wf[f0].f,wf[f2].f)){
00787 v=vl[i].v;
00788 (MainVp+v)->status=SELECTED; NvertSelect++; NvertDeselect--; reduc=1;
00789 GetOppositeFaceEdge(v,f1,wf,&fo1,&eo1);
00790 GetOppositeFaceEdge(v,f2,wf,&fo2,&eo2);
00791 if((vid=GetCommonVertex(v,wf[f1].f,wf[f2].f)) < 0)return 0;
00792 f=(MainFp+wf[f0].f);
00793 wf[f1].del=1;
00794 wf[f2].del=1;
00795 for(j=0;j<3;j++){
00796
00797 l=(long)((MainVp+(MainFp+(wf[f1].f))->V[j])->id);
00798 for(k=0;k<vl[l].nf;k++){
00799 if(vl[l].flist[k] == f1 || vl[l].flist[k] == f2)vl[l].flist[k]=f0;
00800 }
00801 l=(long)((MainVp+(MainFp+(wf[f2].f))->V[j])->id);
00802 for(k=0;k<vl[l].nf;k++){
00803 if(vl[l].flist[k] == f1 || vl[l].flist[k] == f2)vl[l].flist[k]=f0;
00804 }
00805
00806 if(wf[f0].fa[j] == f1){
00807 wf[f0].fa[j]=fo1;
00808 wf[f0].ea[j]=eo1;
00809 }
00810 if(wf[f0].fa[j] == f2){
00811 wf[f0].fa[j]=fo2;
00812 wf[f0].ea[j]=eo2;
00813 }
00814
00815 if(f->V[j] == v)f->V[j]=vid;
00816 if((l=wf[f1].fa[j]) >= 0 && l != f0 && l != f1 && l != f2){
00817 for(k=0;k<3;k++)if(wf[l].fa[k] == f1)wf[l].fa[k]=f0;
00818 }
00819 if((l=wf[f2].fa[j]) >= 0 && l != f0 && l != f1 && l != f2){
00820 for(k=0;k<3;k++)if(wf[l].fa[k] == f2)wf[l].fa[k]=f0;
00821 }
00822 }
00823 for(j=0;j<2;j++){
00824 if(we[eo1].ea[j] == f1)we[eo1].ea[j]=f0;
00825 if(we[eo2].ea[j] == f2)we[eo2].ea[j]=f0;
00826 }
00827 }
00828 }
00829 return reduc;
00830 }
00831