diff --git a/Geo/GFaceCompound.cpp b/Geo/GFaceCompound.cpp
index a9631630a9419b27588a58ac802d4616c16e9215..6c19b7f7bd7fc4594672398d2c83bcb314b657fe 100644
--- a/Geo/GFaceCompound.cpp
+++ b/Geo/GFaceCompound.cpp
@@ -2059,10 +2059,10 @@ GPoint GFaceCompound::pointInRemeshedOctree(double par1, double par2) const {
   //now find point
   double uvw[3]={par1,par2, 0.0};
   double UV[3];
-  double initialTol = MElement::getTolerance();
-  MElement::setTolerance(1.e-2); 
-  MElement *e = octNew->find(par1,par2, 0.0,-1,false);  
-  MElement::setTolerance(initialTol);
+  //double initialTol = MElement::getTolerance();
+  //MElement::setTolerance(1.e-2); 
+  MElement *e = octNew->find(par1,par2, 0.0,-1,true);  
+  //MElement::setTolerance(initialTol);
   if (e){
     e->xyz2uvw(uvw,UV);
     double valX[8], valY[8], valZ[8];
@@ -2087,7 +2087,7 @@ GPoint GFaceCompound::pointInRemeshedOctree(double par1, double par2) const {
 
 #if defined(HAVE_ANN)
     double pt[3] = {par1,par2,0.0};
-    uv_kdtree->annkSearch(pt, 1, index, dist);
+    uv_kdtree->annkSearch(pt, 2, index, dist);
     SPoint3  p1(nodes[index[0]][0], nodes[index[0]][1], nodes[index[0]][2]);
     SPoint3  p2(nodes[index[1]][0], nodes[index[1]][1], nodes[index[1]][2]);
     SPoint3 pnew; double d;
diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp
index e11a62f94b9c72095d6f4c9245154f49f6fff91f..d5516a3600f07fa6eb6e1e452d10d3ad1b18ec5e 100644
--- a/Mesh/BackgroundMesh.cpp
+++ b/Mesh/BackgroundMesh.cpp
@@ -460,19 +460,22 @@ backgroundMesh::backgroundMesh(GFace *_gf)
   // those triangles are local to the backgroundMesh so that
   // they do not depend on the actual mesh that can be deleted
 
+  std::set<SPoint2> myBCNodes;
   for (unsigned int i = 0; i < _gf->triangles.size(); i++){
     MTriangle *e = _gf->triangles[i];
     MVertex *news[3];
     for (int j=0;j<3;j++){
-      std::map<MVertex*,MVertex*>::iterator it = _3Dto2D.find(e->getVertex(j));
+      MVertex *v = e->getVertex(j);
+      std::map<MVertex*,MVertex*>::iterator it = _3Dto2D.find(v);
       MVertex *newv =0;
       if (it == _3Dto2D.end()){
         SPoint2 p;
-        bool success = reparamMeshVertexOnFace(e->getVertex(j), _gf, p);
+        bool success = reparamMeshVertexOnFace(v, _gf, p);
         newv = new MVertex (p.x(), p.y(), 0.0);
         _vertices.push_back(newv);
-        _3Dto2D[e->getVertex(j)] = newv;
-        _2Dto3D[newv] = e->getVertex(j);
+        _3Dto2D[v] = newv;
+        _2Dto3D[newv] = v;
+	if(v->onWhat()->dim()<2) myBCNodes.insert(p);
       }
       else newv = it->second;
       news[j] = newv;
@@ -480,6 +483,24 @@ backgroundMesh::backgroundMesh(GFace *_gf)
     _triangles.push_back(new MTriangle(news[0],news[1],news[2]));
   }
   
+#if defined(HAVE_ANN)
+  //printf("creating uv kdtree %d \n", myBCNodes.size());
+    index = new ANNidx[2];
+    dist  = new ANNdist[2];
+    nodes = annAllocPts(myBCNodes.size(), 3);
+    std::set<SPoint2>::iterator itp = myBCNodes.begin();
+    int ind = 0;
+    while (itp != myBCNodes.end()){
+      SPoint2 pt = *itp;
+      //fprintf(of, "SP(%g,%g,%g){%g};\n", pt.x(), pt.y(), 0.0, 10000);
+      nodes[ind][0] = pt.x();
+      nodes[ind][1] = pt.y();
+      nodes[ind][2] = 0.0;
+      itp++; ind++;
+    }
+    uv_kdtree = new ANNkd_tree(nodes, myBCNodes.size(), 3);
+#endif
+
   // build a search structure
   _octree = new MElementOctree(_triangles); 
   
@@ -507,6 +528,12 @@ backgroundMesh::~backgroundMesh()
   for (unsigned int i = 0; i < _vertices.size(); i++) delete _vertices[i];
   for (unsigned int i = 0; i < _triangles.size(); i++) delete _triangles[i];
   delete _octree;
+#if defined(HAVE_ANN)
+  if(uv_kdtree) delete uv_kdtree;
+  if(nodes) annDeallocPts(nodes);
+  delete[]index;
+  delete[]dist;
+#endif
 }
 
 static void propagateValuesOnFace(GFace *_gf,
@@ -772,8 +799,22 @@ double backgroundMesh::operator() (double u, double v, double w) const
   double uv2[3];
   MElement *e = _octree->find(u, v, w, 2, true);
   if (!e) {
-    Msg::Error("BGM octree: cannot find %g %g %g", u, v, w);
-    return -1000.0;//0.4;
+#if defined(HAVE_ANN)
+    //printf("BGM octree not found --> find in kdtree \n");
+    double pt[3] = {u,v,0.0};
+    uv_kdtree->annkSearch(pt, 2, index, dist);
+    SPoint3  p1(nodes[index[0]][0], nodes[index[0]][1], nodes[index[0]][2]);
+    SPoint3  p2(nodes[index[1]][0], nodes[index[1]][1], nodes[index[1]][2]);
+    SPoint3 pnew; double d;
+    signedDistancePointLine(p1,p2, SPoint3(u,v,0.0), d, pnew);
+    double uvw[3]={pnew.x(),pnew.y(), 0.0};
+    double UV[3];
+    e = _octree->find(pnew.x(), pnew.y(), 0.0, 2, true); 
+#endif
+    if(!e){
+      Msg::Error("BGM octree: cannot find UVW=%g %g %g", u, v, w);
+      return -1000.0;//0.4;
+    }
   }
   e->xyz2uvw(uv, uv2);
   std::map<MVertex*,double>::const_iterator itv1 = _sizes.find(e->getVertex(0));
@@ -799,8 +840,22 @@ double backgroundMesh::getAngle(double u, double v, double w) const
   double uv2[3];
   MElement *e = _octree->find(u, v, w, 2, true);
   if (!e) {
-    Msg::Error("BGM octree : cannot find %g %g %g", u, v, w);
-    return 0.0;
+#if defined(HAVE_ANN)
+    //printf("BGM octree not found --> find in kdtree \n");
+    double pt[3] = {u,v,0.0};
+    uv_kdtree->annkSearch(pt, 2, index, dist);
+    SPoint3  p1(nodes[index[0]][0], nodes[index[0]][1], nodes[index[0]][2]);
+    SPoint3  p2(nodes[index[1]][0], nodes[index[1]][1], nodes[index[1]][2]);
+    SPoint3 pnew; double d;
+    signedDistancePointLine(p1,p2, SPoint3(u,v,0.0), d, pnew);
+    double uvw[3]={pnew.x(),pnew.y(), 0.0};
+    double UV[3];
+    e = _octree->find(pnew.x(), pnew.y(), 0.0, 2,true); 
+#endif
+    if(!e){
+      Msg::Error("BGM octree angle: cannot find UVW=%g %g %g", u, v, w);
+      return -1000.0;
+    }
   }
   e->xyz2uvw(uv, uv2);
   std::map<MVertex*,double>::const_iterator itv1 = _angles.find(e->getVertex(0));
diff --git a/Mesh/BackgroundMesh.h b/Mesh/BackgroundMesh.h
index d7d0ae7c73d595d5e93966e364ec61f1dece77d2..8d5030c6856ea392b668e927e8364d37748384c1 100644
--- a/Mesh/BackgroundMesh.h
+++ b/Mesh/BackgroundMesh.h
@@ -11,6 +11,11 @@
 #include <list>
 #include "simpleFunction.h"
 
+#if defined(HAVE_ANN)
+#include <ANN/ANN.h>
+class ANNkd_tree;
+#endif
+
 class MElementOctree;
 class GFace;
 class GVertex;
@@ -47,6 +52,12 @@ class backgroundMesh : public simpleFunction<double>
   static backgroundMesh * _current;
   backgroundMesh(GFace *);
   ~backgroundMesh();
+#if defined(HAVE_ANN)
+   mutable ANNkd_tree *uv_kdtree;
+   mutable ANNpointArray nodes;
+   ANNidxArray index;
+   ANNdistArray dist;
+#endif
  public:
   static void set(GFace *);
   static void unset();
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 3f7838de4ab7a478cd0c2ae6cc647c51cd442794..8b12aef059497b165272c6ff96f145f9d7aecf31 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -1876,6 +1876,7 @@ void meshGFace::operator() (GFace *gf)
   twoPassesMesh--;
   if (backgroundMesh::current()){
     backgroundMesh::unset();
+    //backgroundMesh::set(gf);
   }
   if (CTX::instance()->mesh.saveAll){
     backgroundMesh::set(gf);