diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.C b/src/meshTools/searchableSurface/triSurfaceMesh.C
index aa117c27942c4e90fc6b8521faaa170075dd7093..ab26033eed015de3de98197c1204ee09a59cec27 100644
--- a/src/meshTools/searchableSurface/triSurfaceMesh.C
+++ b/src/meshTools/searchableSurface/triSurfaceMesh.C
@@ -331,6 +331,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
     ),
     triSurface(s),
     tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()),
+    minQuality_(-1),
     maxTreeDepth_(10),
     surfaceClosed_(-1)
 {}
@@ -375,6 +376,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
         )
     ),
     tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()),
+    minQuality_(-1),
     maxTreeDepth_(10),
     surfaceClosed_(-1)
 {}
@@ -422,6 +424,7 @@ Foam::triSurfaceMesh::triSurfaceMesh
         )
     ),
     tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()),
+    minQuality_(-1),
     maxTreeDepth_(10),
     surfaceClosed_(-1)
 {
@@ -444,6 +447,13 @@ Foam::triSurfaceMesh::triSurfaceMesh
             << tolerance_ << endl;
     }
 
+    // Have optional minimum quality for normal calculation
+    if (dict.readIfPresent("minQuality", minQuality_) && minQuality_ > 0)
+    {
+        Info<< searchableSurface::name()
+            << " : ignoring triangles with quality < "
+            << minQuality_ << " for normals calculation." << endl;
+    }
 
     // Have optional non-standard tree-depth to limit storage.
     if (dict.readIfPresent("maxTreeDepth", maxTreeDepth_) && maxTreeDepth_ > 0)
@@ -804,22 +814,70 @@ void Foam::triSurfaceMesh::getNormal
 {
     normal.setSize(info.size());
 
-    forAll(info, i)
+    if (minQuality_ >= 0)
     {
-        if (info[i].hit())
+        // Make sure we don't use triangles with low quality since
+        // normal is not reliable.
+
+        const triSurface& s = static_cast<const triSurface&>(*this);
+        const labelListList& faceFaces = s.faceFaces();
+
+        forAll(info, i)
         {
-            label faceI = info[i].index();
-            //- Cached:
-            //normal[i] = faceNormals()[faceI];
+            if (info[i].hit())
+            {
+                label faceI = info[i].index();
 
-            //- Uncached
-            normal[i] = triSurface::operator[](faceI).normal(points());
-            normal[i] /= mag(normal[i]) + VSMALL;
+                scalar qual = s[faceI].tri(points()).quality();
+
+                if (qual < minQuality_)
+                {
+                    // Search neighbouring triangles
+                    const labelList& fFaces = faceFaces[faceI];
+
+                    forAll(fFaces, j)
+                    {
+                        label nbrI = fFaces[j];
+                        scalar nbrQual = s[nbrI].tri(points()).quality();
+                        if (nbrQual > qual)
+                        {
+                            qual = nbrQual;
+                            normal[i] = s[nbrI].normal(points());
+                        }
+                    }
+                }
+                else
+                {
+                    normal[i] = s[faceI].normal(points());
+                }
+                normal[i] /= mag(normal[i]);
+            }
+            else
+            {
+                // Set to what?
+                normal[i] = vector::zero;
+            }
         }
-        else
+    }
+    else
+    {
+        forAll(info, i)
         {
-            // Set to what?
-            normal[i] = vector::zero;
+            if (info[i].hit())
+            {
+                label faceI = info[i].index();
+                //- Cached:
+                //normal[i] = faceNormals()[faceI];
+
+                //- Uncached
+                normal[i] = triSurface::operator[](faceI).normal(points());
+                normal[i] /= mag(normal[i]) + VSMALL;
+            }
+            else
+            {
+                // Set to what?
+                normal[i] = vector::zero;
+            }
         }
     }
 }
diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.H b/src/meshTools/searchableSurface/triSurfaceMesh.H
index e1615ccc9bd9300c46b5683299ea41e21551ba67..19d2e78c88e0c7e30c2a0aecf9175f920394fa54 100644
--- a/src/meshTools/searchableSurface/triSurfaceMesh.H
+++ b/src/meshTools/searchableSurface/triSurfaceMesh.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2004-2010 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2004-2011 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -31,6 +31,7 @@ Description
         - scale     : scaling factor.
         - tolerance : relative tolerance for doing intersections
                       (see triangle::intersection)
+        - minQuality: discard triangles with low quality when getting normal
 
 SourceFiles
     triSurfaceMesh.C
@@ -70,6 +71,10 @@ private:
         //- Optional tolerance to use in searches
         scalar tolerance_;
 
+        //- Optional min triangle quality. Triangles below this get
+        //  ignored for normal calculation
+        scalar minQuality_;
+
         //- Optional max tree depth of octree
         label maxTreeDepth_;