From 09cc49fc758373452e98733c17582c29960f3384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Remacle=20=28students=29?= <jean-francois.remacle@uclouvain.be> Date: Mon, 10 Aug 2009 13:45:49 +0000 Subject: [PATCH] *** empty log message *** --- Geo/GFaceCompound.cpp | 348 +++++++++++++++++++++++++++++++++--------- Geo/GFaceCompound.h | 1 + 2 files changed, 275 insertions(+), 74 deletions(-) diff --git a/Geo/GFaceCompound.cpp b/Geo/GFaceCompound.cpp index 83213a3aa1..44f6186d76 100644 --- a/Geo/GFaceCompound.cpp +++ b/Geo/GFaceCompound.cpp @@ -91,6 +91,217 @@ static void fixEdgeToValue(GEdge *ed, double value, gmshAssembler<double> &myAss } } +static void computeCGKernelPolygon(std::map<MVertex*,SPoint3> &coordinates, std::vector<MVertex*> &cavV, double &ucg, double &vcg){ + + ucg = 0.0; + vcg = 0.0; + + //Place at CG polygon + //-------------------- +// int nbVert = cavV.size(); +// printf("nbVert =%d \n", nbVert); + +// for (std::set<MVertex*>::const_iterator it = cavV.begin() ; it != cavV.end() ; ++it){ +// SPoint3 vsp = coordinates[*it]; +// ucg+=vsp[0]; +// vcg+=vsp[1]; +// } +// ucg/=nbVert; +// vcg/=nbVert; +// printf("ucg=%g vcg=%g \n", ucg, vcg); + + //Place at CG KERNEL polygon + //-------------------------- + + int nbPts = cavV.size(); + //printf("COUCOU kernel polygon nbPts = %d\n", nbPts); + gmshMatrix<double> u(100,2); + int i=0; + for (std::vector<MVertex*>::iterator it = cavV.begin(); it != cavV.end(); it++){ + SPoint3 vsp = coordinates[*it]; + u(i,0) = vsp[0]; + u(i,1) = vsp[1]; + //printf("u(%d,0)=%g, u(%d, 1)=%g \n", i, vsp[0], i, vsp[1]); + i++; + } + + //cavity 1 + // mat(0,0) =0.4158; mat(0,1)=0.445671; +// mat(1,0) =0.39449; mat(1,1)= 0.473701; +// mat(2,0) =0.399136; mat(2,1)= 0.452657; +// mat(3,0) =0.424101; mat(3,1)= 0.435164; +// mat(4,0) =0.431606; mat(4,1)= 0.44255; +// mat(5,0) =0.42926; mat(5,1)= 0.442389; + + // //cavity 3 +// mat(0,0) = 0. ; mat(0,1) = 5.; +// mat(1,0) = -4. ; mat(1,1) = -4.; +// mat(2,0) = 0. ; mat(2,1) = 0.; +// mat(3,0) = 4. ; mat(3,1) = -4.; + +// //cavity 4 +// mat(0,0) =0.; mat(0,1)=5. ; +// mat(1,0) =-2.; mat(1,1)=1. ; +// mat(2,0) =-4.; mat(2,1)=1. ; +// mat(3,0) =-2.; mat(3,1)= -1.; +// mat(4,0) =2.; mat(4,1)=-1. ; +// mat(5,0) =4.; mat(5,1)=1. ; +// mat(6,0) =2.; mat(6,1)= 1.; + +// //cavity 5 +// mat(0,0) =0.; mat(0,1)=5. ; +// mat(1,0) =-2.; mat(1,1)=1. ; +// mat(2,0) =-4.; mat(2,1)=1. ; +// mat(3,0) =-2.; mat(3,1)= -1.; +// mat(4,0) =-4.; mat(4,1)=-5. ; +// mat(5,0) =0.; mat(5,1)=-3 ; +// mat(6,0) =4.; mat(6,1)=-5.; +// mat(7,0) =2.; mat(7,1)=-1. ; +// mat(8,0) =4.; mat(8,1)=1. ; +// mat(9,0) =2.; mat(9,1)= 1.; + +// //cavity 6 +// mat(0,0) =1.; mat(0,1)=0. ; +// mat(1,0) =1.;mat(1,1)=1. ; +// mat(2,0) =0.;mat(2,1)=1. ; +// mat(3,0) =0.;mat(3,1)=0. ; + + double eps=-5.e-6; + int N=nbPts; + + std::set<int> setP; + for (int k=0; k< nbPts; k++) setP.insert(k); + //for(std::set<int>::iterator it =setP.begin(); it != setP.end(); it++) printf("setP =%d \n", *it); + + if(nbPts > 3){ + + for (int i=0; i< nbPts-2; i++){ + int next=i+1; + //printf("*** POINT i=%d next=%d\n", i, next); + //printf("-----------------------\n"); + double x1, x2, y1, y2; + x1=u(i,0); y1=u(i,1); + x2=u(next,0); y2=u(next,1); + for ( int j=i+2; j < nbPts; j++){ + int jnext = j+1; + if(j == nbPts-1) jnext = 0; + //printf("---> POINT j=%d jnext=%d\n", j, jnext); + double x3, x4, y3, y4, x,y; + double a, b, c, d; + x3=u(j,0); y3=u(j,1); + x4=u(jnext,0); y4=u(jnext,1); + a=(y2-y1)/(x2-x1); + c=(y4-y3)/(x4-x3); + b=y1-a*x1; + d=y3-c*x3; + if (std::abs(a-c) > 1.e-5 & x2!=x1 & x4 !=x3 & jnext != i){ + x=(d-b)/(a-c); + y=a*x+b; + bool exist= false; + for (int k= 1; k < setP.size(); k++){ + if (x == u(k,0) & y == u(k,1)) exist = true; + } + if (!exist){ + //printf("---> intersection (%d)=%g %g %g %g\n", N, x, y, a, c); + u(N,0)=x; u(N,1)=y; + setP.insert(N); + N++; + } + } + } + + } + + //for(std::set<int>::iterator it =setP.begin(); it != setP.end(); it++) printf("setP =%d \n", *it); + + int nbAll = setP.size(); + //printf("LAST DELETE LOOP nball=%d\n", nbAll); + //printf("*********************\n"); + for (int i=0; i <nbPts; i++){ + int next=i+1; + if(next==nbPts) next=0; + //printf("*** POINT i=%d next=%d\n", i, next); + //printf("-----------------------\n"); + double p1[2]={u(next,0)-u(i,0), u(next,1)-u(i,1) }; + for (int k=0; k < nbAll; k++){ + double p2[2] ={u(k,0)-u(i,0), u(k,1)-u(i,1)}; + double crossProd = p1[0]*p2[1]-p2[0]*p1[1]; + if(crossProd < eps){ + //printf("delete node k=%d, cross=%d\n", k, crossProd); + setP.erase(k); + } + } + } + + //for(std::set<int>::iterator it =setP.begin(); it != setP.end(); it++) printf("setP =%d \n", *it); + + } + + int nbFinal = setP.size(); + if (nbFinal > 0){ + for(std::set<int>::iterator it =setP.begin(); it != setP.end(); it++){ + ucg += u(*it,0); + vcg += u(*it,1); + } + ucg/=nbFinal; + vcg/=nbFinal; + } + else{ + Msg::Error("No Kernel for polygon. Try reparametrization with new initial mesh."); + Msg::Exit(0); + } + +} + +static void myPolygon(std::vector<MElement*> &vTri, std::vector<MVertex*> &vPoly){ + + std::vector<MEdge> ePoly; + for (unsigned int i = 0; i < vTri.size() ; i++) { + MTriangle *t = (MTriangle*) vTri[i]; + for (int iEdge = 0; iEdge < 3; iEdge++) { + MEdge tmp_edge = t->getEdge(iEdge); + MVertex *vB = tmp_edge.getVertex(0); + MVertex *vE = tmp_edge.getVertex(1); + if (std::find(ePoly.begin(), ePoly.end(), tmp_edge) == ePoly.end()) + ePoly.push_back(tmp_edge); + else + ePoly.erase(std::find(ePoly.begin(), ePoly.end(),tmp_edge)); + } + } + +// printf("epoly.size=%d vTri=%d\n", ePoly.size(), vTri.size()); +// for (std::vector<MEdge>::iterator ite = ePoly.begin(); ite != ePoly.end(); ite++){ +// MVertex *vB = ite->getVertex(0); +// MVertex *vE = ite->getVertex(1); +// printf("VB=%d vE=%d \n", vB->getNum(), vE->getNum()); +// } + + std::vector<MEdge>::iterator ite= ePoly.begin() ; + MVertex *vINIT = ite->getVertex(0); + vPoly.push_back(vINIT); + vPoly.push_back(ite->getVertex(1)); + ePoly.erase(ite); + + while (!ePoly.empty()){ + ite= ePoly.begin() ; + while (ite != ePoly.end()){ + MVertex *vB = ite->getVertex(0); + if( vB == vPoly.back()){ + MVertex *vE = ite->getVertex(1); + if (vE != vINIT) vPoly.push_back(vE); + ePoly.erase(ite); + } + else ite++; + } + } + +// printf("epoly.size=%d vTri=%d, cavV.size =%d\n", ePoly.size(), vTri.size(), vPoly.size()); +// for (std::vector<MVertex*>::iterator itv = vPoly.begin(); itv != vPoly.end(); itv++){ +// printf("VV=%d \n", (*itv)->getNum()); +// } + +} + bool GFaceCompound::trivial() const { if (_compound.size() == 1 && (*(_compound.begin()))->getNativeType()==GEntity::OpenCascadeModel && @@ -143,6 +354,31 @@ bool GFaceCompound::checkOrientation() const } +bool GFaceCompound::checkCavity(std::vector<MElement*> &vTri) const{ + + bool badCavity = false; + + int nbV = vTri.size(); + double a_old, a_new; + for (unsigned int i = 0; i < nbV; ++i){ + MTriangle *t = (MTriangle*) vTri[i]; + SPoint3 v1 = coordinates[t->getVertex(0)]; + SPoint3 v2 = coordinates[t->getVertex(1)]; + SPoint3 v3 = coordinates[t->getVertex(2)]; + double p1[2] = {v1[0],v1[1]}; + double p2[2] = {v2[0],v2[1]}; + double p3[2] = {v3[0],v3[1]}; + //printf("p1=(%g %g) p2=(%g %g) p3=(%g %g)\n",v1[0],v1[1], v2[0],v2[1], v3[0],v3[1] ); + a_new = gmsh::orient2d(p1, p2, p3); + if (i == 0) a_old=a_new; + if (a_new*a_old < 0.) badCavity = true; + a_old = a_new; + } + + return badCavity; + +} + void GFaceCompound::one2OneMap() const{ if (!mapv2Tri){ @@ -152,90 +388,54 @@ void GFaceCompound::one2OneMap() const{ allTri.insert(allTri.end(), (*it)->triangles.begin(), (*it)->triangles.end() ); } buildVertexToTriangle(allTri, adjv); - //printf("allTri size =%d\n", allTri.size()); mapv2Tri=true; } for (v2t_cont::iterator it = adjv.begin(); it!= adjv.end(); ++it){ MVertex *v = it->first; - std::vector<MElement*> vTri = it->second; - int nbV = vTri.size(); - double a_old, a_new; - bool badCavity = false; - std::map<MVertex*,SPoint3>::iterator itV = coordinates.find(v); - //printf("*** Node = %d: (%g %g) cavity size = %d \n", v->getNum(), itV->second.x(), itV->second.y(), nbV); - - std::set<MVertex*> cavV; - - for (unsigned int i = 0; i < nbV; ++i){ - MTriangle *t = (MTriangle*) vTri[i]; - SPoint3 v1 = coordinates[t->getVertex(0)]; - SPoint3 v2 = coordinates[t->getVertex(1)]; - SPoint3 v3 = coordinates[t->getVertex(2)]; - for (int k=0; k< 3; k++){ - MVertex *vk = t->getVertex(k); - std::set<MVertex*>::const_iterator it = cavV.find(vk); - if( it == cavV.end() && v != vk ) { - cavV.insert(vk); - //if (v != vk) cavV.insert(vk); - //if (v->onWhat()->dim() == 1 && v == vk) cavV.insert(vk); - } - } - - double p1[2] = {v1[0],v1[1]}; - double p2[2] = {v2[0],v2[1]}; - double p3[2] = {v3[0],v3[1]}; - //printf("p1=(%g %g) p2=(%g %g) p3=(%g %g)\n",v1[0],v1[1], v2[0],v2[1], v3[0],v3[1] ); - a_new = gmsh::orient2d(p1, p2, p3); - if (i == 0) a_old=a_new; - if (a_new*a_old < 0.) badCavity = true; - a_old = a_new; - } + + std::vector<MVertex*> cavV; + std::vector<MElement*> vTri = it->second; + bool badCavity = checkCavity(vTri); + if(badCavity){ - Msg::Info("Wrong cavity place vertex (%d onwhat=%d) at center of gravity (sizeCav=%d).", v->getNum(), v->onWhat()->dim(), nbV); - - int nbVert = cavV.size(); - //printf("nbVert =%d \n", nbVert); - double u_cg = 0.0; - double v_cg = 0.0; - for (std::set<MVertex*>::const_iterator it = cavV.begin() ; it != cavV.end() ; ++it){ - SPoint3 vsp = coordinates[*it]; - u_cg+=vsp[0]; - v_cg+=vsp[1]; - } - u_cg/=nbVert; - v_cg/=nbVert; - //printf("ucg=%g vcg=%g \n", u_cg, v_cg); + Msg::Info("Wrong cavity around vertex (%d onwhat=%d).", v->getNum(), v->onWhat()->dim()); + Msg::Info("--> Place vertex at center of gravity of %d-Polygon kernel." , vTri.size()); + +// for (int i=0; i< vTri.size(); i++){ +// MTriangle *t = (MTriangle*) vTri[i]; +// SPoint3 v1 = coordinates[t->getVertex(0)]; +// SPoint3 v2 = coordinates[t->getVertex(1)]; +// SPoint3 v3 = coordinates[t->getVertex(2)]; + +// printf("//////////////////// \n " ); +// double p1[2] = {v1[0],v1[1]}; +// double p2[2] = {v2[0],v2[1]}; +// double p3[2] = {v3[0],v3[1]}; +// double a_new = gmsh::orient2d(p1, p2, p3); +// MVertex *e1=t->getVertex(0); MVertex *e2=t->getVertex(1); MVertex *e3=t->getVertex(2); +// printf("Point(%d)={%g, %g, 0}; \n ",e1->getNum(), v1[0],v1[1] ); +// printf("Point(%d)={%g, %g, 0}; \n ",e2->getNum(), v2[0],v2[1] ); +// printf("Point(%d)={%g, %g, 0}; \n ",e3->getNum(), v3[0],v3[1] ); +// printf("Line(%d)={%d,%d}; \n", e1->getNum()+e2->getNum() , e1->getNum(), e2->getNum()); +// printf("Line(%d)={%d,%d}; \n", e2->getNum()+e3->getNum() , e2->getNum(), e3->getNum()); +// printf("Line(%d)={%d,%d}; \n", e3->getNum()+e1->getNum() , e3->getNum(), e1->getNum()); +// printf("Surface(%d)={%d,%d, %d}; \n", e3->getNum()+e1->getNum() + e2->getNum(), e3->getNum(), e1->getNum()+e2->getNum() , +// e2->getNum()+e3->getNum() , e3->getNum()+e1->getNum() ); +// printf("//Area=%g \n", a_new); +// } + + double u_cg, v_cg; + myPolygon(vTri, cavV); + computeCGKernelPolygon(coordinates, cavV, u_cg, v_cg); SPoint3 p_cg(u_cg,v_cg,0); coordinates[v] = p_cg; - // //NEW CAVITY: -// printf("//**** NEW CAVITY****** \n " ); -// for (int i=0; i< nbV; i++){ -// MTriangle *t = (MTriangle*) vTri[i]; -// SPoint3 v1 = coordinates[t->getVertex(0)]; -// SPoint3 v2 = coordinates[t->getVertex(1)]; -// SPoint3 v3 = coordinates[t->getVertex(2)]; - -// printf("//////////////////// \n " ); -// double p1[2] = {v1[0],v1[1]}; -// double p2[2] = {v2[0],v2[1]}; -// double p3[2] = {v3[0],v3[1]}; -// a_new = gmsh::orient2d(p1, p2, p3); -// MVertex *e1=t->getVertex(0); MVertex *e2=t->getVertex(1); MVertex *e3=t->getVertex(2); -// printf("Point(%d)={%g, %g, 0}; \n ",e1->getNum(), v1[0],v1[1] ); -// printf("Point(%d)={%g, %g, 0}; \n ",e2->getNum(), v2[0],v2[1] ); -// printf("Point(%d)={%g, %g, 0}; \n ",e3->getNum(), v3[0],v3[1] ); -// printf("Line(%d)={%d,%d}; \n", e1->getNum()+e2->getNum() , e1->getNum(), e2->getNum()); -// printf("Line(%d)={%d,%d}; \n", e2->getNum()+e3->getNum() , e2->getNum(), e3->getNum()); -// printf("Line(%d)={%d,%d}; \n", e3->getNum()+e1->getNum() , e3->getNum(), e1->getNum()); -// printf("Surface(%d)={%d,%d, %d}; \n", e3->getNum()+e1->getNum() + e2->getNum(), e3->getNum(), e1->getNum()+e2->getNum() , -// e2->getNum()+e3->getNum() , e3->getNum()+e1->getNum() ); -// printf("//Area=%g \n", a_new); -// } -// //NEW CAVITY: -// exit(1); + //printf("Kernel CG: ucg=%g vcg=%g \n", u_cg, v_cg); + //bool testbadCavity = checkCavity(vTri); + //if (testbadCavity == true ) printf("**** New cavity is KO \n"); + //else printf("-- New cavity is OK \n"); } } diff --git a/Geo/GFaceCompound.h b/Geo/GFaceCompound.h index 66ba18a69c..7974e302f2 100644 --- a/Geo/GFaceCompound.h +++ b/Geo/GFaceCompound.h @@ -62,6 +62,7 @@ class GFaceCompound : public GFace { void parametrize(iterationStep) const ; bool checkOrientation() const; void one2OneMap() const; + bool checkCavity(std::vector<MElement*> &vTri) const; void computeNormals () const; void getBoundingEdges(); void getTriangle(double u, double v, GFaceCompoundTriangle **lt, -- GitLab