Mesh.cc

Go to the documentation of this file.
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);    /* zarad na konec seznamu vrcholu */
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   /* plocha LeftLoop neni videt */
00170   if (NE->RightLoop->skalar<=0) {
00171   /* plocha RightLoop neni videt */
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  /* zkopiruj vrcholy */  /* previous_vertex je pouzit jako new vertex address */
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  /* zkopiruj roviny */
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  /* zkopiruj hrany */
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  /* oprav ukazatele hran */
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  /* predpokladam, ze teleso je vyrazeno ze sceny */
00239 {
00240   Vert *CV,*NV;
00241   Edge *CE,*NE;
00242   Plane *CP,*NP;
00243 
00244   if (S!=NULL) {
00245     NV=(*S)->first_vertex;   /* rusim vrcholy */
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;     /* rusim hrany */
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;    /* rusim plochy */
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  /* klasifikuj vsechny vrcholy vuci rovine ar.x+br.y+cr.z+dr==0 */
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   /* Vin, Vout jsou vstupni a vystupni body hrany CE^, udavaji orientaci
00309     smycky na plose  */
00310   /* po provedeni funkce Next_edge_in_loop udavaji vstup a vystup na dalsi
00311     hrane */
00312       /* zkoumam hranu CE */
00313       /* volim dalsi hranu ve smycce pro rovinu NP */
00314   if (*Vin==CE->V1)  /* sleduji hrany LeftIn,LeftOut */
00315     NE=CE->LeftOut;
00316   else /* sleduj hrany RightOut,RightIn */
00317     NE=CE->RightOut;
00318   /* vime hranu, jeste nastavime spravnou orientaci Vin, Vout */
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   /* Vin, Vout jsou vstupni a vystupni body hrany CE^, udavaji orientaci
00330     smycky na plose  */
00331   /* po provedeni funkce Next_edge_in_loop udavaji vstup a vystup na dalsi
00332     hrane */
00333   /* couvam na predchozi hranu ve smycce */
00334   if (*Vin==CE->V1)
00335     NE=CE->LeftIn;
00336   else
00337     NE=CE->RightIn;
00338 
00339   /* vime hranu, jeste nastavime spravnou orientaci Vin, Vout */
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)) /* plocha LeftLoop neni videt */
00355       NE->druh_hrany=OBRYSOVA;
00356     if ((NE->RightLoop->skalar<=0))/* plocha RightLoop neni videt */
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)  /* make vertex */
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)  //make plane
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 /* make vertex, solid , face */
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   /* zarad vrchol V2p do seznamu vrcholu */
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)/* tato hrana je prvni */
00420     {
00421       (*E)->LeftIn=*E; (*E)->RightOut=*E; (*E)->LeftOut=*E; (*E)->RightIn=*E;
00422       F->any_edge=*E;
00423     }
00424   else
00425     /* na povrchu F nalezni hranu, ktera konci ve vrcholu V1 */
00426     {
00427       (*E)->LeftOut=*E; (*E)->RightIn=*E;  /* koncova smycka */
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)    /* sleduji levou smycku */
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   /* na povrchu F1 nalezni hranu CE, ktera konci ve vrcholu V2p */
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)/* tato hrana je prvni */
00503    {
00504      (*E)->LeftIn=*E; (*E)->RightOut=*E; (*E)->LeftOut=*E; (*E)->RightIn=*E;
00505      F1->any_edge=*E;
00506    }
00507  else
00508    /* na povrchu F1 nalezni hranu, ktera konci ve vrcholu V1 */
00509    {
00510      (*E)->LeftOut=*E; (*E)->RightIn=*E;  /* koncova smycka */
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)    /* sleduji levou smycku */
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 /* pripoj smycku */
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   /* na povrchu F1 nalezni hranu CE, ktera konci ve vrcholu V2p */
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)/* tato hrana je prvni */
00570    {
00571      (*E)->LeftIn=*E; (*E)->RightOut=*E; (*E)->LeftOut=*E; (*E)->RightIn=*E;
00572      F1->any_edge=*E;
00573    }
00574  else
00575    /* na povrchu F1 nalezni hranu, ktera konci ve vrcholu V1 */
00576    {
00577      (*E)->LeftOut=*E; (*E)->RightIn=*E;  /* koncova smycka */
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)    /* sleduji levou smycku */
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 /* pripoj smycku */
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   /* vim, ze hrana protina rezovou rovinu */
00620   /* protoze fxyz==a.x+b.y+c.z-d je jiz vypocteno a ulozeno
00621     u kazdeho vrcholu, nepotrebuji koeficienty roviny */
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            /* hrany LeftIn, RightOut patri k odpadu */
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 /* zaklad telesa */
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    /* zrus vrcholy s ...Valid==false */
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    /* zrus plochy se zapornym jmenem */
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 //------------------------ public --------------------------
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; // Last solid in list
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; // loop finished
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 

Generated on Wed Jun 28 12:24:31 2006 for esg by  doxygen 1.4.6