diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 2eee730c2d49c200a8a688a3a3399bfd2b08b296..668339951a849db79ad90043750a1314661beb1b 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -23,6 +23,9 @@ #include "discreteFace.h" #include "discreteEdge.h" #include "discreteVertex.h" +#include "boundaryLayerFace.h" +#include "boundaryLayerEdge.h" +#include "boundaryLayerVertex.h" #include "gmshSurface.h" #include "SmoothData.h" #include "Context.h" @@ -1004,7 +1007,7 @@ void GModel::checkMeshCoherence(double tolerance) for(unsigned int i = 0; i < entities.size(); i++) vertices.insert(vertices.end(), entities[i]->mesh_vertices.begin(), entities[i]->mesh_vertices.end()); - MVertexPositionSet pos(vertices, std::min((int)vertices.size(), 10)); + MVertexPositionSet pos(vertices); for(unsigned int i = 0; i < vertices.size(); i++) pos.find(vertices[i]->x(), vertices[i]->y(), vertices[i]->z(), eps); int num = 0; @@ -1026,7 +1029,7 @@ void GModel::checkMeshCoherence(double tolerance) SPoint3 p = entities[i]->getMeshElement(j)->barycenter(); vertices.push_back(new MVertex(p.x(), p.y(), p.z())); } - MVertexPositionSet pos(vertices, std::min((int)vertices.size(), 10)); + MVertexPositionSet pos(vertices); for(unsigned int i = 0; i < vertices.size(); i++) pos.find(vertices[i]->x(), vertices[i]->y(), vertices[i]->z(), eps); int num = 0; @@ -1061,7 +1064,7 @@ int GModel::removeDuplicateMeshVertices(double tolerance) MVertex *v = entities[i]->mesh_vertices[j]; vertices.push_back(new MVertex(v->x(), v->y(), v->z())); } - MVertexPositionSet pos(vertices, std::min((int)vertices.size(), 10)); + MVertexPositionSet pos(vertices); for(unsigned int i = 0; i < vertices.size(); i++) pos.find(vertices[i]->x(), vertices[i]->y(), vertices[i]->z(), eps); int num = 0; @@ -1638,6 +1641,49 @@ GEntity *GModel::extrude(GEntity *e, std::vector<double> p1, std::vector<double> return 0; } +void GModel::createBoundaryLayer(std::vector<GEntity *> e, double h) +{ +#if defined(HAVE_MESH) + // FIXME remove this! + Field *f = _fields->newField(0, "MathEval"); + char s[128]; + sprintf(s, "%g", h); + f->options["F"]->string() = s; + + GModel *gm = this; + for(unsigned int i = 0; i < e.size(); i++){ + if(e[i]->dim() == 1){ + GEdge *ge = static_cast<GEdge*>(e[i]); + GVertex *beg = ge->getBeginVertex(); + GVertex *end = ge->getEndVertex(); + GVertex *v0 = new boundaryLayerVertex(gm, gm->getMaxElementaryNumber(0) + 1, beg); + gm->add(v0); + GVertex *v1 = new boundaryLayerVertex(gm, gm->getMaxElementaryNumber(0) + 1, end); + gm->add(v1); + GEdge *e0 = new boundaryLayerEdge(gm, gm->getMaxElementaryNumber(1) + 1, v0, v1, ge); + gm->add(e0); + GEdge *e1 = new boundaryLayerEdge(gm, gm->getMaxElementaryNumber(1) + 1, beg, v0, beg); + gm->add(e1); + GEdge *e2 = new boundaryLayerEdge(gm, gm->getMaxElementaryNumber(1) + 1, end, v1, end); + gm->add(e2); + boundaryLayerFace *f0 = new boundaryLayerFace(gm, gm->getMaxElementaryNumber(2) + 1, e, f, ge); + std::vector<int> boundEdges; + boundEdges.push_back(ge->tag()); + boundEdges.push_back(e0->tag()); + boundEdges.push_back(e1->tag()); + boundEdges.push_back(e2->tag()); + f0->setBoundEdges(boundEdges); + gm->add(f0); + } + else{ + Msg::Error("FIXME: GModel boundary layer creation only for edges for now"); + } + } + + glue(CTX::instance()->geom.tolerance); +#endif +} + GEntity *GModel::addPipe(GEntity *e, std::vector<GEdge *> edges){ if(_factory) return _factory->addPipe(this,e,edges); @@ -1703,8 +1749,9 @@ static void computeDuplicates(GModel *model, std::map<GVertex*, GVertex*> &Duplicates2Unique, const double &eps) { - // currently we use a greedy algorithm in n^2 (using bounding boxes - // and the Octree would certainly be better for huge models...) + // FIXME: currently we use a greedy algorithm in n^2 (using a + // kd-tree: cf. MVertexPositionSet) + // FIXME: add option to remove orphaned entities after duplicate check std::list<GVertex*> v; v.insert(v.begin(), model->firstVertex(), model->lastVertex()); @@ -1712,13 +1759,13 @@ static void computeDuplicates(GModel *model, GVertex *pv = *v.begin(); v.erase(v.begin()); bool found = false; - for ( std::multimap<GVertex*,GVertex*>::iterator it = Unique2Duplicates.begin(); - it != Unique2Duplicates.end(); ++it ){ + for (std::multimap<GVertex*,GVertex*>::iterator it = Unique2Duplicates.begin(); + it != Unique2Duplicates.end(); ++it){ GVertex *unique = it->first; const double d = sqrt((unique->x() - pv->x()) * (unique->x() - pv->x()) + (unique->y() - pv->y()) * (unique->y() - pv->y()) + (unique->z() - pv->z()) * (unique->z() - pv->z())); - if (d <= eps) { + if (d <= eps && pv->geomType() == unique->geomType()) { found = true; Unique2Duplicates.insert(std::make_pair(unique, pv)); Duplicates2Unique[pv] = unique; @@ -1760,25 +1807,30 @@ static void computeDuplicates(GModel *model, while(!e.empty()){ GEdge *pe = *e.begin(); - // compute a point - Range<double> r = pe->parBounds(0); - GPoint gp = pe->point(0.5 * (r.low() + r.high())); e.erase(e.begin()); bool found = false; for (std::multimap<GEdge*,GEdge*>::iterator it = Unique2Duplicates.begin(); it != Unique2Duplicates.end(); ++it ){ GEdge *unique = it->first; // first check edges that have same endpoints - if ((unique->getBeginVertex() == pe->getBeginVertex() && - unique->getEndVertex() == pe->getEndVertex()) || - (unique->getEndVertex() == pe->getBeginVertex() && - unique->getBeginVertex() == pe->getEndVertex())){ - if (unique->geomType() == GEntity::Line && pe->geomType() == GEntity::Line){ + if (((unique->getBeginVertex() == pe->getBeginVertex() && + unique->getEndVertex() == pe->getEndVertex()) || + (unique->getEndVertex() == pe->getBeginVertex() && + unique->getBeginVertex() == pe->getEndVertex())) && + unique->geomType() == pe->geomType()){ + if ((unique->geomType() == GEntity::Line && pe->geomType() == GEntity::Line) || + unique->geomType() == GEntity::DiscreteCurve || + pe->geomType() == GEntity::DiscreteCurve || + unique->geomType() == GEntity::BoundaryLayerCurve || + pe->geomType() == GEntity::BoundaryLayerCurve){ found = true; Unique2Duplicates.insert(std::make_pair(unique,pe)); Duplicates2Unique[pe] = unique; break; } + // compute a point + Range<double> r = pe->parBounds(0); + GPoint gp = pe->point(0.5 * (r.low() + r.high())); double t; GPoint gp2 = pe->closestPoint(SPoint3(gp.x(),gp.y(),gp.z()),t); const double d = sqrt((gp.x() - gp2.x()) * (gp.x() - gp2.x()) + @@ -1832,11 +1884,8 @@ static void computeDuplicates(GModel *model, while(!f.empty()){ GFace *pf = *f.begin(); - // compute a point Range<double> r = pf->parBounds(0); Range<double> s = pf->parBounds(1); - // FIXME : this is WRONG (the point can be in a hole ;-) - GPoint gp = pf->point(SPoint2(0.5 * (r.low() + r.high()), 0.5 * (s.low() + s.high()))); f.erase(f.begin()); std::list<GEdge*> pf_edges = pf->edges(); pf_edges.sort(); @@ -1845,7 +1894,8 @@ static void computeDuplicates(GModel *model, it != Unique2Duplicates.end(); ++it){ GFace *unique = it->first; std::list<GEdge*> unique_edges = unique->edges(); - if (unique_edges.size() == pf_edges.size()){ + if (pf->geomType() == unique->geomType() && + unique_edges.size() == pf_edges.size()){ unique_edges.sort(); std::list<GEdge*>::iterator it_pf = pf_edges.begin(); std::list<GEdge*>::iterator it_unique = unique_edges.begin(); @@ -1862,11 +1912,8 @@ static void computeDuplicates(GModel *model, break; } double t[2]={0,0}; - const double d = 1.0; - /*sqrt((gp.x()-gp2.x())*(gp.x()-gp2.x())+ - (gp.y()-gp2.y())*(gp.y()-gp2.y())+ - (gp.z()-gp2.z())*(gp.z()-gp2.z()));*/ - // printf ("closest point @ distance %g\n",d); + // FIXME: evaluate a point on the surface (use e.g. buildRepresentationCross) + const double d = 1.0; if (t[0] >= r.low() && t[0] <= r.high() && t[1] >= s.low() && t[1] <= s.high() && d <= eps) { found = true; @@ -2089,4 +2136,9 @@ void GModel::registerBindings(binding *b) "dimension and number. If number=0, the first free number " "is chosen. Returns the number."); cm->setArgNames("physicalName","dim","number",NULL); + + cm = cb->addMethod("createBoundaryLayer", &GModel::createBoundaryLayer); + cm->setDescription("create a boundary layer using a given field for the " + "extrusion height."); + cm->setArgNames("{list of entities}","height",NULL); } diff --git a/Geo/GModelIO_Mesh.cpp b/Geo/GModelIO_Mesh.cpp index 0ae1de21ba56dc5bfa7e323b93593aa36346ce7f..a23f1a131a79e89f264666a5a75640aa508175af 100644 --- a/Geo/GModelIO_Mesh.cpp +++ b/Geo/GModelIO_Mesh.cpp @@ -861,8 +861,8 @@ int GModel::writePartitionedMSH(const std::string &baseName, bool binary, int GModel::writePOS(const std::string &name, bool printElementary, bool printElementNumber, bool printGamma, bool printEta, - bool printRho, bool printDisto, bool saveAll, - double scalingFactor) + bool printRho, bool printDisto, + bool saveAll, double scalingFactor) { FILE *fp = fopen(name.c_str(), "w"); if(!fp){ @@ -870,6 +870,23 @@ int GModel::writePOS(const std::string &name, bool printElementary, return 0; } + /* + bool printVertices = true; + if(printVertices){ + fprintf(fp, "View \"Vertices\" {\n"); + std::vector<GEntity*> entities; + getEntities(entities); + for(unsigned int i = 0; i < entities.size(); i++) + for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){ + MVertex *v = entities[i]->mesh_vertices[j]; + fprintf(fp, "SP(%g,%g,%g){1};\n", v->x(), v->y(), v->z()); + } + fprintf(fp, "};\n"); + fclose(fp); + return 1; + } + */ + bool f[6] = {printElementary, printElementNumber, printGamma, printEta, printRho, printDisto}; @@ -1045,7 +1062,7 @@ int GModel::readSTL(const std::string &name, double tolerance) for(unsigned int j = 0; j < points[i].size(); j++) vertices.push_back(new MVertex(points[i][j].x(), points[i][j].y(), points[i][j].z())); - MVertexPositionSet pos(vertices, std::min((int)vertices.size(),10)); + MVertexPositionSet pos(vertices); for(unsigned int i = 0; i < points.size(); i ++){ for(unsigned int j = 0; j < points[i].size(); j += 3){ diff --git a/Geo/MVertexPositionSet.h b/Geo/MVertexPositionSet.h index f912e53ddcb00bbc962e68586585a937e27eea72..a0c7c7a25bb6666e0ee7d580b4ea427b4cc6c492 100644 --- a/Geo/MVertexPositionSet.h +++ b/Geo/MVertexPositionSet.h @@ -32,6 +32,7 @@ class MVertexPositionSet{ { int totpoints = vertices.size(); if(!totpoints) return; + if(_maxDuplicates > totpoints) _maxDuplicates = totpoints; _zeronodes = annAllocPts(totpoints, 3); for(int i = 0; i < totpoints; i++){ vertices[i]->setIndex(0);