00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <math.h>
00004 #include <esg/mesh/Mesh.h>
00005
00006 using namespace esg;
00007
00008 void Mesh::AppendVertex(Solid *S, Vert *V)
00009 {
00010 Vert *LV;
00011
00012 if (S->first_vertex==NULL) {
00013 S->first_vertex=V;
00014 V->next_vertex=V; V->previous_vertex=V;
00015 S->cover.xmin=S->cover.xmax=V->x;
00016 S->cover.ymin=S->cover.ymax=V->y;
00017 S->cover.zmin=S->cover.zmax=V->z;
00018 } else {
00019 LV=S->first_vertex->previous_vertex;
00020 V->previous_vertex=LV;
00021 V->next_vertex=LV->next_vertex;
00022 LV->next_vertex->previous_vertex=V;
00023 LV->next_vertex=V;
00024
00025 if (V->x<S->cover.xmin) S->cover.xmin=V->x; else
00026 if (V->x>S->cover.xmax) S->cover.xmax=V->x;
00027 if (V->y<S->cover.ymin) S->cover.ymin=V->y; else
00028 if (V->y>S->cover.ymax) S->cover.ymax=V->y;
00029 if (V->z<S->cover.zmin) S->cover.zmin=V->z; else
00030 if (V->z>S->cover.zmax) S->cover.zmax=V->z;
00031 }
00032 }
00033
00034 void Mesh::AppendEdge(Solid *S, Edge *E)
00035 {
00036 Edge *LE;
00037
00038 if (S->first_edge==NULL) {
00039 S->first_edge=E;
00040 E->next_edge=E; E->previous_edge=E;
00041 } else {
00042 LE=S->first_edge->previous_edge;
00043 E->previous_edge=LE;
00044 E->next_edge=LE->next_edge;
00045 LE->next_edge->previous_edge=E;
00046 LE->next_edge=E;
00047 }
00048 }
00049
00050 void Mesh::AppendFace(Solid *S, Plane *NP)
00051 {
00052 Plane *LP;
00053
00054 if (S->first_plane!=NULL) {
00055 LP=S->first_plane->previous_plane;
00056 NP->next_plane=LP->next_plane;
00057 NP->previous_plane=LP;
00058 NP->next_plane->previous_plane=NP;
00059 LP->next_plane=NP;
00060 } else {
00061 NP->next_plane=NP; NP->previous_plane=NP;
00062 S->first_plane =NP;
00063 }
00064 }
00065
00066 void Mesh::DeleteVertex(Solid *S, Vert *V)
00067 {
00068 if (V!=NULL) {
00069 if (V->next_vertex==V) {
00070 S->first_vertex=NULL;
00071 } else {
00072 V->next_vertex->previous_vertex=V->previous_vertex;
00073 V->previous_vertex->next_vertex=V->next_vertex;
00074 if (S->first_vertex==V) S->first_vertex=V->next_vertex;
00075 }
00076 delete(V);
00077 }
00078 }
00079
00080 void Mesh::DeleteEdge(Solid *S, Edge *E)
00081 {
00082 if (E!=NULL) {
00083 if (E->next_edge==E) {
00084 S->first_edge=NULL;
00085 } else {
00086 E->next_edge->previous_edge=E->previous_edge;
00087 E->previous_edge->next_edge=E->next_edge;
00088
00089 if (S->first_edge==E) S->first_edge=E->next_edge;
00090 }
00091 delete(E);
00092 }
00093 }
00094
00095 void Mesh::DeleteFace(Solid *S, Plane *NP)
00096 {
00097 if (NP!=NULL) {
00098 if (NP->next_plane==NP) {
00099 S->first_plane=NULL;
00100 } else {
00101 NP->next_plane->previous_plane=NP->previous_plane;
00102 NP->previous_plane->next_plane=NP->next_plane;
00103 if (S->first_plane==NP) S->first_plane=NP->next_plane;
00104 }
00105 delete(NP);
00106 }
00107 };
00108
00109 void Mesh::MoveVertex(Solid *S, Solid *SM, Vert *V)
00110 {
00111 if (V!=NULL) {
00112 if (V->next_vertex==V) {
00113 S->first_vertex=NULL;
00114 } else {
00115 V->next_vertex->previous_vertex=V->previous_vertex;
00116 V->previous_vertex->next_vertex=V->next_vertex;
00117 if (S->first_vertex==V) S->first_vertex=V->next_vertex;
00118 }
00119 AppendVertex(SM,V);
00120 }
00121 }
00122
00123 void Mesh::MoveEdge(Solid *S, Solid *SM, Edge *E)
00124 {
00125 if (E!=NULL) {
00126 if (E->next_edge==E) S->first_edge=NULL;
00127 else {
00128 E->next_edge->previous_edge=E->previous_edge;
00129 E->previous_edge->next_edge=E->next_edge;
00130
00131 if (S->first_edge==E) S->first_edge=E->next_edge;
00132 }
00133 AppendEdge(SM,E);
00134 }
00135 }
00136
00137 void Mesh::MoveFace(Solid *S, Solid *SM, Plane *NP)
00138 {
00139 if (NP!=NULL) {
00140 if (NP->next_plane==NP)S->first_plane=NULL;
00141 else
00142 {
00143 NP->next_plane->previous_plane=NP->previous_plane;
00144 NP->previous_plane->next_plane=NP->next_plane;
00145 if (S->first_plane==NP) S->first_plane=NP->next_plane;
00146 }
00147 AppendFace(SM,NP);
00148 }
00149 }
00150
00151 Mesh::Vert* Mesh::NewVertex(Solid *S, float xp, float yp, float zp)
00152 {
00153 Vert *NV = MV(xp, yp, zp);
00154 AppendVertex(S,NV);
00155 return NV;
00156 }
00157
00158 Mesh::Edge* Mesh::NewEdge(Solid *S, Vert *V1p, Vert *V2p,
00159 Plane *P1p, Plane *P2p)
00160 {
00161 Edge *NE = new Edge;
00162
00163 pocet_hran++;
00164
00165 NE->V1=V1p; NE->V2=V2p;
00166 NE->LeftLoop=P1p; NE->RightLoop=P2p;
00167 NE->jmeno_hrany=pocet_hran; NE->druh_hrany=VNITRNI;
00168 if (NE->LeftLoop->skalar<=0) NE->druh_hrany=OBRYSOVA;
00169
00170 if (NE->RightLoop->skalar<=0) {
00171
00172 if (NE->druh_hrany==OBRYSOVA) NE->druh_hrany=ZAKRYTA;
00173 else NE->druh_hrany=OBRYSOVA;
00174 }
00175 P1p->any_edge=NE; P2p->any_edge=NE;
00176 AppendEdge(S,NE);
00177
00178 return NE;
00179 }
00180
00181 Mesh::Plane* Mesh::NewPlane(Solid *S,float a1,float b1,float c1,float d1)
00182 {
00183 Plane *NP=new Plane;
00184
00185 pocet_rovin++;
00186 NP->a=a1; NP->b=b1; NP->c=c1; NP->d=d1; NP->any_edge=NULL; NP->skalar=-c1;
00187 NP->jmeno_roviny=pocet_rovin;
00188 AppendFace(S,NP);
00189 return NP;
00190 }
00191
00192 void Mesh::Copy_solid(Solid *Sorigin, Solid *Scopy)
00193 {
00194 Vert *OV;
00195 Edge *OE;
00196 Plane *OP;
00197
00198
00199 OV=Sorigin->first_vertex;
00200 do {
00201 OV->previous_vertex=NewVertex(Scopy,OV->x,OV->y,OV->z);
00202 AppendVertex(Scopy,OV->previous_vertex);
00203 OV=OV->next_vertex;
00204 } while (OV!=Sorigin->first_vertex);
00205
00206
00207 OP=Sorigin->first_plane;
00208 do {
00209 OP->previous_plane=NewPlane(Scopy,OP->a,OP->b,OP->c,OP->d);
00210 AppendFace(Scopy,OP->previous_plane);
00211 OP=OP->next_plane;
00212 } while (OP!=Sorigin->first_plane);
00213
00214
00215 OE=Sorigin->first_edge;
00216 do {
00217 OE->previous_edge=NewEdge(Scopy,
00218 OE->V1->previous_vertex,
00219 OE->V2->previous_vertex,
00220 OE->LeftLoop->previous_plane,
00221 OE->RightLoop->previous_plane);
00222 AppendEdge(Scopy,OE->previous_edge);
00223 OE=OE->next_edge;
00224 } while (OE!=Sorigin->first_edge);
00225
00226
00227 OE=Sorigin->first_edge;
00228 do {
00229 OE->previous_edge->LeftIn=OE->LeftIn->previous_edge;
00230 OE->previous_edge->RightOut=OE->RightOut->previous_edge;
00231 OE->previous_edge->LeftOut=OE->LeftOut->previous_edge;
00232 OE->previous_edge->RightIn=OE->RightIn->previous_edge;
00233 OE=OE->next_edge;
00234 } while (OE!=Sorigin->first_edge);
00235 }
00236
00237 void Mesh::Delete_solid(Solid **S)
00238
00239 {
00240 Vert *CV,*NV;
00241 Edge *CE,*NE;
00242 Plane *CP,*NP;
00243
00244 if (S!=NULL) {
00245 NV=(*S)->first_vertex;
00246 if (NV!=NULL)
00247 do {
00248 CV=NV; NV=NV->next_vertex; delete CV;
00249 } while (NV!=(*S)->first_vertex);
00250
00251 NE=(*S)->first_edge;
00252 if (NE!=NULL)
00253 do {
00254 CE=NE; NE=NE->next_edge; delete CE;
00255 } while (NE!=(*S)->first_edge);
00256
00257 NP=(*S)->first_plane;
00258 if (NP!=NULL)
00259 do {
00260 CP=NP; NP=NP->next_plane; delete CP;
00261 } while (NP!=(*S)->first_plane);
00262 }
00263 delete *S;
00264 }
00265
00266 #define eps 0.01
00267 int Mesh::Paralel_planes(float a, float b, float c,
00268 float ar, float br, float cr,
00269 int &same_orientation)
00270 {
00271 int ParPla;
00272
00273 same_orientation=0;
00274 ParPla= (fabs(b*cr-c*br)+fabs(c*ar-a*cr)+fabs(a*br-b*ar))<eps;
00275 if (ParPla) same_orientation= (a*ar+b*br+c*cr)>0;
00276
00277 return ParPla;
00278 }
00279 #undef eps
00280
00281 void Mesh::Vertex_Plane_position(Solid &S,
00282 float ar, float br, float cr, float dr,
00283 int &Pozitiv,int &Negativ)
00284 {
00285 Vert *NV;
00286
00287 Pozitiv=0; Negativ=0;
00288
00289 NV=S.first_vertex;
00290 do {
00291 NV->fxyz=ar*NV->x+br*NV->y+cr*NV->z+dr;
00292 if (NV->fxyz>0) Pozitiv++; else
00293 if (NV->fxyz<0) Negativ++;
00294 NV=NV->next_vertex;
00295 } while (NV!=S.first_vertex);
00296 }
00297
00298 void Mesh::Orient_Edge(Edge *E, Plane *F, Vert **Vin, Vert **Vout)
00299 {
00300 if (F==E->LeftLoop){ *Vin=E->V1; *Vout=E->V2; }
00301 else { *Vin=E->V2; *Vout=E->V1; }
00302 }
00303
00304 Mesh::Edge* Mesh::Next_Edge_in_loop(Edge *CE, Vert **Vin, Vert **Vout)
00305 {
00306 Edge *NE;
00307
00308
00309
00310
00311
00312
00313
00314 if (*Vin==CE->V1)
00315 NE=CE->LeftOut;
00316 else
00317 NE=CE->RightOut;
00318
00319 if (*Vout==NE->V1)
00320 { *Vin=NE->V1; *Vout=NE->V2; }
00321 else
00322 { *Vin=NE->V2; *Vout=NE->V1; }
00323 return(NE);
00324 }
00325
00326 Mesh::Edge* Mesh::Previous_Edge_in_loop(Edge *CE, Vert **Vin, Vert **Vout)
00327 {
00328 Edge *NE;
00329
00330
00331
00332
00333
00334 if (*Vin==CE->V1)
00335 NE=CE->LeftIn;
00336 else
00337 NE=CE->RightIn;
00338
00339
00340 if (*Vin==NE->V2)
00341 { *Vin=NE->V1; *Vout=NE->V2; }
00342 else
00343 { *Vin=NE->V2; *Vout=NE->V1; }
00344 return(NE);
00345 }
00346
00347 void Mesh::ClasifyEdges(Solid *S)
00348 {
00349 Edge *NE;
00350
00351 NE=S->first_edge;
00352 do {
00353 NE->druh_hrany=VNITRNI;
00354 if ((NE->LeftLoop->skalar<=0))
00355 NE->druh_hrany=OBRYSOVA;
00356 if ((NE->RightLoop->skalar<=0))
00357 {
00358 if (NE->druh_hrany==OBRYSOVA) NE->druh_hrany=ZAKRYTA;
00359 else NE->druh_hrany=OBRYSOVA;
00360 }
00361 NE=NE->next_edge;
00362 } while (NE!=S->first_edge);
00363 }
00364
00365 Mesh::Vert* Mesh::MV(float xp, float yp, float zp)
00366 {
00367 Vert *NV = new Vert;
00368
00369 NV->x=xp; NV->y=yp; NV->z=zp;
00370 NV->jmeno_vrcholu=pocet_vrcholu++;
00371 NV->fxyz=0.0;
00372 return(NV);
00373 }
00374
00375 Mesh::Plane* Mesh::MF(float a1, float b1, float c1, float d1)
00376 {
00377 Plane *NP = new Plane;
00378
00379 pocet_rovin=pocet_rovin+1;
00380 NP->a=a1; NP->b=b1; NP->c=c1; NP->d=d1;
00381 NP->any_edge=NULL; NP->skalar=-(NP->c);
00382 NP->jmeno_roviny=pocet_rovin;
00383 return(NP);
00384 }
00385
00386
00387 Mesh::Solid* Mesh::MVSF(Plane *F, Vert *V)
00388 {
00389 Solid* S = new Solid;
00390
00391 S->solid_name=0;
00392 S->first_vertex=NULL;
00393 S->first_edge=NULL;
00394 S->first_plane=NULL;
00395 S->next_solid=S;
00396 S->previous_solid=S;
00397 AppendVertex(S,V);
00398 AppendFace(S,F);
00399 return(S);
00400 }
00401
00402
00403 void Mesh::MEV(Solid *S, Vert *V1p, Vert *V2p, Edge **E, Plane *F)
00404 {
00405 Vert *Vin, *Vout;
00406 Edge *CE;
00407
00408
00409 AppendVertex(S,V2p);
00410
00411 *E = new Edge;
00412
00413 pocet_hran=pocet_hran+1;
00414 (*E)->V1=V1p; (*E)->V2=V2p; (*E)->jmeno_hrany=pocet_hran;
00415 (*E)->LeftLoop=F; (*E)->RightLoop=F;
00416 (*E)->LeftIn=NULL; (*E)->RightOut=NULL;
00417 (*E)->LeftOut=NULL; (*E)->RightIn=NULL;
00418
00419 if (F->any_edge==NULL)
00420 {
00421 (*E)->LeftIn=*E; (*E)->RightOut=*E; (*E)->LeftOut=*E; (*E)->RightIn=*E;
00422 F->any_edge=*E;
00423 }
00424 else
00425
00426 {
00427 (*E)->LeftOut=*E; (*E)->RightIn=*E;
00428 CE=F->any_edge;
00429 Orient_Edge(CE,F,&Vin,&Vout);
00430
00431 while (Vout!=V1p) { CE=Next_Edge_in_loop(CE,&Vin,&Vout); }
00432 if (CE->V1==Vin)
00433 {
00434 if (CE->LeftOut->V1==Vout) CE->LeftOut->LeftIn=*E;
00435 else CE->LeftOut->RightIn=*E;
00436 (*E)->RightOut=CE->LeftOut; (*E)->LeftIn=CE; CE->LeftOut=*E;
00437 }
00438 else
00439 {
00440 if (CE->RightOut->V1==Vout) CE->RightOut->LeftIn=*E;
00441 else CE->RightOut->RightIn=*E;
00442 (*E)->RightOut=CE->RightOut; (*E)->LeftIn=CE; CE->RightOut=*E;
00443 }
00444 }
00445 AppendEdge(S,*E);
00446 }
00447
00448 void Mesh::ReplaceEdge(Edge *E1, Edge *E, Edge *E2)
00449 {
00450 if (E1->LeftIn==E) E1->LeftIn=E2;
00451 else
00452 if (E1->RightIn==E) E1->RightIn=E2;
00453 else
00454 if (E1->LeftOut==E) E1->LeftOut=E2;
00455 else
00456 if (E1->RightOut==E) E1->RightOut=E2;
00457 }
00458
00459 void Mesh::SEMV(Solid *S, Edge *E1, Vert *V, Edge **E2)
00460 {
00461 *E2 = new Edge;
00462 pocet_hran=pocet_hran+1;
00463
00464 (*E2)->jmeno_hrany=pocet_hran;
00465 (*E2)->LeftLoop=E1->LeftLoop; (*E2)->RightLoop=E1->RightLoop;
00466 (*E2)->V1=V; (*E2)->V2=E1->V2; E1->V2=V;
00467 (*E2)->LeftOut=E1->LeftOut; (*E2)->LeftIn=E1;
00468 (*E2)->RightIn=E1->RightIn; (*E2)->RightOut=E1;
00469 E1->LeftOut=*E2; E1->RightIn=*E2;
00470
00471 ReplaceEdge((*E2)->LeftOut,E1,*E2); ReplaceEdge((*E2)->RightIn,E1,*E2);
00472 AppendEdge(S,*E2); AppendVertex(S,V);
00473 }
00474
00475 void Mesh::MEF(Solid *S,Vert *V1p,Vert *V2p,Plane *F1,Plane *F2,Edge **E)
00476 {
00477 MEnotF(S,V1p,V2p,F1,F2,E);
00478 AppendFace(S,F2);
00479 return;
00480
00481 Edge *CE, *NE, *L;
00482 Vert *Vin, *Vout, *Cin, *Nout;
00483 Vert *Nin = NULL;
00484 Vert *Cout = NULL;
00485
00486
00487 CE=NULL; NE=NULL;
00488 L=F1->any_edge; Orient_Edge(L,F1,&Vin,&Vout);
00489
00490 do {
00491 if (Vout==V2p) { CE=L; Cin=Vin; Cout=Vout; }
00492 if (Vin==V2p ) { NE=L; Nin=Vin; Nout=Vout; }
00493 L=Next_Edge_in_loop(L,&Vin,&Vout);
00494 } while ((CE == NULL) || (NE == NULL));
00495
00496 *E = new Edge; pocet_hran=pocet_hran+1;
00497 (*E)->V1=V1p; (*E)->V2=V2p; (*E)->jmeno_hrany=pocet_hran;
00498 (*E)->LeftLoop=F1; (*E)->RightLoop=F1;
00499 (*E)->LeftIn=NULL; (*E)->RightOut=NULL;
00500 (*E)->LeftOut=NULL;(*E)->RightIn=NULL;
00501
00502 if (F1->any_edge==NULL)
00503 {
00504 (*E)->LeftIn=*E; (*E)->RightOut=*E; (*E)->LeftOut=*E; (*E)->RightIn=*E;
00505 F1->any_edge=*E;
00506 }
00507 else
00508
00509 {
00510 (*E)->LeftOut=*E; (*E)->RightIn=*E;
00511 L=F1->any_edge;
00512 Orient_Edge(L,F1,&Vin,&Vout);
00513
00514 while (Vout!=V1p) { L=Next_Edge_in_loop(L,&Vin,&Vout); }
00515 if (L->V1==Vin)
00516 {
00517 if (L->LeftOut->V1==Vout) L->LeftOut->LeftIn=*E;
00518 else L->LeftOut->RightIn=*E;
00519 (*E)->RightOut=L->LeftOut; (*E)->LeftIn=L; L->LeftOut=*E;
00520 }
00521 else
00522 {
00523 if (L->RightOut->V1==Vout) L->RightOut->LeftIn=*E;
00524 else L->RightOut->RightIn=*E;
00525 (*E)->RightOut=L->RightOut; (*E)->LeftIn=L; L->RightOut=*E;
00526 }
00527 }
00528
00529 (*E)->LeftLoop=F2; (*E)->RightLoop=F1;
00530 F1->any_edge=*E; F2->any_edge=*E;
00531 (*E)->LeftOut=NE; (*E)->RightIn=CE;
00532
00533
00534
00535 if (CE->V2 == Cout) CE->LeftOut=*E; else CE->RightOut=*E;
00536 if (NE->V1 == Nin ) NE->LeftIn =*E; else NE->RightIn =*E;
00537
00538 L=*E; Vin=V1p; Vout=V2p;
00539 do {
00540 if (Vin==L->V1) L->LeftLoop=F2; else L->RightLoop=F2;
00541 L=Next_Edge_in_loop(L,&Vin,&Vout);
00542 } while (L!=(*E));
00543
00544 AppendEdge(S,*E); AppendFace(S,F2);
00545 }
00546
00547 void Mesh::MEnotF(Solid *S, Vert *V1p, Vert *V2p,
00548 Plane *F1, Plane *F2, Edge **E)
00549 {
00550 Edge *CE, *NE, *L;
00551 Vert *Vin, *Vout, *Cin, *Nout;
00552 Vert *Nin = NULL;
00553 Vert *Cout = NULL;
00554
00555
00556 CE=NULL; NE=NULL;
00557 L=F1->any_edge; Orient_Edge(L,F1,&Vin,&Vout);
00558
00559 do {
00560 if (Vout==V2p){ CE=L; Cin=Vin; Cout=Vout; }
00561 if (Vin==V2p ){ NE=L; Nin=Vin; Nout=Vout; }
00562 L=Next_Edge_in_loop(L,&Vin,&Vout);
00563 } while ((CE == NULL) || (NE == NULL));
00564
00565 *E = new Edge; pocet_hran=pocet_hran+1;
00566 (*E)->V1=V1p; (*E)->V2=V2p; (*E)->jmeno_hrany=pocet_hran;
00567 (*E)->LeftLoop=F1; (*E)->RightLoop=F1;
00568
00569 if (F1->any_edge==NULL)
00570 {
00571 (*E)->LeftIn=*E; (*E)->RightOut=*E; (*E)->LeftOut=*E; (*E)->RightIn=*E;
00572 F1->any_edge=*E;
00573 }
00574 else
00575
00576 {
00577 (*E)->LeftOut=*E; (*E)->RightIn=*E;
00578 L=F1->any_edge;
00579 Orient_Edge(L,F1,&Vin,&Vout);
00580
00581 while (Vout!=V1p) { L=Next_Edge_in_loop(L,&Vin,&Vout); }
00582 if (L->V1==Vin)
00583 {
00584 if (L->LeftOut->V1==Vout) L->LeftOut->LeftIn=*E;
00585 else L->LeftOut->RightIn=*E;
00586 (*E)->RightOut=L->LeftOut; (*E)->LeftIn=L; L->LeftOut=*E;
00587 }
00588 else
00589 {
00590 if (L->RightOut->V1==Vout) L->RightOut->LeftIn=*E;
00591 else L->RightOut->RightIn=*E;
00592 (*E)->RightOut=L->RightOut; (*E)->LeftIn=L; L->RightOut=*E;
00593 }
00594 }
00595
00596 (*E)->LeftLoop=F2; (*E)->RightLoop=F1;
00597 F1->any_edge=*E; F2->any_edge=*E;
00598 (*E)->LeftOut=NE; (*E)->RightIn=CE;
00599
00600
00601
00602 if (CE->V2 == Cout) CE->LeftOut=*E; else CE->RightOut=*E;
00603 if (NE->V1 == Nin ) NE->LeftIn =*E; else NE->RightIn =*E;
00604
00605 L=*E; Vin=V1p; Vout=V2p;
00606 do {
00607 if (Vin==L->V1) L->LeftLoop=F2; else L->RightLoop=F2;
00608 L=Next_Edge_in_loop(L,&Vin,&Vout);
00609 } while (L!=(*E));
00610
00611 AppendEdge(S,*E);
00612 }
00613
00614 Mesh::Vert* Mesh::Vertex_of_cut(Vert *V1, Vert *V2)
00615 {
00616 float t,xcut,ycut,zcut;
00617 Vert *VC;
00618
00619
00620
00621
00622 t = V1->fxyz/(V1->fxyz-V2->fxyz);
00623 xcut=V1->x+(V2->x-V1->x)*t;
00624 ycut=V1->y+(V2->y-V1->y)*t;
00625 zcut=V1->z+(V2->z-V1->z)*t;
00626 VC=MV(xcut,ycut,zcut); VC->fxyz=0.0;
00627 return(VC);
00628 }
00629
00630 Mesh::Plane* Mesh::This_loop(Edge *E, Vert *V)
00631 {
00632 if (V == E->V1) return(E->LeftLoop); else return(E->RightLoop);
00633 }
00634
00635 void Mesh::ConnectEdge(Edge *E1, Edge *E, Edge *E2, Plane *P)
00636 {
00637 if (E1->LeftIn==E) { E1->LeftIn=E2; E1->LeftLoop=P; }
00638 else
00639 if (E1->RightIn==E) { E1->RightIn=E2; E1->RightLoop=P; }
00640 else
00641 if (E1->LeftOut==E) { E1->LeftOut=E2; E1->LeftLoop=P; }
00642 else
00643 if (E1->RightOut==E) { E1->RightOut=E2; E1->RightLoop=P; }
00644 }
00645
00646 void Mesh::KE(Edge *E, Vert *Vin, Plane *P1, Plane *P2)
00647 {
00648 if (Vin==E->V1)
00649 {
00650 P2->any_edge=E->LeftOut; P1->any_edge=E->LeftIn;
00651 ConnectEdge(E->LeftOut,E,E->RightIn,P2);
00652 ConnectEdge(E->RightIn,E,E->LeftOut,P2);
00653 ConnectEdge(E->LeftIn,E,E->RightOut,P1);
00654 ConnectEdge(E->RightOut,E,E->LeftIn,P1);
00655 }
00656 else
00657 {
00658 P1->any_edge=E->LeftOut; P2->any_edge=E->LeftIn;
00659 ConnectEdge(E->LeftOut,E,E->RightIn,P1);
00660 ConnectEdge(E->RightIn,E,E->LeftOut,P1);
00661 ConnectEdge(E->LeftIn,E,E->RightOut,P2);
00662 ConnectEdge(E->RightOut,E,E->LeftIn,P2);
00663 }
00664 }
00665
00666 void Mesh::SeparateSolids(Solid **NS, Solid **Odpad)
00667 {
00668 Edge *NE, *PE;
00669 Plane *NP, *PP;
00670 Vert *NV, *PV;
00671 int konec;
00672
00673
00674 *Odpad = new Solid;
00675 (*Odpad)->solid_name=0;
00676 (*Odpad)->first_vertex=NULL;
00677 (*Odpad)->first_edge=NULL;
00678 (*Odpad)->first_plane=NULL;
00679
00680 NV=(*NS)->first_vertex;
00681 do {
00682 NV->valid=0;
00683 NV=NV->next_vertex;
00684 } while (NV!=(*NS)->first_vertex);
00685
00686 NP=(*NS)->first_plane;
00687 do {
00688 NP->jmeno_roviny=-NP->jmeno_roviny;
00689 NP=NP->next_plane;
00690 } while (NP!=(*NS)->first_plane);
00691
00692 PE=(*NS)->first_edge;
00693 do {
00694 NE=PE->next_edge;
00695 if (PE==(*NS)->first_edge->previous_edge) konec=1; else konec=0;
00696 if (PE->druh_hrany==TELESOVA)
00697 {
00698 PE->V1->valid=1; PE->V2->valid=1;
00699 PE->LeftLoop->jmeno_roviny=abs(PE->LeftLoop->jmeno_roviny);
00700 PE->RightLoop->jmeno_roviny=abs(PE->RightLoop->jmeno_roviny);
00701 }
00702 else
00703 {
00704 MoveEdge(*NS,*Odpad,PE);
00705 }
00706 PE=NE;
00707 } while (!konec);
00708
00709
00710 PV=(*NS)->first_vertex;
00711 do {
00712 if (PV==(*NS)->first_vertex->previous_vertex) konec=1; else konec=0;
00713 NV=PV->next_vertex;
00714 if (!(PV->valid)) MoveVertex(*NS,*Odpad,PV);
00715 PV=NV;
00716 } while (!konec);
00717
00718
00719 PP=(*NS)->first_plane;
00720 do {
00721 if (PP==(*NS)->first_plane->previous_plane) konec=1; else konec=0;
00722 NP=PP->next_plane;
00723 if ((PP->jmeno_roviny<=0))
00724 {
00725 PP->jmeno_roviny=abs(PP->jmeno_roviny);
00726 MoveFace(*NS,*Odpad,PP);
00727 }
00728 PP=NP;
00729 } while (!konec);
00730 }
00731
00732
00733
00734
00735 void Mesh::rotate(const Matrix3& rotMat)
00736 {
00737 if (!pSolid) return;
00738
00739 Vector3 v;
00740 Vert* pVert = pSolid->first_vertex;
00741 if (pVert)
00742 do {
00743 v.set(pVert->x, pVert->y, pVert->z);
00744 rotMat.transform(v);
00745 pVert->x = v.x;
00746 pVert->y = v.y;
00747 pVert->z = v.z;
00748 rotMat.transform(pVert->normal);
00749 pVert = pVert->next_vertex;
00750 } while (pVert != pSolid->first_vertex);
00751
00752 Vector3 u;
00753 Plane* pPlane = pSolid->first_plane;
00754 if (pPlane)
00755 do {
00756 v.set(pPlane->a, pPlane->b, pPlane->c);
00757 rotMat.transform(v);
00758 pPlane->a = v.x;
00759 pPlane->b = v.y;
00760 pPlane->c = v.z;
00761 u.set(pPlane->any_edge->V1->x,
00762 pPlane->any_edge->V1->y,
00763 pPlane->any_edge->V1->z);
00764 pPlane->d = - u.dot(v);
00765 pPlane = pPlane->next_plane;
00766 } while (pPlane != pSolid->first_plane);
00767 }
00768
00769 void Mesh::translate(const Vector3& tr)
00770 {
00771 if (!pSolid) return;
00772
00773 Vert* pVert = pSolid->first_vertex;
00774 if (pVert)
00775 do {
00776 pVert->x += tr.x;
00777 pVert->y += tr.y;
00778 pVert->z += tr.z;
00779 pVert->fxyz += tr.length();
00780 pVert = pVert->next_vertex;
00781 } while (pVert != pSolid->first_vertex);
00782
00783 Vector3 u, v;
00784 Plane* pPlane = pSolid->first_plane;
00785 if (pPlane)
00786 do {
00787 v.set(pPlane->a, pPlane->b, pPlane->c);
00788 u.set(pPlane->any_edge->V1->x,
00789 pPlane->any_edge->V1->y,
00790 pPlane->any_edge->V1->z);
00791 pPlane->d = - u.dot(v);
00792 pPlane = pPlane->next_plane;
00793 } while (pPlane != pSolid->first_plane);
00794 }
00795
00796 void Mesh::transform(const Matrix4& trMat)
00797 {
00798 if (!pSolid) return;
00799
00800 Vector3 v;
00801 Matrix3 rotMat;
00802
00803 trMat.get(rotMat);
00804
00805 Vert* pVert = pSolid->first_vertex;
00806 if (pVert)
00807 do {
00808 v.set(pVert->x, pVert->y, pVert->z);
00809 trMat.transform(v);
00810 pVert->x = v.x;
00811 pVert->y = v.y;
00812 pVert->z = v.z;
00813 rotMat.transform(pVert->normal);
00814 pVert->fxyz = - pVert->normal.dot(v);
00815 pVert = pVert->next_vertex;
00816 } while (pVert != pSolid->first_vertex);
00817
00818 Vector3 u;
00819 Plane* pPlane = pSolid->first_plane;
00820 if (pPlane)
00821 do {
00822 v.set(pPlane->a, pPlane->b, pPlane->c);
00823 rotMat.transform(v);
00824 pPlane->a = v.x;
00825 pPlane->b = v.y;
00826 pPlane->c = v.z;
00827 u.set(pPlane->any_edge->V1->x,
00828 pPlane->any_edge->V1->y,
00829 pPlane->any_edge->V1->z);
00830 pPlane->d = - u.dot(v);
00831 pPlane = pPlane->next_plane;
00832 } while (pPlane != pSolid->first_plane);
00833 }
00834
00835 void Mesh::scale(float scX, float scY, float scZ)
00836 {
00837 if (!pSolid) return;
00838
00839 Vert* pVert = pSolid->first_vertex;
00840 if (pVert)
00841 do {
00842 pVert->x *= scX;
00843 pVert->y *= scY;
00844 pVert->z *= scZ;
00845 pVert = pVert->next_vertex;
00846 } while (pVert != pSolid->first_vertex);
00847 }
00848
00849 void Mesh::resetActSolid()
00850 {
00851 pActSolid = pSolid;
00852 }
00853
00854 int Mesh::goToNextSolid()
00855 {
00856 if (!pActSolid) return 0;
00857 if (pActSolid->next_solid == pSolid) return 0;
00858 pActSolid = pActSolid->next_solid;
00859 return 1;
00860 }
00861
00862 void Mesh::resetActPlane()
00863 {
00864 pActPlane = pActSolid->first_plane;
00865 }
00866
00867 Mesh::Plane* Mesh::getActPlane()
00868 {
00869 return pActPlane;
00870 }
00871
00872 int Mesh::goToNextPlane()
00873 {
00874 if (pActPlane->next_plane == pSolid->first_plane) return 0;
00875 pActPlane = pActPlane->next_plane;
00876 return 1;
00877 }
00878
00879 void Mesh::resetActEdge()
00880 {
00881 pActEdge = pActPlane->any_edge;
00882 }
00883
00884 int Mesh::goToNextEdge()
00885 {
00886 Vert *Vin, *Vout;
00887
00888 Orient_Edge(pActEdge, pActPlane, &Vin, &Vout);
00889 pActEdge = Next_Edge_in_loop(pActEdge, &Vin, &Vout);
00890
00891 if (pActEdge == pActPlane->any_edge) return 0;
00892 else return 1;
00893 }
00894
00895 Vertex3 Mesh::getActVert1(bool orient)
00896 {
00897 if (orient) {
00898 if (pActEdge->LeftLoop == pActPlane)
00899 return Vertex3(pActEdge->V1->x, pActEdge->V1->y, pActEdge->V1->z);
00900 else if (pActEdge->RightLoop == pActPlane)
00901 return Vertex3(pActEdge->V2->x, pActEdge->V2->y, pActEdge->V2->z);
00902 else {
00903 fprintf(stderr,"Mesh error: Actual face mismatch the actual edge\n");
00904 return Vertex3(0,0,0);
00905 }
00906 } else {
00907 return Vertex3(pActEdge->V1->x, pActEdge->V1->y, pActEdge->V1->z);
00908 }
00909 }
00910
00911 Vertex3 Mesh::getActVert2(bool orient)
00912 {
00913 if (orient) {
00914 if (pActEdge->LeftLoop == pActPlane)
00915 return Vertex3(pActEdge->V2->x, pActEdge->V2->y, pActEdge->V2->z);
00916 else if (pActEdge->RightLoop == pActPlane)
00917 return Vertex3(pActEdge->V1->x, pActEdge->V1->y, pActEdge->V1->z);
00918 else {
00919 fprintf(stderr,"Mesh error: Actual face mismatch the actual edge\n");
00920 return Vertex3(0,0,0);
00921 }
00922 } else
00923 return Vertex3(pActEdge->V2->x, pActEdge->V2->y, pActEdge->V2->z);
00924 }
00925
00926 Vertex3 Mesh::getActVert()
00927 {
00928 if (pActVert) return Vertex3(pActVert->x, pActVert->y, pActVert->z);
00929 else {
00930 fprintf(stderr,"Mesh error: getActVert() called but no actual vertex set\n");
00931 return Vertex3(0,0,0);
00932 }
00933 }
00934
00935 Vertex3 Mesh::getActVertNormal1(bool orient)
00936 {
00937 if (orient) {
00938 if (pActEdge->LeftLoop == pActPlane)
00939 return pActEdge->V1->normal;
00940 else if (pActEdge->RightLoop == pActPlane)
00941 return pActEdge->V2->normal;
00942 else {
00943 fprintf(stderr,"Mesh error: Actual face mismatch actual edge\n");
00944 return Vertex3(0,0,0);
00945 }
00946 } else
00947 return pActEdge->V1->normal;
00948 }
00949
00950 Vertex3 Mesh::getActVertNormal2(bool orient)
00951 {
00952 if (orient) {
00953 if (pActEdge->LeftLoop == pActPlane)
00954 return pActEdge->V2->normal;
00955 else if (pActEdge->RightLoop == pActPlane)
00956 return pActEdge->V1->normal;
00957 else {
00958 fprintf(stderr,"Mesh error: Actual face mismatch actual edge\n");
00959 return Vertex3(0,0,0);
00960 }
00961 } else
00962 return pActEdge->V2->normal;
00963 }
00964
00965 Vertex3 Mesh::getActVertNormal()
00966 {
00967 if (pActVert) return pActVert->normal;
00968 else {
00969 fprintf(stderr,"Mesh error: getActVertNormal() called but no actual vertex defined\n");
00970 return Vertex3(0,0,0);
00971 }
00972 }
00973
00974 int Mesh::getActVertID1(bool orient)
00975 {
00976 if (orient) {
00977 if (pActEdge->LeftLoop == pActPlane)
00978 return pActEdge->V1->jmeno_vrcholu;
00979 else if (pActEdge->RightLoop == pActPlane)
00980 return pActEdge->V2->jmeno_vrcholu;
00981 else {
00982 fprintf(stderr,"Mesh error: Actual face mismatch actual edge\n");
00983 return -1;
00984 }
00985 } else
00986 return pActEdge->V1->jmeno_vrcholu;
00987 }
00988
00989 int Mesh::getActVertID2(bool orient)
00990 {
00991 if (orient) {
00992 if (pActEdge->LeftLoop == pActPlane)
00993 return pActEdge->V2->jmeno_vrcholu;
00994 else if (pActEdge->RightLoop == pActPlane)
00995 return pActEdge->V1->jmeno_vrcholu;
00996 else {
00997 fprintf(stderr,"Mesh error: Actual face mismatch actual edge\n");
00998 return -1;
00999 }
01000 } else
01001 return pActEdge->V2->jmeno_vrcholu;
01002 }
01003
01004 int Mesh::getActVertID()
01005 {
01006 if (pActVert) return pActVert->jmeno_vrcholu;
01007 else {
01008 fprintf(stderr,"Mesh error: getActVertColor() called but no actual vertex defined\n");
01009 return -1;
01010 }
01011 }
01012
01013 int Mesh::getActPlaneID()
01014 {
01015 if (pActPlane) return pActPlane->jmeno_roviny;
01016 else {
01017 fprintf(stderr,"Mesh error: getActPlaneID() called but no actual plane defined\n");
01018 return -1;
01019 }
01020 }
01021
01022 Vertex3 Mesh::getActPlaneNormal() const
01023 {
01024 if (pActPlane) return Vertex3(pActPlane->a,pActPlane->b,pActPlane->c);
01025 else {
01026 fprintf(stderr,"Mesh error: getActPlaneNormal() called but no actual plane defined\n");
01027 return Vertex3(0,0,0);
01028 }
01029 }
01030
01031 Vector3 Mesh::getActPlaneCentroid()
01032 {
01033 if (!pActPlane) return Vector3(MAX_VEC_VALUE,MAX_VEC_VALUE,MAX_VEC_VALUE);
01034
01035 Vector3 ret;
01036 unsigned n = 0;
01037 Edge * e = pActEdge;
01038
01039 resetActEdge();
01040 do {
01041 if (n == 0) ret.set(getActVert1(true));
01042 else ret.add(getActVert1(true));
01043 } while (++n && goToNextEdge());
01044 ret.scale(1.0/n);
01045
01046 pActEdge = e;
01047 return ret;
01048 }
01049
01050 double Mesh::getActPlaneArea()
01051 {
01052 if (!pActPlane) return MINDOUBLE;
01053
01054 double area;
01055 Edge * e = pActEdge;
01056 Vector3 v0, v1;
01057 unsigned n = 0;
01058
01059 resetActEdge();
01060 do {
01061 if (n == 0) {
01062 v0.set(getActVert1(true));
01063 v0.sub(getActVert2(true));
01064 }
01065 if (n == 1) {
01066 v1.set(getActVert2(true));
01067 v1.sub(getActVert1(true));
01068 }
01069 } while (++n && goToNextEdge());
01070
01071 area = v0.dot(v1);
01072 if (n == 3) area /= 2.0;
01073 else if (n != 4) {
01074 fprintf(stderr,"Mesh::getActPlaneArea(): only three or four edges supported\n");
01075 }
01076
01077 pActEdge = e;
01078
01079 return area;
01080 }
01081
01082 void Mesh::resetEdgeWalkInSolid()
01083 {
01084 pActEdge = pActSolid->first_edge;
01085 }
01086
01087 int Mesh::stepInEdgeWalkInSolid()
01088 {
01089 if (pActEdge->next_edge == pActSolid->first_edge) return 0;
01090 pActEdge = pActEdge->next_edge;
01091 return 1;
01092 }
01093
01094 void Mesh::resetVertWalkInSolid()
01095 {
01096 pActVert = pActSolid->first_vertex;
01097 }
01098
01099 bool Mesh::stepInVertWalkInSolid()
01100 {
01101 if (pActVert->next_vertex == pActSolid->first_vertex) return false;
01102 pActVert = pActVert->next_vertex;
01103 return true;
01104 }
01105
01106 void Mesh::turnInsideOut(void)
01107 {
01108 Solid * pActSolid = pSolid;
01109 do {
01110 Plane * pActPlane = pActSolid->first_plane;
01111 if (pActPlane)
01112 do {
01113 pActPlane->a *= -1;
01114 pActPlane->b *= -1;
01115 pActPlane->c *= -1;
01116 pActPlane->d *= -1;
01117 pActPlane->skalar *= -1;
01118 pActPlane = pActPlane->next_plane;
01119 } while (pActPlane != pActSolid->first_plane);
01120 Vert * pActVert = pActSolid->first_vertex;
01121 if (pActVert)
01122 do {
01123 pActVert->normal.negate();
01124 pActVert = pActVert->next_vertex;
01125 } while (pActVert != pActSolid->first_vertex);
01126 pActSolid = pActSolid->next_solid;
01127 } while (pActSolid != pSolid);
01128 }
01129