diff --git a/Geo/CMakeLists.txt b/Geo/CMakeLists.txt index 4f8685ff42167732df7a0a5118931e7b7611ad52..514533cc4e539888164f5efaf9042d15a863b2c2 100644 --- a/Geo/CMakeLists.txt +++ b/Geo/CMakeLists.txt @@ -10,7 +10,8 @@ set(SRC GVertex.cpp GEdge.cpp GFace.cpp GRegion.cpp GEdgeLoop.cpp GEdgeCompound.cpp GFaceCompound.cpp GRegionCompound.cpp GRbf.cpp - gmshVertex.cpp gmshEdge.cpp gmshFace.cpp gmshRegion.cpp gmshSurface.cpp + gmshVertex.cpp gmshEdge.cpp gmshFace.cpp gmshRegion.cpp + gmshCurve.cpp gmshSurface.cpp OCCVertex.cpp OCCEdge.cpp OCCFace.cpp OCCRegion.cpp discreteEdge.cpp discreteFace.cpp discreteRegion.cpp fourierEdge.cpp fourierFace.cpp fourierProjectionFace.cpp diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp index 9f1620c42c4767d1f9236568eb0062fad2c2b448..238c63b82b0ba06cffb37b9dc35c7e5b06eebf76 100644 --- a/Geo/GFace.cpp +++ b/Geo/GFace.cpp @@ -967,7 +967,6 @@ GPoint GFace::closestPoint(const SPoint3 &queryPoint, const double initialGuess[ GPoint pnt = point(initialGuess[0], initialGuess[1]); SPoint3 spnt(pnt.x(), pnt.y(), pnt.z()); double dist = queryPoint.distance(spnt); - printf("dist = %12.5E\n",dist); } // FILE *F = Fopen ("hop.pos","w"); diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 096918d28027447ca7a0511c908eefb6732ab34f..d2e04c5aebe241c1dc59ac3abdbc57829f2152b8 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -2652,6 +2652,15 @@ GEdge *GModel::addBezier(GVertex *start, GVertex *end, return 0; } +GEdge *GModel::addBSpline(GVertex *start, GVertex *end, + std::vector<std::vector<double> > points) +{ + if(_factory) + return _factory->addSpline(this, GModelFactory::BSPLINE, start, end, + points); + return 0; +} + GEdge *GModel::addNURBS(GVertex *start, GVertex *end, std::vector<std::vector<double> > points, std::vector<double> knots, diff --git a/Geo/GModel.h b/Geo/GModel.h index f026f38b6ce8ee25f0d002eeffc46a0a7abf6339..8fc5068a07e53c392aca034c9fd9992ecabf6486 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -489,6 +489,7 @@ class GModel GEdge *addCircleArcCenter(GVertex *start, GVertex *center, GVertex *end); GEdge *addCircleArc3Points(double x, double y, double z, GVertex *start, GVertex *end); GEdge *addBezier(GVertex *start, GVertex *end, std::vector<std::vector<double> > points); + GEdge *addBSpline(GVertex *start, GVertex *end, std::vector<std::vector<double> > points); GEdge *addNURBS(GVertex *start, GVertex *end, std::vector<std::vector<double> > points, std::vector<double> knots, diff --git a/Geo/GModelFactory.cpp b/Geo/GModelFactory.cpp index 19b29e28063707280589e51142c591ed82b5dafb..4a7cbeae41e38b6269649a5b54553c73b10b6482 100644 --- a/Geo/GModelFactory.cpp +++ b/Geo/GModelFactory.cpp @@ -20,6 +20,7 @@ #include "Geo.h" #include "GmshDefines.h" + GVertex *GeoFactory::addVertex(GModel *gm, double x, double y, double z, double lc) { int num = gm->getMaxElementaryNumber(0) + 1; @@ -481,6 +482,7 @@ std::vector<GEntity*> GeoFactory::extrudeBoundaryLayer(GModel *gm, GEntity *e, #include <TopoDS_Wire.hxx> #include <TopoDS_Compound.hxx> #include <TopTools_ListOfShape.hxx> +#include <GeomAPI_PointsToBSpline.hxx> #include "OCC_Connect.h" #if defined(HAVE_SALOME) #include "Partition_Spliter.hxx" @@ -581,18 +583,33 @@ GEdge *OCCFactory::addSpline(GModel *gm, const splineType &type, TColgp_Array1OfPnt ctrlPoints(1, nbControlPoints + 2); int index = 1; ctrlPoints.SetValue(index++, gp_Pnt(start->x(), start->y(), start->z())); + + // printf("%d %d %d %d\n",points.size(),points[0].size(),points[1].size(),points[2].size()); for (int i = 0; i < nbControlPoints; i++) { + // printf("%g %g %g\n",points[i][0],points[i][1],points[i][2]); gp_Pnt aP(points[i][0],points[i][1],points[i][2]); ctrlPoints.SetValue(index++, aP); } ctrlPoints.SetValue(index++, gp_Pnt(end->x(), end->y(), end->z())); if (type == BEZIER) { + if (nbControlPoints >= 20)Msg::Fatal("OCC Bezier Curves have a maximum degree of 20"); Handle(Geom_BezierCurve) Bez = new Geom_BezierCurve(ctrlPoints); if (occv1 && occv2) occEdge = BRepBuilderAPI_MakeEdge(Bez,occv1->getShape(),occv2->getShape()).Edge(); else occEdge = BRepBuilderAPI_MakeEdge(Bez).Edge(); } + else if (type == BSPLINE) { + + Handle(Geom_BSplineCurve) Bez = GeomAPI_PointsToBSpline(ctrlPoints).Curve(); + + if (occv1 && occv2) + occEdge = BRepBuilderAPI_MakeEdge(Bez,occv1->getShape(),occv2->getShape()).Edge(); + else + occEdge = BRepBuilderAPI_MakeEdge(Bez).Edge(); + } + + return gm->_occ_internals->addEdgeToModel(gm, occEdge); } diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp index 42bb88ce9eba4c0d9893b2c78b1d564b5a034a9e..f6b8a077f84602ee40bf8fe105e44de3fef54bcf 100644 --- a/Geo/GModelIO_OCC.cpp +++ b/Geo/GModelIO_OCC.cpp @@ -692,10 +692,17 @@ GRegion* OCC_Internals::addRegionToModel(GModel *model, TopoDS_Solid region) { GRegion *gr = getOCCRegionByNativePtr(model, region); if(gr) return gr; - addShapeToLists(region); + buildShapeFromLists(region); + model->destroy(); + buildLists(); buildGModel(model); return getOCCRegionByNativePtr(model, region); + + // addShapeToLists(region); + // buildShapeFromLists(region); + // buildGModel(model); + // return getOCCRegionByNativePtr(model, region); } /* I needed getGTagOfOCC*ByNativePtr whithin setPhysicalNumToEntitiesInBox */ diff --git a/Geo/MElementOctree.cpp b/Geo/MElementOctree.cpp index ce8db23964fa307ab2ca2b4611364a0d605b6aa0..e65860ca16fbcb8d1e03650ceaa1815c5438cc66 100644 --- a/Geo/MElementOctree.cpp +++ b/Geo/MElementOctree.cpp @@ -9,7 +9,7 @@ #include "Octree.h" #include "Context.h" -static void MElementBB(void *a, double *min, double *max) +void MElementBB(void *a, double *min, double *max) { MElement *e = (MElement*)a; MVertex *v = e->getVertex(0); @@ -47,7 +47,7 @@ static void MElementCentroid(void *a, double *x) x[2] *= oc; } -static int MElementInEle(void *a, double *x) +int MElementInEle(void *a, double *x) { MElement *e = (MElement*)a; double uvw[3]; diff --git a/Geo/MVertex.cpp b/Geo/MVertex.cpp index 40fff3e7cf056e791050c2e8d00ebf1f19be8c3b..98dceccb732b641d583aa304098376eb85204618 100644 --- a/Geo/MVertex.cpp +++ b/Geo/MVertex.cpp @@ -452,17 +452,6 @@ bool reparamMeshEdgeOnFace(MVertex *v1, MVertex *v2, GFace *gf, } } } - /* - if (p1.size() == 8 ||p2.size() == 8){ - for (int i=0;i<p1.size();i++){ - printf("p1[%d] = %g %g\n",i,p1[i].x(),p1[i].y()); - } - for (int i=0;i<p2.size();i++){ - printf("p2[%d] = %g %g\n",i,p2[i].x(),p2[i].y()); - } - printf("%d %d\n",imin,jmin); - } - */ param1 = p1[jmin]; param2 = p2[imin]; } diff --git a/Geo/OCCEdge.cpp b/Geo/OCCEdge.cpp index 589d9a1668c2dc29322e178fc49e7617c963db54..23c59eba933d3fe5e5b4c72860df3653c75b7a22 100644 --- a/Geo/OCCEdge.cpp +++ b/Geo/OCCEdge.cpp @@ -93,18 +93,20 @@ SPoint2 OCCEdge::reparamOnFace(const GFace *face, double epar, int dir) const pnt.Coord(u, v); // sometimes OCC miserably fails ... - GPoint p1 = point(epar); - GPoint p2 = face->point(u, v); - const double dx = p1.x()-p2.x(); - const double dy = p1.y()-p2.y(); - const double dz = p1.z()-p2.z(); - if(sqrt(dx * dx + dy * dy + dz * dz) > 1.e-2 * CTX::instance()->lc){ - Msg::Warning("Reparam on face was inaccurate for curve %d on surface %d at point %g", - tag(), face->tag(), epar); - Msg::Warning("On the face %d local (%g %g) global (%g %g %g)", - face->tag(), u, v, p2.x(), p2.y(), p2.z()); - Msg::Warning("On the edge %d local (%g) global (%g %g %g)", - tag(), epar, p1.x(), p1.y(), p1.z()); + if (0){ + GPoint p1 = point(epar); + GPoint p2 = face->point(u, v); + const double dx = p1.x()-p2.x(); + const double dy = p1.y()-p2.y(); + const double dz = p1.z()-p2.z(); + if(sqrt(dx * dx + dy * dy + dz * dz) > 1.e-2 * CTX::instance()->lc){ + Msg::Warning("Reparam on face was inaccurate for curve %d on surface %d at point %g", + tag(), face->tag(), epar); + Msg::Warning("On the face %d local (%g %g) global (%g %g %g)", + face->tag(), u, v, p2.x(), p2.y(), p2.z()); + Msg::Warning("On the edge %d local (%g) global (%g %g %g)", + tag(), epar, p1.x(), p1.y(), p1.z()); + } } return SPoint2(u, v); } diff --git a/Geo/boundaryLayersData.cpp b/Geo/boundaryLayersData.cpp index 7d572a276ce97ad5d169396d3218e5474a28fb70..c6430d92619e39caebe8570a8b0d956ff82c46e9 100644 --- a/Geo/boundaryLayersData.cpp +++ b/Geo/boundaryLayersData.cpp @@ -17,10 +17,6 @@ #include "OS.h" #include "BackgroundMesh.h" -#if defined(HAVE_RTREE) -#include "rtree.h" -#endif - #if !defined(HAVE_MESH) || !defined(HAVE_ANN) BoundaryLayerField* getBLField(GModel *gm){ return 0; } @@ -152,23 +148,10 @@ const BoundaryLayerData & BoundaryLayerColumns::getColumn(MVertex *v, MFace f) { int N = getNbColumns(v) ; if (N == 1) return getColumn(v, 0); - if (isOnWedge (v)){ - GFace *gf = _inverse_classification[f]; - BoundaryLayerFanWedge3d w = getWedge(v); - if (w.isLeft(gf))return getColumn(v, 0); - if (w.isRight(gf))return getColumn(v, N-1); - Msg::Error("Strange behavior for a wedge"); - } - if (isCorner (v)){ - GFace *gf = _inverse_classification[f]; - BoundaryLayerFanCorner3d c = getCorner(v); - int k = 0; - for (unsigned int i=0;i<c._gf.size();i++){ - if (c._gf[i] == gf){ - return getColumn(v, k); - } - k += (c._fanSize - 1); - } + GFace *gf = _inverse_classification[f]; + for (int i=0;i<N;i++){ + const BoundaryLayerData & c = getColumn(v, i); + if (std::find(c._joint.begin(),c._joint.end(),gf) != c._joint.end())return c; } static BoundaryLayerData error; return error; @@ -782,8 +765,6 @@ bool buildAdditionalPoints2D(GFace *gf) } // DEBUG STUFF - _columns->filterPoints(gf,0.21); - char name[256]; sprintf(name,"points_face_%d.pos",gf->tag()); FILE *f = Fopen (name,"w"); @@ -835,6 +816,56 @@ static void createBLPointsInDir(GRegion *gr, } } + +static bool createWedgeBetweenTwoFaces(MVertex *myV, + SVector3 n1, SVector3 n2, + std::vector<SVector3> &shoot) +{ + double angle = angle_0_180 (n1,n2); + int fanSize = FANSIZE__; //angle / _treshold; + for (int i=-1; i<=fanSize; i++){ + + double ti = (double)(i+1)/ (fanSize+1); + double angle_t = ti * angle; + double cosA = cos (angle_t); + double cosAlpha = dot(n1,n2); + + const double A = (1.- 2.*cosA*cosA) + cosAlpha*cosAlpha - 2 * cosAlpha*(1.-cosA*cosA); + const double B = -2*(1.-cosA*cosA)*(1-cosAlpha); + const double C = 1.-cosA*cosA; + double DELTA = B*B-4*A*C; + double t = 0.0; + if (A == 0.0){ + t = -C / B; + } + else if (C != 0.0){ + if (DELTA < 0){ + Msg::Error("this should not happen DELTA = %12.5E",DELTA); + DELTA = 0; + } + const double t1 = (-B+sqrt(DELTA))/(2.*A); + const double t2 = (-B-sqrt(DELTA))/(2.*A); + + SVector3 x1 (n1*(1.-t1) + n2 * t2); + SVector3 x2 (n1*(1.-t2) + n2 * t2); + double a1 = angle_0_180 (n1,x1); + double a2 = angle_0_180 (n1,x2); + if (fabs(a1 - angle_t) < fabs(a2 - angle_t))t = t1; + else t = t2; + } + SVector3 x (n1*(1.-t) + n2 * t); + x.normalize(); + shoot.push_back(x); + } + return true; +} + +void computeAllGEdgesThatAreCreatingFans (GRegion *gr, std::vector<GEdge*> &fans) +{ + +} + + static void createColumnsBetweenFaces(GRegion *gr, MVertex *myV, BoundaryLayerField *blf, @@ -870,6 +901,7 @@ static void createColumnsBetweenFaces(GRegion *gr, // printf("vertex %d %d faces\n",myV->getNum(),count); std::set<int> done; + std::vector< std::vector<GFace*> > joints; for (int i=0;i<count;i++){ if (done.find(i) == done.end()){ SVector3 n1 = n[i]; @@ -893,91 +925,38 @@ static void createColumnsBetweenFaces(GRegion *gr, if (joint.size()){ std::vector<MVertex*> _column; std::vector<SMetric3> _metrics; + joints.push_back(joint); avg.normalize(); createBLPointsInDir (gr,myV,blf,avg,_column,_metrics); _columns->addColumn(avg,myV, _column, _metrics, joint); } - // printf("adding one column for %d faces\n",joint.size()); + // printf("adding one column for %d fqaces\n",joint.size()); } } -} - -/* -static bool createWedgeBetweenTwoFaces(bool testOnly, - MVertex *myV, - GFace *gf1, GFace *gf2, - std::multimap<GFace*,MTriangle*> & _faces, - std::map<MFace,SVector3,Less_Face> &_normals, - double _treshold, - std::vector<SVector3> &shoot) -{ - SVector3 n1,n2; - SPoint3 c1,c2; - for (std::multimap<GFace*,MTriangle*>::iterator itm = - _faces.lower_bound(gf1); - itm != _faces.upper_bound(gf1); ++itm){ - n1 += _normals[itm->second->getFace(0)]; - c1 = itm->second->getFace(0).barycenter(); - } - for (std::multimap<GFace*,MTriangle*>::iterator itm = - _faces.lower_bound(gf2); - itm != _faces.upper_bound(gf2); ++itm){ - n2 += _normals[itm->second->getFace(0)]; - c2 = itm->second->getFace(0).barycenter(); - } - n1.normalize(); - n2.normalize(); - // FIXME WRONG FOR INTERNAL CORNERS !!! - double angle = angle_0_180 (n1,n2); - double sign = dot((n1-n2),(c1-c2)); - if (angle > _treshold && sign > 0){ - if(testOnly)return true; - int fanSize = FANSIZE__; //angle / _treshold; - for (int i=-1; i<=fanSize; i++){ - - double ti = (double)(i+1)/ (fanSize+1); - double angle_t = ti * angle; - double cosA = cos (angle_t); - double cosAlpha = dot(n1,n2); - - const double A = (1.- 2.*cosA*cosA) + cosAlpha*cosAlpha - 2 * cosAlpha*(1.-cosA*cosA); - const double B = -2*(1.-cosA*cosA)*(1-cosAlpha); - const double C = 1.-cosA*cosA; - double DELTA = B*B-4*A*C; - double t = 0.0; - if (A == 0.0){ - t = -C / B; - } - else if (C != 0.0){ - if (DELTA < 0){ - Msg::Error("this should not happen DELTA = %12.5E",DELTA); - DELTA = 0; + // create wedges + if (joints.size() > 1){ + for (unsigned int I = 0 ; I < joints.size() ; I++){ + const BoundaryLayerData & c0 = _columns->getColumn(myV, I); + for (unsigned int J = I+1 ; J < joints.size() ; J++){ + const BoundaryLayerData & c1 = _columns->getColumn(myV, J); + std::vector<SVector3> shoot; + createWedgeBetweenTwoFaces(myV,c0._n,c1._n,shoot); + for (unsigned int i=1;i<shoot.size()-1;i++){ + std::vector<MVertex*> _column; + std::vector<SMetric3> _metrics; + createBLPointsInDir (gr,myV,blf,shoot[i],_column,_metrics); + _columns->addColumn(shoot[i] , myV, _column, _metrics); } - const double t1 = (-B+sqrt(DELTA))/(2.*A); - const double t2 = (-B-sqrt(DELTA))/(2.*A); - - SVector3 x1 (n1*(1.-t1) + n2 * t2); - SVector3 x2 (n1*(1.-t2) + n2 * t2); - double a1 = angle_0_180 (n1,x1); - double a2 = angle_0_180 (n1,x2); - if (fabs(a1 - angle_t) < fabs(a2 - angle_t))t = t1; - else t = t2; } - SVector3 x (n1*(1.-t) + n2 * t); - x.normalize(); - shoot.push_back(x); } - return true; } - else { - if(testOnly)return false; - SVector3 n = n1+n2; - n.normalize(); - shoot.push_back(n); - return false; + // we have a corner : in a first step, only add one single + // in the average direction + if (joints.size() > 2){ } } -*/ + + BoundaryLayerColumns *buildAdditionalPoints3D(GRegion *gr) { @@ -1079,6 +1058,8 @@ BoundaryLayerColumns *buildAdditionalPoints3D(GRegion *gr) } } + // we have a 3D boundary layer that connects a 2D boundary layer + // this is the tricky case if (onSymmetryPlane){ for ( std::list<GFace*>::iterator itf = faces.begin(); itf!= faces.end() ; ++itf){ BoundaryLayerColumns* _face_columns = (*itf)->getColumns(); @@ -1087,10 +1068,70 @@ BoundaryLayerColumns *buildAdditionalPoints3D(GRegion *gr) std::vector<GFace*> _joint; _joint.insert(_joint.begin(),_allGFaces.begin(),_allGFaces.end()); const BoundaryLayerData & c = _face_columns->getColumn(*it,0); - _columns->addColumn(_allDirs[0],*it, c._column, c._metrics, _joint); + _columns->addColumn(c._n,*it, c._column, c._metrics, _joint); } else if (N > 1){ - Msg::Error ("Impossible connexion between face and region BLs"); + if (_allGFaces.size() != 2){ + Msg::Fatal("cannot solve such a strange stuff in the BL"); + } + // printf("%d columns\n",N); + std::set<GFace*>::iterator itff = _allGFaces.begin(); + GFace *g1 = *itff ; ++itff; GFace *g2 = *itff; + int sense = 1; + std::vector<GFace*> _joint; + + const BoundaryLayerFan *fan = _face_columns->getFan(*it); + + if (fan){ + MVertex *v11 = fan->_e1.getVertex(0); + MVertex *v12 = fan->_e1.getVertex(1); + std::list<GEdge*> l1 = g1->edges(); + std::list<GEdge*> l2 = g2->edges(); + if (v11 == *it){ + if (v12->onWhat()->dim() == 1){ + GEdge *ge1 = (GEdge*)v12->onWhat(); + // printf("COUCOU %d %d %d\n",fan->sense,std::find(l1.begin(),l1.end(),ge1) != l1.end(),std::find(l2.begin(),l2.end(),ge1) != l2.end()); + if (std::find(l1.begin(),l1.end(),ge1) != l1.end())sense = fan->sense; + else if (std::find(l2.begin(),l2.end(),ge1) != l2.end())sense = -fan->sense; + else printf("strange1 %d %d \n"); + } + else Msg::Error("Cannot choose between directions in a BL (dim = %d)",v12->onWhat()->dim()); + } + else { + if (v11->onWhat()->dim() == 1){ + GEdge *ge1 = (GEdge*)v11->onWhat(); + if (std::find(l1.begin(),l1.end(),ge1) != l1.end())sense = fan->sense; + else if (std::find(l2.begin(),l2.end(),ge1) != l2.end())sense = -fan->sense; + else printf("strange2 %d %d \n"); + } + else Msg::Error("Cannot choose between directions in a BL"); + } + } + else{ + Msg::Error("No fan on the outgoing BL"); + } + _joint.push_back(g1); + const BoundaryLayerData & c0 = _face_columns->getColumn(*it,sense==1 ? 0 : N-1); + _columns->addColumn(c0._n,*it, c0._column, c0._metrics,_joint); + _joint.clear(); + _joint.push_back(g2); + const BoundaryLayerData & cN = _face_columns->getColumn(*it,sense==1 ? N-1 : 0); + _columns->addColumn(cN._n,*it, cN._column, cN._metrics,_joint); + // printf("%g %g %g --> %g %g %g\n",c0._n.x(),c0._n.y(),c0._n.z(),cN._n.x(),cN._n.y(),cN._n.z()); + if (sense==1){ + for (int k=1;k<N-1;k++){ + const BoundaryLayerData & c = _face_columns->getColumn(*it,k); + _columns->addColumn(c._n,*it, c._column, c._metrics); + // printf("%g %g %g \n",c._n.x(),c._n.y(),c._n.z()); + } + } + else { + for (int k=N-2;k>0;k--){ + const BoundaryLayerData & c = _face_columns->getColumn(*it,k); + _columns->addColumn(c._n,*it, c._column, c._metrics); + // printf("%g %g %g \n",c._n.x(),c._n.y(),c._n.z()); + } + } } } } @@ -1101,7 +1142,7 @@ BoundaryLayerColumns *buildAdditionalPoints3D(GRegion *gr) // DEBUG STUFF - FILE *f = fopen ("test3D.pos","w"); + FILE *f = fopen ("POINTS3D.pos","w"); fprintf(f,"View \"\" {\n"); for (std::set<MVertex*>::iterator it = _vertices.begin(); it != _vertices.end() ; ++it){ MVertex *v = *it; @@ -1121,176 +1162,4 @@ BoundaryLayerColumns *buildAdditionalPoints3D(GRegion *gr) return _columns; } -struct blPoint_wrapper -{ - bool _tooclose; - MVertex *_v; - std::map<MVertex*,MVertex*> &_v2v; - blPoint_wrapper (MVertex *v, std::map<MVertex*,MVertex*> &v2v) - : _tooclose(false), _v(v), _v2v(v2v) {} -}; - -struct blPoint_rtree -{ - MVertex *_v; - double _size; - blPoint_rtree (MVertex *v, double size) : - _v(v), _size(size) {} - bool inExclusionZone (MVertex *v){ - double d = _v->distance(v); - //printf("d = %12.5E\n",d); - if (d <= _size) return true; - return false; - } - void minmax (double min[3], double max[3]){ - min[0] = _v->x() - _size; - min[1] = _v->y() - _size; - min[2] = _v->z() - _size; - max[0] = _v->x() + _size; - max[1] = _v->y() + _size; - max[2] = _v->z() + _size; - } -}; - - -bool rtree_callback(blPoint_rtree *neighbour,void* point){ - blPoint_wrapper *w = static_cast<blPoint_wrapper*>(point); - - const MVertex *from_1 = w->_v2v[neighbour->_v]; - const MVertex *from_2 = w->_v2v[w->_v]; - - // printf("%p %p\n",from_1,from_2); - - if (from_1 == from_2) { - return true; - } - - if (neighbour->inExclusionZone(w->_v)){ - w->_tooclose = true; - return false; - } - return true; -} - -#if defined(HAVE_RTREE) -bool inExclusionZone_filter (MVertex* p, - std::map <MVertex*, MVertex*> &v2v, - RTree< blPoint_rtree *,double,3,double> &rtree){ - // should assert that the point is inside the domain - { - double u, v; - p->getParameter(0,u); - p->getParameter(1,v); - if (!backgroundMesh::current()->inDomain(u,v,0)) return true; - } - - blPoint_wrapper w (p,v2v); - double _min[3] = {p->x()-1.e-1, p->y()-1.e-1,p->z()-1.e-1}; - double _max[3] = {p->x()+1.e-1, p->y()+1.e-1,p->z()+1.e-1}; - rtree.Search(_min,_max,rtree_callback,&w); - - return w._tooclose; -} -#endif - - -void BoundaryLayerColumns::filterPoints(GEntity *ge, double factor) -{ -#if defined(HAVE_RTREE) - // return; - // compute the element sizes - std::map<MVertex*,double> sizes; - if (ge->dim() == 2){ - backgroundMesh::set((GFace *)ge); - std::list<GEdge*> edges = ge->edges(); - std::list<GEdge*>::iterator it = edges.begin(); - for ( ; it != edges.end() ; ++it){ - GEdge *ged = *it; - for (unsigned int i=0;i<ged->lines.size();i++){ - MLine *e = ged->lines[i]; - MVertex *v0 = e->getVertex(0); - MVertex *v1 = e->getVertex(1); - double d = v0->distance(v1); - std::map<MVertex*,double>::iterator it0 = sizes.find(v0); - if (it0 == sizes.end()) sizes[v0] = d; - else it0->second = std::max(d, it0->second); - std::map<MVertex*,double>::iterator it1 = sizes.find(v1); - if (it1 == sizes.end()) sizes[v1] = d; - else it1->second = std::max(d, it1->second); - } - } - } - else { - Msg::Fatal("code ce truc JF !"); - } - - // a RTREE data structure that enables to verify if - // points are too close - RTree<blPoint_rtree*,double,3,double> rtree; - // stores the info "where the new vertex comes form" - std::map <MVertex*, MVertex*> v2v; - - // compute maximum column size - // initialize the RTREE with points on the boundary - unsigned int MAXCOLSIZE = 0; - BoundaryLayerColumns::iter it = _data.begin(); - for ( ; it != _data.end() ; ++it) { - BoundaryLayerData & d = it->second; - MAXCOLSIZE = MAXCOLSIZE > d._column.size() ? MAXCOLSIZE : d._column.size(); - MVertex * v = it->first; - double largeMeshSize = factor*sizes[v]; - blPoint_rtree *p = new blPoint_rtree(v,largeMeshSize); - double _min[3],_max[3]; - p->minmax (_min,_max); - rtree.Insert(_min,_max,p); - v2v[v] = v; - for (unsigned int k = 0 ; k < d._column.size() ; k++) - v2v[d._column[k]] = v; - } - - // go layer by layer - for (unsigned int LAYER = 0 ; LAYER < MAXCOLSIZE ; LAYER++){ - // store accepted points that will be inserted in the rtree - // afterwards - std::set<MVertex*> accepted; - it = _data.begin(); - for ( ; it != _data.end() ; ++it) { - MVertex * v = it->first; - double largeMeshSize = sizes[v]; - BoundaryLayerData & d = it->second; - // take the point if the number of layers is - // large enough - if (d._column.size() > LAYER){ - // check if the vertex in the column at position LAYER - // isn't too close to another vertex - MVertex *toCheck = d._column[LAYER]; - if (LAYER){ - double DD = toCheck->distance ( d._column[LAYER-1] ); - // do not allow to have elements that are stretched the - // other way around ! - if (DD > largeMeshSize) largeMeshSize *= 100; - largeMeshSize = std::max (largeMeshSize, DD); - } - largeMeshSize *= factor; - bool exclude = inExclusionZone_filter (toCheck,v2v,rtree); - if (!exclude){ - v2v [toCheck] = v; - blPoint_rtree *p = new blPoint_rtree(toCheck,largeMeshSize); - double _min[3],_max[3]; - p->minmax (_min,_max); - rtree.Insert(_min,_max,p); - } - else { - std::vector<MVertex*> newColumn; - for (unsigned int k = 0 ; k < LAYER ; k++) newColumn.push_back(d._column[k]); - for (unsigned int k = LAYER ; k < d._column.size() ; k++) delete d._column[k]; - d._column = newColumn; - } - } - } - } -#else - Msg::Warning ("Boundary Layer Points cannot be filtered without compiling gmsh with the rtree library"); -#endif -} #endif diff --git a/Geo/boundaryLayersData.h b/Geo/boundaryLayersData.h index ee02ed8516e7bfbdebfd1490af3e2fd075b8faa3..b626555c56dd88797c8b416fa9b6dee98f84df51 100644 --- a/Geo/boundaryLayersData.h +++ b/Geo/boundaryLayersData.h @@ -45,49 +45,6 @@ struct BoundaryLayerFan BoundaryLayerFan(MEdge e1, MEdge e2 , bool s = true) : _e1(e1),_e2(e2) , sense (s){} }; - -// wedge between 2 sets of continuous faces -struct BoundaryLayerFanWedge3d -{ - std::vector<GFace*> _gf1, _gf2; - BoundaryLayerFanWedge3d(GFace *gf1=0, GFace *gf2=0) - { - if(gf1)_gf1.push_back(gf1); - if(gf2)_gf2.push_back(gf2); - } - BoundaryLayerFanWedge3d(std::vector<GFace*> &gf1, - std::vector<GFace*> &gf2):_gf1(gf1),_gf2(gf2) - { - } - bool isLeft (const GFace *gf) const { - for (unsigned int i=0;i<_gf1.size();i++)if (_gf1[i] == gf)return true; - return false; - } - bool isRight (const GFace *gf) const{ - for (unsigned int i=0;i<_gf2.size();i++)if (_gf2[i] == gf)return true; - return false; - } - bool isLeft (const std::vector<GFace *> &gf) const { - for (unsigned int i=0;i<gf.size();i++)if (isLeft(gf[i]))return true; - return false; - } - bool isRight (const std::vector<GFace *> &gf) const { - for (unsigned int i=0;i<gf.size();i++)if (isRight(gf[i]))return true; - return false; - } - -}; - -struct BoundaryLayerFanCorner3d -{ - int _fanSize; - std::vector<GFace *> _gf; - BoundaryLayerFanCorner3d() : _fanSize(0){} - BoundaryLayerFanCorner3d(int fanSize ,std::vector<GFace *> &gf) - : _fanSize(fanSize), _gf(gf){} -}; - - struct edgeColumn { const BoundaryLayerData &_c1, &_c2; edgeColumn(const BoundaryLayerData &c1, const BoundaryLayerData &c2) @@ -111,9 +68,11 @@ struct faceColumn { class BoundaryLayerColumns { std::map<MVertex*, BoundaryLayerFan> _fans; - std::map<MVertex*, BoundaryLayerFanWedge3d> _wedges; - std::map<MVertex*, BoundaryLayerFanCorner3d> _corners; public: + // Element columns + std::map<MElement*,MElement*> _toFirst; + std::map<MElement*,std::vector<MElement*> > _elemColumns; + std::map<MFace, GFace*, Less_Face> _inverse_classification; std::multimap<MVertex*, BoundaryLayerData> _data; size_t size () const {return _data.size();} @@ -145,35 +104,15 @@ public: { _fans.insert(std::make_pair(v,BoundaryLayerFan(e1,e2,s))); } - inline void addWedge(MVertex *v, GFace *gf1, GFace *gf2) - { - _wedges.insert(std::make_pair(v,BoundaryLayerFanWedge3d(gf1,gf2))); - } - inline void addWedge(MVertex *v, std::vector<GFace *>&gf1, std::vector<GFace *> &gf2) - { - _wedges.insert(std::make_pair(v,BoundaryLayerFanWedge3d(gf1,gf2))); - } - inline void addCorner(MVertex *v, int fanSize, std::vector<GFace *> &gfs) - { - _corners.insert(std::make_pair(v,BoundaryLayerFanCorner3d(fanSize, gfs))); - } - inline bool isCorner (MVertex* v) const{ - return _corners.find(v) != _corners.end(); - } - inline bool isOnWedge (MVertex* v) const{ - return _wedges.find(v) != _wedges.end(); - } - inline BoundaryLayerFanWedge3d getWedge (MVertex* v) { - std::map<MVertex*, BoundaryLayerFanWedge3d>::iterator it = _wedges.find(v); - return it->second; - } - inline BoundaryLayerFanCorner3d getCorner (MVertex* v) { - std::map<MVertex*, BoundaryLayerFanCorner3d>::iterator it = _corners.find(v); - return it->second; + inline const BoundaryLayerFan *getFan(MVertex *v) const{ + std::map<MVertex*,BoundaryLayerFan>::const_iterator it = _fans.find(v); + if (it != _fans.end()){ + return &it->second; + } + return 0; } - const BoundaryLayerData &getColumn(MVertex *v, MFace f); inline const BoundaryLayerData &getColumn(MVertex *v, MEdge e) @@ -205,7 +144,6 @@ public: static BoundaryLayerData error; return error; } - void filterPoints(GEntity *ge, double factor); }; BoundaryLayerField* getBLField(GModel *gm); @@ -213,5 +151,4 @@ bool buildAdditionalPoints2D (GFace *gf ) ; BoundaryLayerColumns * buildAdditionalPoints3D (GRegion *gr) ; void buildMeshMetric(GFace *gf, double *uv, SMetric3 &m, double metric[3]); - #endif diff --git a/Mesh/CMakeLists.txt b/Mesh/CMakeLists.txt index bd9cde08ae46c0cac77f2bfda9dc04568c4ade96..e13f9c2100f6ba388b73f178b01af485485a0869 100644 --- a/Mesh/CMakeLists.txt +++ b/Mesh/CMakeLists.txt @@ -4,6 +4,7 @@ # bugs and problems to the public mailing list <gmsh@geuz.org>. set(SRC + filterElements.cpp Generator.cpp meshGEdge.cpp meshGEdgeExtruded.cpp diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp index 4342f40e2fd2275f865970c35132bbe5f1a5056e..ea1153ff9acb6192fae49c8be62e741531658e6d 100644 --- a/Mesh/Generator.cpp +++ b/Mesh/Generator.cpp @@ -802,7 +802,7 @@ void GenerateMesh(GModel *m, int ask) if(CTX::instance()->mesh.hoOptimize < 0){ ElasticAnalogy(GModel::current(), CTX::instance()->mesh.hoThresholdMin, false); } - else{ + else{ OptHomParameters p; p.nbLayers = CTX::instance()->mesh.hoNLayers; p.BARRIER_MIN = CTX::instance()->mesh.hoThresholdMin; diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp index b9f3e0255aa74e45490a4e05ba39ecd3e5c5ccec..b5f405bc9e88e5ef141340593a76a1a6313b3ebd 100644 --- a/Mesh/HighOrder.cpp +++ b/Mesh/HighOrder.cpp @@ -224,9 +224,30 @@ static void getEdgeVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &ve, bool reparamOK = true; if(!linear){ reparamOK = reparamMeshEdgeOnFace(v0, v1, gf, p0, p1); - if(reparamOK) - computeEquidistantParameters(gf, p0[0], p1[0], p0[1], p1[1], nPts + 2, - US, VS); + if(reparamOK) { + if (nPts >= 30)computeEquidistantParameters(gf, p0[0], p1[0], p0[1], p1[1], nPts + 2, + US, VS); + else { + US[0] = p0[0]; + VS[0] = p0[1]; + US[nPts+1] = p1[0]; + VS[nPts+1] = p1[1]; + for(int j = 0; j < nPts; j++){ + const double t = (double)(j + 1) / (nPts + 1); + SPoint3 pc = edge.interpolate(t); + SPoint2 guess = p0 * (1.-t) + p1 * t; + GPoint gp = gf->closestPoint(pc, guess); + if(gp.succeeded()){ + US[j+1] = gp.u(); + VS[j+1] = gp.v(); + } + else{ + US[j+1] = guess.x(); + VS[j+1] = guess.y(); + } + } + } + } } std::vector<MVertex*> temp; for(int j = 0; j < nPts; j++){ diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index a7e6b12dbfe002d6a394748c6dd3e2a312e12cb5..5358debc2a9b523f767dc0a723f89585105d20c7 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -44,6 +44,7 @@ #include "multiscalePartition.h" #include "meshGFaceLloyd.h" #include "boundaryLayersData.h" +#include "filterElements.h" inline double myAngle(const SVector3 &a, const SVector3 &b, const SVector3 &d) { @@ -593,46 +594,11 @@ static void addOrRemove(MVertex *v1, MVertex *v2, std::set<MEdge,Less_Edge> & be else bedges.erase(it); } -void filterOverlappingElements(int dim, std::vector<MElement*> &e, - std::vector<MElement*> &eout, - std::vector<MElement*> &einter) -{ - eout.clear(); - MElementOctree octree (e); - for (unsigned int i = 0; i < e.size(); ++i){ - MElement *el = e[i]; - bool intersection = false; - for (int j=0;j<el->getNumVertices();++j){ - MVertex *v = el->getVertex(j); - std::vector<MElement *> inters = octree.findAll(v->x(), v->y(), v->z(), dim); - std::vector<MElement *> inters2; - for (unsigned int k = 0; k < inters.size(); k++){ - bool found = false; - for (int l = 0; l < inters[k]->getNumVertices(); l++){ - if (inters[k]->getVertex(l) == v)found = true; - } - if (!found)inters2.push_back(inters[k]); - } - if (inters2.size() >= 1 ){ - intersection = true; - } - } - if (intersection){ - // printf("intersection found\n"); - einter.push_back(el); - } - else { - eout.push_back(el); - } - } -} - void modifyInitialMeshForTakingIntoAccountBoundaryLayers(GFace *gf) { if (!buildAdditionalPoints2D (gf))return; BoundaryLayerColumns* _columns = gf->getColumns(); - std::set<MEdge,Less_Edge> bedges; std::vector<MQuadrangle*> blQuads; @@ -650,8 +616,8 @@ void modifyInitialMeshForTakingIntoAccountBoundaryLayers(GFace *gf) MVertex *v2 = (*ite)->lines[i]->getVertex(1); MEdge dv(v1,v2); addOrRemove(v1,v2,bedges); - for (unsigned int SIDE = 0 ; SIDE < _columns->_normals.count(dv); SIDE ++){ + std::vector<MElement*> myCol; edgeColumn ec = _columns->getColumns(v1, v2, SIDE); const BoundaryLayerData & c1 = ec._c1; const BoundaryLayerData & c2 = ec._c2; @@ -672,7 +638,10 @@ void modifyInitialMeshForTakingIntoAccountBoundaryLayers(GFace *gf) //avoid convergent errors if (dv2.length() < 0.03 * dv.length())break; - blQuads.push_back(new MQuadrangle(v11,v21,v22,v12)); + MQuadrangle *qq = new MQuadrangle(v11,v21,v22,v12); + myCol.push_back(qq); + qq->setPartition(l); + blQuads.push_back(qq); fprintf(ff2,"SQ (%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g){1,1,1,1};\n", v11->x(),v11->y(),v11->z(), v12->x(),v12->y(),v12->z(), @@ -680,7 +649,8 @@ void modifyInitialMeshForTakingIntoAccountBoundaryLayers(GFace *gf) v21->x(),v21->y(),v21->z()); } // int M = std::max(c1._column.size(),c2._column.size()); - + for (unsigned int l=0;l<myCol.size();l++)_columns->_toFirst[myCol[l]] = myCol[0]; + _columns->_elemColumns[myCol[0]] = myCol; } } ++ite; @@ -692,6 +662,7 @@ void modifyInitialMeshForTakingIntoAccountBoundaryLayers(GFace *gf) MVertex *v = itf->first; int nbCol = _columns->getNbColumns(v); + std::vector<MElement*> myCol; for (int i=0;i<nbCol-1;i++){ const BoundaryLayerData & c1 = _columns->getColumn(v,i); const BoundaryLayerData & c2 = _columns->getColumn(v,i+1); @@ -709,7 +680,10 @@ void modifyInitialMeshForTakingIntoAccountBoundaryLayers(GFace *gf) v12 = c2._column[l-1]; } if (v11 != v12){ - blQuads.push_back(new MQuadrangle(v11,v12,v22,v21)); + MQuadrangle *qq = new MQuadrangle(v11,v12,v22,v21); + myCol.push_back(qq); + qq->setPartition(l); + blQuads.push_back(qq); fprintf(ff2,"SQ (%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g){1,1,1,1};\n", v11->x(),v11->y(),v11->z(), v12->x(),v12->y(),v12->z(), @@ -717,7 +691,10 @@ void modifyInitialMeshForTakingIntoAccountBoundaryLayers(GFace *gf) v21->x(),v21->y(),v21->z()); } else { - blTris.push_back(new MTriangle(v,v22,v21)); + MTriangle *qq = new MTriangle(v,v22,v21); + myCol.push_back(qq); + qq->setPartition(l); + blTris.push_back(qq); fprintf(ff2,"ST (%g,%g,%g,%g,%g,%g,%g,%g,%g){1,1,1,1};\n", v->x(),v->y(),v->z(), v22->x(),v22->y(),v22->z(), @@ -725,19 +702,16 @@ void modifyInitialMeshForTakingIntoAccountBoundaryLayers(GFace *gf) } } } + for (unsigned int l=0;l<myCol.size();l++)_columns->_toFirst[myCol[l]] = myCol[0]; + _columns->_elemColumns[myCol[0]] = myCol; } } fprintf(ff2,"};\n"); fclose(ff2); - std::vector<MElement*> els,newels,oldels; - for (unsigned int i = 0; i < blQuads.size();i++) els.push_back(blQuads[i]); - filterOverlappingElements (2,els,newels,oldels); - blQuads.clear(); - for (unsigned int i = 0; i < newels.size(); i++) - blQuads.push_back((MQuadrangle*)newels[i]); - for (unsigned int i = 0; i < oldels.size(); i++) delete oldels[i]; + + filterOverlappingElements (blTris,blQuads,_columns->_elemColumns,_columns->_toFirst); for (unsigned int i = 0; i < blQuads.size();i++){ addOrRemove(blQuads[i]->getVertex(0),blQuads[i]->getVertex(1),bedges); diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp index e22a13eb84b1f7a13e05b6bbe48415965747cd74..f09154f43a79ca413c77a7f8272c75a7cd541f6e 100644 --- a/Mesh/meshGFaceDelaunayInsertion.cpp +++ b/Mesh/meshGFaceDelaunayInsertion.cpp @@ -1054,7 +1054,7 @@ void bowyerWatson(GFace *gf, int MAXPNT, } #endif transferDataStructure(gf, AllTris, DATA); - removeThreeTrianglesNodes(gf); + // removeThreeTrianglesNodes(gf); } /* @@ -1332,14 +1332,18 @@ void bowyerWatsonFrontal(GFace *gf, */ } - // char name[245]; - // sprintf(name,"frontal%d-real.pos", gf->tag()); - // _printTris (name, AllTris, Us, Vs,false); - // sprintf(name,"frontal%d-param.pos", gf->tag()); - // _printTris (name, AllTris, Us, Vs,true); + nbSwaps = edgeSwapPass(gf, AllTris, SWCR_QUAL, DATA); + /* + char name[245]; + sprintf(name,"frontal%d-real.pos", gf->tag()); + _printTris (name, AllTris.begin(), AllTris.end(), DATA,false); + sprintf(name,"frontal%d-param.pos", gf->tag()); + _printTris (name, AllTris.begin(), AllTris.end(), DATA,true); + */ transferDataStructure(gf, AllTris, DATA); - removeThreeTrianglesNodes(gf); + // removeThreeTrianglesNodes(gf); + // in case of boundary layer meshing #if defined(HAVE_ANN) { diff --git a/Mesh/meshGFaceDelaunayInsertion.h b/Mesh/meshGFaceDelaunayInsertion.h index bdb26f58899d15256e2fc0d8ca570b3634c95971..45e5e7073fd82452107fc95375b1294a9a34d30b 100644 --- a/Mesh/meshGFaceDelaunayInsertion.h +++ b/Mesh/meshGFaceDelaunayInsertion.h @@ -10,6 +10,7 @@ #include "MQuadrangle.h" #include "STensor3.h" #include "GEntity.h" +#include "MFace.h" #include <list> #include <set> #include <map> @@ -127,7 +128,8 @@ class compareTri3Ptr { if(a->getRadius() > b->getRadius()) return true; if(a->getRadius() < b->getRadius()) return false; - return a<b; + Less_Face lf; + return lf(a->tri()->getFace(0), b->tri()->getFace(0)); } }; @@ -159,11 +161,12 @@ struct edgeXface { v[0] = t1->tri()->getVertex(iFac == 0 ? 2 : iFac-1); v[1] = t1->tri()->getVertex(iFac); - if(v[0]->getNum() > v[1]->getNum()){ - MVertex *tmp = v[0]; - v[0] = v[1]; - v[1] = tmp; - } + if (v[0]->getNum() > v[1]->getNum()) + { + MVertex *tmp = v[0]; + v[0] = v[1]; + v[1] = tmp; + } } inline bool operator < ( const edgeXface &other) const { @@ -174,8 +177,7 @@ struct edgeXface } inline bool operator == ( const edgeXface &other) const { - if(v[0]->getNum() == other.v[0]->getNum() && - v[1]->getNum() == other.v[1]->getNum()) return true; + if(v[0]->getNum() == other.v[0]->getNum() && v[1]->getNum() == other.v[1]->getNum()) return true; return false; } }; diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp index 796873e3d7c0529f402018745bb57b942867cbd4..b61d1e3cc7ab8ca287783fb887601f7f3b1e0aa6 100644 --- a/Mesh/meshGRegion.cpp +++ b/Mesh/meshGRegion.cpp @@ -33,6 +33,7 @@ #include "Levy3D.h" #include "directions3D.h" #include "discreteFace.h" +#include "filterElements.h" #if defined(HAVE_ANN) #include "ANN/ANN.h" @@ -667,6 +668,108 @@ bool AssociateElementsToModelRegionWithBoundaryLayers (GRegion *gr, } +static int getWedge (BoundaryLayerColumns* _columns, MVertex *v1, MVertex *v2, + int indicesVert1 [], int indicesVert2 []) +{ + int N1 = _columns->getNbColumns(v1) ; + int N2 = _columns->getNbColumns(v2) ; + int fanSize = 4; + int NW1 = 0; + int NW2 = 0; + for (int i=0;i<N1;i++){ + const BoundaryLayerData & c1 = _columns->getColumn(v1,i); + if (c1._joint.size())NW1++; + } + for (int i=0;i<N2;i++){ + const BoundaryLayerData & c2 = _columns->getColumn(v2,i); + if (c2._joint.size())NW2++; + } + + + + + std::map<int,int> one2two; + for (int i=0;i<NW1;i++){ + const BoundaryLayerData & c1 = _columns->getColumn(v1,i); + for (int j=0;j<NW2;j++){ + const BoundaryLayerData & c2 = _columns->getColumn(v2,j); + for (unsigned int k=0;k<c2._joint.size();k++){ + if (std::find(c1._joint.begin(),c1._joint.end(),c2._joint[k]) != + c1._joint.end()) { + one2two[i] = j; + } + } + } + } + + // printf("%d %d %d %d \n",N1,N2,NW1,NW2); + // for (std::map<int,int>::iterator it = one2two.begin(); it != one2two.end(); it++){ + // printf("one2two[%d] = %d\n",it->first,it->second); + // } + if (one2two.size() != 2)return 0; + + int vert1Start,vert1End; + int vert2Start,vert2End; + std::map<int,int>::iterator it = one2two.begin(); + vert1Start = it->first; + vert2Start = it->second; + ++it; + vert1End = it->first; + vert2End = it->second; + + + int INDEX1, count = 0; + for (int i=0;i<NW1;i++){ + for (int j=i+1;j<NW1;j++){ + if ((vert1Start == i && vert1End == j) || + (vert1Start == j && vert1End == i)) + { + INDEX1 = count; + } + count++; + } + } + int INDEX2; + count = 0; + for (int i=0;i<NW2;i++){ + for (int j=i+1;j<NW2;j++){ + if ((vert2Start == i && vert2End == j) || + (vert2Start == i && vert2End == j)) + { + INDEX2 = count; + } + count++; + } + } + + int indexVert1Start = NW1 + fanSize * ( 0 + INDEX1); + int indexVert1End = NW1 + fanSize * ( 1 + INDEX1); + + int indexVert2Start = NW2 + fanSize * ( 0 + INDEX2); + int indexVert2End = NW2 + fanSize * ( 1 + INDEX2); + + indicesVert1[0] = vert1Start; + int k=1; + for (int i=indexVert1Start;i< indexVert1End;++i)indicesVert1[k++] = i; + indicesVert1[fanSize+1] = vert1End; + + indicesVert2[0] = vert2Start; + k = 1; + if (indexVert2End > indexVert2Start){ + for (int i=indexVert2Start;i< indexVert2End;++i)indicesVert2[k++] = i; + } + else { + for (int i=indexVert2Start-1;i<= indexVert2End;--i)indicesVert2[k++] = i; + } + indicesVert2[fanSize+1] = vert2End; + + + // printf("%d %d %d %d %d %d %d %d\n",vert1Start,vert1End,vert2Start,vert2End,indexVert1Start,indexVert1End,indexVert2Start,indexVert2End); + // return 0; + + return fanSize + 2; +} + static bool modifyInitialMeshForTakingIntoAccountBoundaryLayers(GRegion *gr) { if (getBLField(gr->model())) insertVerticesInRegion(gr,-1); @@ -681,8 +784,6 @@ static bool modifyInitialMeshForTakingIntoAccountBoundaryLayers(GRegion *gr) std::list<GFace*> embedded_faces = gr->embeddedFaces(); faces.insert(faces.begin(), embedded_faces.begin(),embedded_faces.end()); - FILE *ff2 = fopen ("tato3D.pos","w"); - fprintf(ff2,"View \" \"{\n"); std::set<MVertex*> verts; std::list<GFace*>::iterator itf = faces.begin(); @@ -700,6 +801,7 @@ static bool modifyInitialMeshForTakingIntoAccountBoundaryLayers(GRegion *gr) const BoundaryLayerData & c3 = fc._c3; int N = std::min(c1._column.size(),std::min(c2._column.size(),c3._column.size())); // printf("%d Layers\n",N); + std::vector<MElement*> myCol; for (int l=0;l < N ;++l){ MVertex *v11,*v12,*v13,*v21,*v22,*v23; v21 = c1._column[l]; @@ -716,15 +818,15 @@ static bool modifyInitialMeshForTakingIntoAccountBoundaryLayers(GRegion *gr) v13 = c3._column[l-1]; } // printf("coucoucouc %p %p %p %p %p %p\n",v11,v12,v13,v21,v22,v23); - blPrisms.push_back(new MPrism(v11,v12,v13,v21,v22,v23)); - fprintf(ff2,"SI (%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g){1,1,1,1,1,1};\n", - v11->x(),v11->y(),v11->z(), - v12->x(),v12->y(),v12->z(), - v13->x(),v13->y(),v13->z(), - v21->x(),v21->y(),v21->z(), - v22->x(),v22->y(),v22->z(), - v23->x(),v23->y(),v23->z()); - // printf("done %d\n",l); + MPrism *prism = new MPrism(v11,v12,v13,v21,v22,v23); + // store the layer the element belongs + prism->setPartition(l+1); + blPrisms.push_back(prism); + myCol.push_back(prism); + } + if (!myCol.empty()){ + for (unsigned int l=0;l<myCol.size();l++)_columns->_toFirst[myCol[l]] = myCol[0]; + _columns->_elemColumns[myCol[0]] = myCol; } } } @@ -748,167 +850,77 @@ static bool modifyInitialMeshForTakingIntoAccountBoundaryLayers(GRegion *gr) MEdge e = *ite; MVertex *v1 = e.getVertex(0); MVertex *v2 = e.getVertex(1); - bool onWedge1 = _columns->isOnWedge(v1); - bool onWedge2 = _columns->isOnWedge(v2); - bool onCorner1 = _columns->isCorner(v1); - bool onCorner2 = _columns->isCorner(v2); - if ((onWedge1 || onCorner1) && (onWedge2 || onCorner2)){ - int N1=0,N2=0; - std::vector<GFace *>gfs1,gfs2; - BoundaryLayerFanWedge3d w1,w2; - BoundaryLayerFanCorner3d c1,c2; - if (onWedge1) { - N1 = _columns->getNbColumns(v1); - w1 = _columns->getWedge(v1); - gfs1 = w1._gf1; - gfs2 = w1._gf2; - } - else { - c1 = _columns->getCorner(v1); - N1 = c1._fanSize; - } - if (onWedge2) { - N2 = _columns->getNbColumns(v2); - w2 = _columns->getWedge(v2); - gfs1 = w2._gf1; - gfs2 = w2._gf2; - } - else { - c2 = _columns->getCorner(v2); - N2 = c2._fanSize; - } - - // have to go from gf1 to gf2 to be aware of the sense!!! - if (N1 == N2){ - for (int i = 0; i < N1 - 1; i++){ - - unsigned int i11=i, i12=i+1, i21=i,i22=i+1; - - if (onWedge1){ - // if (w1.isLeft(gfs1)){i11=i;i12=i+1;} - // else if (w1.isRight(gfs1)){i11=N1-1-i;i12=N1-2-i;} - // printf("%d %d %d\n",w1.isLeft(gfs1),gfs1[0] == w1._gf1[0],gfs1.size()); - // printf("%d %d %d\n",w1.isRight(gfs1),gfs1[0] == w1._gf2[0],gfs1.size()); - if (gfs1[0] == w1._gf1[0]){i11=i;i12=i+1;} - else if (gfs1[0] == w1._gf2[0]){i11=N1-1-i;i12=N1-2-i;} - } - else { - /* - - - - | 0 --> column 0 - | - | fan with N1 columns - gf.size | - ---------- + ---------- 1 --> column N1-1 - | - | - | - | 2 --> column 2*(N1-1) - - 0 1 2 3 --> 0 -> 4-1 - 3 4 5 6 --> 4-1 -> 2 (4-1) - 6 7 8 0 - - 1 --> 0 ==> - - */ - int K1 = -1, K2 = -1; - for (unsigned int s=0;s < c1._gf.size();s++){ - if (w2.isLeft(c1._gf[s]))K1 = s; - if (w2.isRight(c1._gf[s]))K2 = s; - } - if (K1==-1) Msg::Error("K1 = -1"); - if (K2==-1) Msg::Error("K2 = -1"); - if (K1+1==K2){ i11=K1*(N1-1)+i;i12=i11+1; } - else if (K2+1 == K1){ i11=K1*(N1-1)-i;i12=i11-1; } - else if (K2 == 0 && K1 == (int)c1._gf.size() - 1){ i11=K1*(N1-1)+i;i12=i11+1; } - else if (K1 == 0 && K2 == (int)c1._gf.size() - 1){ i11=(K2+1)*(N1-1)-i;i12=i11-1; } - else Msg::Error("KROUPOUK 1 %d %d !", K1, K2); - if (i12 == (c1._gf.size()) * (N1-1))i12=0; - if (i11 == (c1._gf.size()) * (N1-1))i11=0; - } - if (onWedge2){ - if (w2.isLeft(gfs1)){ i21=i;i22=i+1; } - else if (w2.isRight(gfs1)){ i21=N1-1-i;i22=N1-2-i; } - } - else { - int K1 = -1, K2 = -1; - for (unsigned int s=0;s<c2._gf.size();s++){ - if (w1.isLeft(c2._gf[s]))K1 = s; - if (w1.isRight(c2._gf[s]))K2 = s; - } - if (K1+1 == K2){ i21=K1*(N1-1)+i;i22=i21+1; } - else if (K2+1 == K1){ i21=K1*(N1-1)-i;i22=i21-1; } - else if (K2 == 0 && K1 == (int)c2._gf.size()-1 ){ i21=K1*(N1-1)+i;i22=i21+1; } - else if (K1 == 0 && K2 == (int)c2._gf.size()-1){ i21=(K2+1)*(N1-1)-i;i22=i21-1; } - else Msg::Error("KROUPOUK 2 %d %d !",K1,K2); - if (i22 == (c2._gf.size()) * (N1-1))i22=0; - if (i21 == (c2._gf.size()) * (N1-1))i21=0; - } - - BoundaryLayerData c11 = _columns->getColumn(v1,i11); - BoundaryLayerData c12 = _columns->getColumn(v1,i12); - BoundaryLayerData c21 = _columns->getColumn(v2,i21); - BoundaryLayerData c22 = _columns->getColumn(v2,i22); - int N = std::min(c11._column.size(), - std::min(c12._column.size(), - std::min(c21._column.size(), c22._column.size()))); - for (int l=0;l < N ;++l){ - MVertex *v11,*v12,*v13,*v14; - MVertex *v21,*v22,*v23,*v24; - v21 = c11._column[l]; - v22 = c12._column[l]; - v23 = c22._column[l]; - v24 = c21._column[l]; - if (l == 0){ - v11 = v12 = v1; - v13 = v14 = v2; - } - else { - v11 = c11._column[l-1]; - v12 = c12._column[l-1]; - v13 = c22._column[l-1]; - v14 = c21._column[l-1]; - } - - if (l == 0){ - blPrisms.push_back(new MPrism(v12,v21,v22,v13,v24,v23)); - fprintf(ff2,"SI (%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g){3,3,3,3,3,3};\n", - v12->x(),v12->y(),v12->z(), - v21->x(),v21->y(),v21->z(), - v22->x(),v22->y(),v22->z(), - v13->x(),v13->y(),v13->z(), - v24->x(),v24->y(),v24->z(), - v23->x(),v23->y(),v23->z()); - } - else { - blHexes.push_back(new MHexahedron(v11,v12,v13,v14,v21,v22,v23,v24)); - fprintf(ff2,"SH (%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g){2,2,2,2,2,2,2,2};\n", - v11->x(),v11->y(),v11->z(), - v12->x(),v12->y(),v12->z(), - v13->x(),v13->y(),v13->z(), - v14->x(),v14->y(),v14->z(), - v21->x(),v21->y(),v21->z(), - v22->x(),v22->y(),v22->z(), - v23->x(),v23->y(),v23->z(), - v24->x(),v24->y(),v24->z()); - } - } + int indices1[256]; + int indices2[256]; + int NbW = getWedge (_columns, v1, v2, indices1,indices2); + for (int i=0;i<NbW-1;i++){ + int i11 = indices1[i]; + int i12 = indices1[i+1]; + int i21 = indices2[i]; + int i22 = indices2[i+1]; + BoundaryLayerData c11 = _columns->getColumn(v1,i11); + BoundaryLayerData c12 = _columns->getColumn(v1,i12); + BoundaryLayerData c21 = _columns->getColumn(v2,i21); + BoundaryLayerData c22 = _columns->getColumn(v2,i22); + int N = std::min(c11._column.size(), + std::min(c12._column.size(), + std::min(c21._column.size(), c22._column.size()))); + std::vector<MElement*> myCol; + for (int l=0;l < N ;++l){ + MVertex *v11,*v12,*v13,*v14; + MVertex *v21,*v22,*v23,*v24; + v21 = c11._column[l]; + v22 = c12._column[l]; + v23 = c22._column[l]; + v24 = c21._column[l]; + if (l == 0){ + v11 = v12 = v1; + v13 = v14 = v2; + } + else { + v11 = c11._column[l-1]; + v12 = c12._column[l-1]; + v13 = c22._column[l-1]; + v14 = c21._column[l-1]; + } + + if (l == 0){ + MPrism *prism = new MPrism(v12,v21,v22,v13,v24,v23); + // store the layer the element belongs + prism->setPartition(l+1); + myCol.push_back(prism); + + blPrisms.push_back(prism); + } + else { + MHexahedron *hex = new MHexahedron(v11,v12,v13,v14,v21,v22,v23,v24); + // store the layer the element belongs + myCol.push_back(hex); + hex->setPartition(l+1); + blHexes.push_back(hex); } } - else{ - Msg::Error("cannot create 3D BL FAN %d %d -- %d %d %d %d", - N1,N2,onWedge1,onWedge1,onCorner1,onCorner2); + if (!myCol.empty()){ + for (unsigned int l=0;l<myCol.size();l++)_columns->_toFirst[myCol[l]] = myCol[0]; + _columns->_elemColumns[myCol[0]] = myCol; } } ++ite; } - fprintf(ff2,"};\n"); - fclose(ff2); - + filterOverlappingElements (blPrisms,blHexes,_columns->_elemColumns,_columns->_toFirst); + { + FILE *ff2 = fopen ("tato3D.pos","w"); + fprintf(ff2,"View \" \"{\n"); + for (unsigned int i = 0; i < blPrisms.size();i++){ + blPrisms[i]->writePOS(ff2,1,0,0,0,0,0); + } + for (unsigned int i = 0; i < blHexes.size();i++){ + blHexes[i]->writePOS(ff2,1,0,0,0,0,0); + } + fprintf(ff2,"};\n"); + fclose(ff2); + } for (unsigned int i = 0; i < blPrisms.size();i++){ for (unsigned int j=0;j<5;j++) diff --git a/Numeric/CMakeLists.txt b/Numeric/CMakeLists.txt index e4f78f93a1e821ce0e1759873d97a2fd7e39abf0..6e726cf0997a1b3f5d4627f56e4f117a971ba7d7 100644 --- a/Numeric/CMakeLists.txt +++ b/Numeric/CMakeLists.txt @@ -27,6 +27,7 @@ set(SRC GaussQuadraturePyr.cpp GaussLegendreSimplex.cpp GaussJacobi1D.cpp + geodesics.cpp robustPredicates.cpp mathEvaluator.cpp Iso.cpp diff --git a/benchmarks/2d/Square-02.geo b/benchmarks/2d/Square-02.geo index 70c16d58ad5b2437d44faef176bdefb25e685eaa..b2612898bd2e83282c9fa358ca3ca28626c1817d 100644 --- a/benchmarks/2d/Square-02.geo +++ b/benchmarks/2d/Square-02.geo @@ -13,4 +13,4 @@ Line(3) = {1,4}; Line(4) = {4,3}; Line Loop(5) = {1,2,3,4}; Plane Surface(6) = {5}; -Recombine Surface {6}; +//Recombine Surface {6}; diff --git a/benchmarks/2d/square.geo b/benchmarks/2d/square.geo index 6c186bf2f90bf7915d17de352e0192800338b7fb..f3050fb2548065f88789884592b0ed4ba884daa7 100644 --- a/benchmarks/2d/square.geo +++ b/benchmarks/2d/square.geo @@ -1,4 +1,4 @@ -lc=1; +lc=1000; Point(1) = {0, 0, 0,lc*.1}; Point(2) = {0, 10, 0,lc}; Point(3) = {10, 10, 0,lc}; @@ -11,6 +11,9 @@ Line(4) = {1, 2}; Line Loop(5) = {1, 2, 3, 4}; Plane Surface(10) = {5}; +Physical Line("wall")={1,2,3,4}; +Physical Surface("air")={10}; + //---------------------- //Compound Line(10)={1,2,3,4}; @@ -24,4 +27,4 @@ Plane Surface(10) = {5}; -Recombine Surface {10}; +//Recombine Surface {10};