diff --git a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp index 3630ae260b9ff8d5fdbc6bc24c0d9ac8bb051099..f99522a5ea64f3fa9c47d0c725009012995ade58 100644 --- a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp +++ b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp @@ -158,13 +158,50 @@ static std::set<MVertex *> getAllBndVertices return bnd; } +// Approximate test of intersection element with circle/sphere by sampling +static bool testElInDist(const SPoint3 p, double limDist, MElement *el) +{ + const double sampleLen = 0.5*limDist; // Distance between sample points + + if (el->getDim() == 2) { // 2D? + for (int iEd = 0; iEd < el->getNumEdges(); iEd++) { // Loop over edges of element + MEdge ed = el->getEdge(iEd); + const int nPts = int(ed.length()/sampleLen)+2; // Nb of sample points based on edge length + for (int iPt = 0; iPt < nPts; iPt++) { // Loop over sample points + const SPoint3 pt = ed.interpolate(iPt/float(nPts-1)); + if (p.distance(pt) < limDist) return true; + } + } + } + else { // 3D + for (int iFace = 0; iFace < el->getNumFaces(); iFace++) { // Loop over faces of element + MFace face = el->getFace(iFace); + double lMax = 0.; // Max. edge length in face + const int nVert = face.getNumVertices(); + for (int iEd = 0; iEd < nVert; iEd++) + lMax = std::max(lMax, face.getEdge(iEd).length()); + const int nPts = int(lMax/sampleLen)+2; // Nb of sample points based on max. edge length in face + for (int iPt0 = 0; iPt0 < nPts; iPt0++) { + const double u = iPt0/float(nPts-1); + for (int iPt1 = 0; iPt1 < nPts; iPt1++) { // Loop over sample points + const double vMax = (nVert == 3) ? 1.-u : 1.; + const SPoint3 pt = face.interpolate(u, vMax*iPt1/float(nPts-1)); + if (p.distance(pt) < limDist) return true; + } + } + } + } + + return false; +} + static std::set<MElement*> getSurroundingBlob (MElement *el, int depth, const std::map<MVertex*, std::vector<MElement*> > &vertex2elements, const double distFactor, int forceDepth, bool optPrimSurfMesh) { - const SPoint3 p = el->barycenter(); + const SPoint3 p = el->barycenter(true); const double dist = el->maxDistToStraight(); const double limDist = ((optPrimSurfMesh && (dist < 1.e-10)) ? el->getOuterRadius() : dist) * distFactor; @@ -183,21 +220,12 @@ static std::set<MElement*> getSurroundingBlob ((*it)->getVertex(i))->second; for (std::vector<MElement*>::const_iterator itN = neighbours.begin(); itN != neighbours.end(); ++itN){ - if ((d < forceDepth) || (p.distance((*itN)->barycenter()) < limDist)){ + if ((d < forceDepth) || testElInDist(p, limDist, *itN)){ // Assume that if an el is too far, its neighbours are too far as well if (blob.insert(*itN).second) currentLayer.push_back(*itN); } } } -// for (int i = 0; i < (*it)->getNumPrimaryVertices(); ++i) { -// if ((d < forceDepth) || (p.distance((*it)->getVertex(i)->point()) < limDist)) { -// const std::vector<MElement*> &neighbours = vertex2elements.find((*it)->getVertex(i))->second; -// for (std::vector<MElement*>::const_iterator itN = neighbours.begin(); itN != neighbours.end(); ++itN) { -// // Assume that if an el is too far, its neighbours are too far as well -// if (blob.insert(*itN).second) currentLayer.push_back(*itN); -// } -// } -// } } lastLayer = currentLayer; }