diff --git a/src/mesh/blockMesh/Make/files b/src/mesh/blockMesh/Make/files
index cc7a1c1bb5fe8b9db96e92037ca0dced0fe89b86..d68caa1c244ba6544143a427c877a1e885649894 100644
--- a/src/mesh/blockMesh/Make/files
+++ b/src/mesh/blockMesh/Make/files
@@ -1,13 +1,17 @@
+curvedEdges/CatmullRomSpline.C
+curvedEdges/polyLine.C
+
+curvedEdges/arcEdge.C
 curvedEdges/curvedEdge.C
 curvedEdges/lineEdge.C
-curvedEdges/polyLine.C
 curvedEdges/polyLineEdge.C
-curvedEdges/arcEdge.C
-curvedEdges/spline.C
-curvedEdges/BSpline.C
-curvedEdges/simpleSplineEdge.C
-curvedEdges/polySplineEdge.C
 curvedEdges/lineDivide.C
+curvedEdges/splineEdge.C
+
+curvedEdges/legacy/spline.C
+curvedEdges/legacy/BSpline.C
+curvedEdges/legacy/simpleSplineEdge.C
+curvedEdges/legacy/polySplineEdge.C
 
 blockDescriptor/blockDescriptor.C
 blockDescriptor/blockDescriptorEdges.C
diff --git a/src/mesh/blockMesh/curvedEdges/CatmullRomSpline.C b/src/mesh/blockMesh/curvedEdges/CatmullRomSpline.C
new file mode 100644
index 0000000000000000000000000000000000000000..f82d3f0d589291b042e344115e59d444c0fb5e5e
--- /dev/null
+++ b/src/mesh/blockMesh/curvedEdges/CatmullRomSpline.C
@@ -0,0 +1,131 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "error.H"
+#include "CatmullRomSpline.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::CatmullRomSpline::CatmullRomSpline
+(
+    const pointField& Knots,
+    const vector&,
+    const vector&
+)
+:
+    polyLine(Knots)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::point Foam::CatmullRomSpline::position(const scalar mu) const
+{
+    // endpoints
+    if (mu < SMALL)
+    {
+        return points()[0];
+    }
+    else if (mu > 1 - SMALL)
+    {
+        return points()[points().size()-1];
+    }
+
+    scalar lambda = mu;
+    label segment = localParameter(lambda);
+    return position(segment, lambda);
+}
+
+
+Foam::point Foam::CatmullRomSpline::position
+(
+    const label segment,
+    const scalar mu
+) const
+{
+    const point& p0 = points()[segment];
+    const point& p1 = points()[segment+1];
+
+    // special cases - no calculation needed
+    if (segment < 0 || mu < 0.0)
+    {
+        return p0;
+    }
+    else if (segment > nSegments() || mu >= 1.0)
+    {
+        return p1;
+    }
+
+    // determine the end points
+    point e0;
+    point e1;
+
+    if (segment == 0)
+    {
+        // end: simple reflection
+        e0 = 2.0 * p0 - p1;
+    }
+    else
+    {
+        e0 = points()[segment-1];
+    }
+
+    if (segment+1 == nSegments())
+    {
+        // end: simple reflection
+        e1 = 2.0 * p1 - p0;
+    }
+    else
+    {
+        e1 = points()[segment+2];
+    }
+
+
+    return 0.5 *
+    (
+        ( 2 * p0 )
+      + mu *
+        (
+            ( -e0 + p1 )
+          + mu *
+            (
+                ( 2*e0 - 5*p0 + 4*p1 - e1 )
+              + mu *
+                ( -e0 + 3*p0 - 3*p1 + e1 )
+            )
+        )
+    );
+}
+
+
+Foam::scalar Foam::CatmullRomSpline::length() const
+{
+    notImplemented("CatmullRomSpline::length() const");
+    return 1.0;
+}
+
+
+// ************************************************************************* //
diff --git a/src/mesh/blockMesh/curvedEdges/CatmullRomSpline.H b/src/mesh/blockMesh/curvedEdges/CatmullRomSpline.H
new file mode 100644
index 0000000000000000000000000000000000000000..6f1851a7a65821af8c7986c38c0a17d7504429e0
--- /dev/null
+++ b/src/mesh/blockMesh/curvedEdges/CatmullRomSpline.H
@@ -0,0 +1,128 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2009-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::CatmullRomSpline
+
+Description
+    An implementation of Catmull-Rom splines (sometime as known as
+    Overhauser splines).
+
+    In this implementation, the end tangents are created
+    automatically by reflection.
+
+    In matrix form, the @e local interpolation on the interval t=[0..1] is
+    described as follows:
+    @verbatim
+    P(t) = 0.5 * [ t^3 t^2 t 1 ] * [ -1  3 -3  1 ] * [ P-1 ]
+                                   [  2 -5  4 -1 ]   [ P0 ]
+                                   [ -1  0  1  0 ]   [ P1 ]
+                                   [  0  2  0  0 ]   [ P2 ]
+    @endverbatim
+
+    Where P-1 and P2 represent the neighbouring points or the
+    extrapolated end points. Simple reflection is used to
+    automatically create the end points.
+
+    The spline is discretized based on the chord length of the
+    individual segments. In rare cases (sections with very high
+    curvatures), the resulting distribution may be sub-optimal.
+
+SeeAlso
+    http://www.algorithmist.net/catmullrom.html provides a nice
+    introduction
+
+ToDo
+    A future implementation could also handle closed splines - either
+    when the start/end points are identically or when specified.
+
+SourceFiles
+    CatmullRomSpline.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef CatmullRomSpline_H
+#define CatmullRomSpline_H
+
+#include "polyLine.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class CatmullRomSpline Declaration
+\*---------------------------------------------------------------------------*/
+
+class CatmullRomSpline
+:
+    public polyLine
+{
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        CatmullRomSpline(const CatmullRomSpline&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const CatmullRomSpline&);
+
+
+public:
+
+    // Constructors
+
+        //- Construct from components
+        CatmullRomSpline
+        (
+            const pointField& knots,
+            const vector& begTangentNotImplemented = vector::zero,
+            const vector& endTangentNotImplemented = vector::zero
+        );
+
+
+    // Member Functions
+
+        //- Return the point position corresponding to the curve parameter
+        //  0 <= lambda <= 1
+        point position(const scalar lambda) const;
+
+        //- Return the point position corresponding to the local parameter
+        //  0 <= lambda <= 1 on the given segment
+        point position(const label segment, const scalar lambda) const;
+
+        //- Return the length of the curve
+        scalar length() const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/mesh/blockMesh/curvedEdges/arcEdge.C b/src/mesh/blockMesh/curvedEdges/arcEdge.C
index 5718b731ad53db5c65df27e4139fd9917791f8b6..21143ac43a5bcd6e39a4e09a79c247aff0e8e935 100644
--- a/src/mesh/blockMesh/curvedEdges/arcEdge.C
+++ b/src/mesh/blockMesh/curvedEdges/arcEdge.C
@@ -71,8 +71,7 @@ Foam::cylindricalCS Foam::arcEdge::calcAngle()
     vector r3(p3_ - centre);
 
     // find angles
-    scalar tmp = (r3&r1)/(mag(r3)*mag(r1));
-    angle_ = radToDeg(acos(tmp));
+    angle_ = radToDeg(acos((r3 & r1)/(mag(r3) * mag(r1))));
 
     // check if the vectors define an exterior or an interior arcEdge
     if (((r1 ^ r2) & (r1 ^ r3)) < 0.0)
@@ -99,7 +98,7 @@ Foam::cylindricalCS Foam::arcEdge::calcAngle()
     radius_ = mag(r3);
 
     // set up and return the local coordinate system
-    return cylindricalCS("tmpCS", centre, tempAxis, r1);
+    return cylindricalCS("arcEdgeCS", centre, tempAxis, r1);
 }
 
 
diff --git a/src/mesh/blockMesh/curvedEdges/arcEdge.H b/src/mesh/blockMesh/curvedEdges/arcEdge.H
index 1539916aaa3673fed85d1bdaf0f78be79e602756..194e5c634bb39d147081af5e25624b2fe9f91de6 100644
--- a/src/mesh/blockMesh/curvedEdges/arcEdge.H
+++ b/src/mesh/blockMesh/curvedEdges/arcEdge.H
@@ -55,14 +55,15 @@ class arcEdge
     // Private data
 
         point p1_, p2_, p3_;
+        cylindricalCS cs_;
         scalar angle_;
         scalar radius_;
-        cylindricalCS cs_;
-
-        cylindricalCS calcAngle();
 
     // Private Member Functions
 
+        //- Calculate the coordinate system, angle and radius
+        cylindricalCS calcAngle();
+
         //- Disallow default bitwise copy construct
         arcEdge(const arcEdge&);
 
diff --git a/src/mesh/blockMesh/curvedEdges/curvedEdge.C b/src/mesh/blockMesh/curvedEdges/curvedEdge.C
index 595a923475d2c320735f96dd3f5c5dd553adc84c..35e58b7692b96e1573f900e6554cd664d90bb799 100644
--- a/src/mesh/blockMesh/curvedEdges/curvedEdge.C
+++ b/src/mesh/blockMesh/curvedEdges/curvedEdge.C
@@ -108,7 +108,7 @@ Foam::autoPtr<Foam::curvedEdge> Foam::curvedEdge::New
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-Foam::pointField Foam::curvedEdge::fullKnotList
+Foam::pointField Foam::curvedEdge::appendEndPoints
 (
     const pointField& points,
     const label start,
diff --git a/src/mesh/blockMesh/curvedEdges/curvedEdge.H b/src/mesh/blockMesh/curvedEdges/curvedEdge.H
index 629b833cb9f6600134c5d1a7404a74554ce282fe..bd1ad3246ada4444ef88cd3dabdfd914d695c329 100644
--- a/src/mesh/blockMesh/curvedEdges/curvedEdge.H
+++ b/src/mesh/blockMesh/curvedEdges/curvedEdge.H
@@ -64,9 +64,9 @@ protected:
 
     // Protected Member Functions
 
-        //- Return a complete knotList by adding the start/end points
+        //- Return a complete point field by appending the start/end points
         //  to the given list
-        static pointField fullKnotList
+        static pointField appendEndPoints
         (
             const pointField&,
             const label start,
diff --git a/src/mesh/blockMesh/curvedEdges/BSpline.C b/src/mesh/blockMesh/curvedEdges/legacy/BSpline.C
similarity index 100%
rename from src/mesh/blockMesh/curvedEdges/BSpline.C
rename to src/mesh/blockMesh/curvedEdges/legacy/BSpline.C
diff --git a/src/mesh/blockMesh/curvedEdges/BSpline.H b/src/mesh/blockMesh/curvedEdges/legacy/BSpline.H
similarity index 100%
rename from src/mesh/blockMesh/curvedEdges/BSpline.H
rename to src/mesh/blockMesh/curvedEdges/legacy/BSpline.H
diff --git a/src/mesh/blockMesh/curvedEdges/polySplineEdge.C b/src/mesh/blockMesh/curvedEdges/legacy/polySplineEdge.C
similarity index 93%
rename from src/mesh/blockMesh/curvedEdges/polySplineEdge.C
rename to src/mesh/blockMesh/curvedEdges/legacy/polySplineEdge.C
index 94ef3feb70685f89cbf02f4ac8e1d878a8a049bd..bf370cd7d3fe0fee5ebb1f554fd430a032b836a3 100644
--- a/src/mesh/blockMesh/curvedEdges/polySplineEdge.C
+++ b/src/mesh/blockMesh/curvedEdges/legacy/polySplineEdge.C
@@ -56,7 +56,7 @@ Foam::pointField Foam::polySplineEdge::intervening
 {
     BSpline spl
     (
-        fullKnotList(points_, start_, end_, otherknots),
+        appendEndPoints(curvedEdge::points_, start_, end_, otherknots),
         fstend,
         sndend
     );
@@ -73,7 +73,7 @@ Foam::pointField Foam::polySplineEdge::intervening
     interval /= nBetweenKnots + 1;
 
     pointField ans(nSize);
-    ans[0] = points_[start_];
+    ans[0] = curvedEdge::points_[start_];
 
     register scalar index(init);
     for (register label i=1; i<nSize-1; i++)
@@ -82,7 +82,7 @@ Foam::pointField Foam::polySplineEdge::intervening
         ans[i] = spl.realPosition(index);
     }
 
-    ans[nSize-1] = points_[end_];
+    ans[nSize-1] = curvedEdge::points_[end_];
 
     return ans;
 }
@@ -128,8 +128,8 @@ Foam::polySplineEdge::polySplineEdge
     vector fstend(is);
     vector sndend(is);
 
-    controlPoints_ = intervening(otherKnots_, nInterKnots, fstend, sndend);
-    calcDistances();
+    polyLine::points_ = intervening(otherKnots_, nInterKnots, fstend, sndend);
+    calcParam();
 }
 
 
diff --git a/src/mesh/blockMesh/curvedEdges/polySplineEdge.H b/src/mesh/blockMesh/curvedEdges/legacy/polySplineEdge.H
similarity index 98%
rename from src/mesh/blockMesh/curvedEdges/polySplineEdge.H
rename to src/mesh/blockMesh/curvedEdges/legacy/polySplineEdge.H
index e352da96fcdc4dbac74256fd36458d89b5cfb58a..dcb5fc2dfe97da62bbbf423196dc84a7839b86cb 100644
--- a/src/mesh/blockMesh/curvedEdges/polySplineEdge.H
+++ b/src/mesh/blockMesh/curvedEdges/legacy/polySplineEdge.H
@@ -26,7 +26,7 @@ Class
     Foam::polySplineEdge
 
 Description
-    A spline representation via a polyLine
+    A curvedEdge interface for B-splines.
 
 SourceFiles
     polySplineEdge.C
diff --git a/src/mesh/blockMesh/curvedEdges/simpleSplineEdge.C b/src/mesh/blockMesh/curvedEdges/legacy/simpleSplineEdge.C
similarity index 92%
rename from src/mesh/blockMesh/curvedEdges/simpleSplineEdge.C
rename to src/mesh/blockMesh/curvedEdges/legacy/simpleSplineEdge.C
index 61b803f44bdee9717bf088a244c6f473e04efeab..c5dc9e6d9c866015c02c0914640413a5b72f3bc0 100644
--- a/src/mesh/blockMesh/curvedEdges/simpleSplineEdge.C
+++ b/src/mesh/blockMesh/curvedEdges/legacy/simpleSplineEdge.C
@@ -48,7 +48,7 @@ Foam::simpleSplineEdge::simpleSplineEdge
 )
 :
     curvedEdge(points, start, end),
-    BSpline(fullKnotList(points, start, end, otherknots))
+    BSpline(appendEndPoints(points, start, end, otherknots))
 {}
 
 
@@ -63,14 +63,14 @@ Foam::simpleSplineEdge::simpleSplineEdge
 )
 :
     curvedEdge(points, start, end),
-    BSpline(fullKnotList(points, start, end, otherknots), fstend, sndend)
+    BSpline(appendEndPoints(points, start, end, otherknots), fstend, sndend)
 {}
 
 
 Foam::simpleSplineEdge::simpleSplineEdge(const pointField& points, Istream& is)
 :
     curvedEdge(points, is),
-    BSpline(fullKnotList(points, start_, end_, pointField(is)))
+    BSpline(appendEndPoints(points, start_, end_, pointField(is)))
 {}
 
 
diff --git a/src/mesh/blockMesh/curvedEdges/simpleSplineEdge.H b/src/mesh/blockMesh/curvedEdges/legacy/simpleSplineEdge.H
similarity index 98%
rename from src/mesh/blockMesh/curvedEdges/simpleSplineEdge.H
rename to src/mesh/blockMesh/curvedEdges/legacy/simpleSplineEdge.H
index 14a22adc09bec69c48423f4afa311e9ab79b576d..91acf6fdee535928dd7589b8c50b3bcc017bba73 100644
--- a/src/mesh/blockMesh/curvedEdges/simpleSplineEdge.H
+++ b/src/mesh/blockMesh/curvedEdges/legacy/simpleSplineEdge.H
@@ -26,7 +26,7 @@ Class
     Foam::simpleSplineEdge
 
 Description
-    The actual access class for Bspline
+    A curvedEdge interface for B-splines.
 
 SourceFiles
     simpleSplineEdge.C
diff --git a/src/mesh/blockMesh/curvedEdges/spline.C b/src/mesh/blockMesh/curvedEdges/legacy/spline.C
similarity index 100%
rename from src/mesh/blockMesh/curvedEdges/spline.C
rename to src/mesh/blockMesh/curvedEdges/legacy/spline.C
diff --git a/src/mesh/blockMesh/curvedEdges/spline.H b/src/mesh/blockMesh/curvedEdges/legacy/spline.H
similarity index 100%
rename from src/mesh/blockMesh/curvedEdges/spline.H
rename to src/mesh/blockMesh/curvedEdges/legacy/spline.H
diff --git a/src/mesh/blockMesh/curvedEdges/lineEdge.C b/src/mesh/blockMesh/curvedEdges/lineEdge.C
index f118634efc4107da2cb3f4fcf751d890e692e544..586d495d491d8e0a556a0d96f81e630fe308a35b 100644
--- a/src/mesh/blockMesh/curvedEdges/lineEdge.C
+++ b/src/mesh/blockMesh/curvedEdges/lineEdge.C
@@ -55,6 +55,10 @@ Foam::lineEdge::lineEdge(const pointField& points, Istream& is)
     curvedEdge(points, is)
 {}
 
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
+
+Foam::lineEdge::~lineEdge()
+{}
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
diff --git a/src/mesh/blockMesh/curvedEdges/lineEdge.H b/src/mesh/blockMesh/curvedEdges/lineEdge.H
index fdc8d035e64ce8fa7eca28938873c27aace882b0..3d295912325ae204df275b720707defdb416a62a 100644
--- a/src/mesh/blockMesh/curvedEdges/lineEdge.H
+++ b/src/mesh/blockMesh/curvedEdges/lineEdge.H
@@ -26,7 +26,7 @@ Class
     Foam::lineEdge
 
 Description
-    Defines a straight line between the start point and the end point.
+    A straight edge between the start point and the end point.
 
 SourceFiles
     lineEdge.C
@@ -70,13 +70,12 @@ public:
         //- Construct from components
         lineEdge(const pointField&, const label start, const label end);
 
-        //- Construct from Istream setting pointsList
+        //- Construct from Istream with a pointField
         lineEdge(const pointField&, Istream&);
 
 
-    //- Destructor
-        virtual ~lineEdge()
-        {}
+        //- Destructor
+        virtual ~lineEdge();
 
 
     // Member Functions
diff --git a/src/mesh/blockMesh/curvedEdges/polyLine.C b/src/mesh/blockMesh/curvedEdges/polyLine.C
index 739fd044f1c8e2bf1cb3f28f4947aa2d080e6d34..ed894246cb001063d01db19b5307b20a74d0376f 100644
--- a/src/mesh/blockMesh/curvedEdges/polyLine.C
+++ b/src/mesh/blockMesh/curvedEdges/polyLine.C
@@ -29,30 +29,27 @@ License
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-// calcDistances generates the distances_ lookup table (cumulative
-// distance along the line) from the individual vectors to the points
-
-void Foam::polyLine::calcDistances()
+void Foam::polyLine::calcParam()
 {
-    distances_.setSize(controlPoints_.size());
+    param_.setSize(points_.size());
 
-    if (distances_.size())
+    if (param_.size())
     {
-        distances_[0] = 0.0;
+        param_[0] = 0.0;
 
-        for (label i=1; i < distances_.size(); i++)
+        for (label i=1; i < param_.size(); i++)
         {
-            distances_[i] = distances_[i-1] +
-                mag(controlPoints_[i] - controlPoints_[i-1]);
+            param_[i] = param_[i-1] +
+                mag(points_[i] - points_[i-1]);
         }
 
         // normalize on the interval 0-1
-        lineLength_ = distances_[distances_.size()-1];
-        for (label i=1; i < distances_.size() - 1; i++)
+        lineLength_ = param_[param_.size()-1];
+        for (label i=1; i < param_.size() - 1; i++)
         {
-            distances_[i] /= lineLength_;
+            param_[i] /= lineLength_;
         }
-        distances_[distances_.size()-1] = 1.0;
+        param_[param_.size()-1] = 1.0;
     }
     else
     {
@@ -66,19 +63,69 @@ void Foam::polyLine::calcDistances()
 
 Foam::polyLine::polyLine(const pointField& ps)
 :
-    controlPoints_(ps),
-    distances_(0),
-    lineLength_(0.0)
+    points_(ps),
+    lineLength_(0.0),
+    param_(0)
 {
-    calcDistances();
+    calcParam();
 }
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-const Foam::pointField& Foam::polyLine::controlPoints() const
+const Foam::pointField& Foam::polyLine::points() const
+{
+    return points_;
+}
+
+
+Foam::label Foam::polyLine::nSegments() const
+{
+    return points_.size()-1;
+}
+
+
+Foam::label Foam::polyLine::localParameter(scalar& lambda) const
 {
-    return controlPoints_;
+    // check range of lambda
+    if (lambda < 0 || lambda > 1)
+    {
+        FatalErrorIn("polyLine::localParameter(scalar&)")
+            << "Parameter out-of-range, "
+            << "lambda = " << lambda
+            << abort(FatalError);
+    }
+
+    // check endpoints
+    if (lambda < SMALL)
+    {
+        lambda = 0;
+        return 0;
+    }
+    else if (lambda > 1 - SMALL)
+    {
+        lambda = 1;
+        return nSegments();
+    }
+
+    // search table of cumulative distances to find which line-segment
+    // we are on. Check the upper bound.
+
+    label segmentI = 1;
+    while (param_[segmentI] < lambda)
+    {
+        segmentI++;
+    }
+    segmentI--;   // we want the corresponding lower bound
+
+    // the local parameter [0-1] on this line segment
+    lambda =
+    (
+        ( lambda - param_[segmentI] )
+      / ( param_[segmentI+1] - param_[segmentI] )
+    );
+
+    return segmentI;
 }
 
 
@@ -96,31 +143,32 @@ Foam::point Foam::polyLine::position(const scalar lambda) const
     // check endpoints
     if (lambda < SMALL)
     {
-        return controlPoints_[0];
+        return points_[0];
     }
     else if (lambda > 1 - SMALL)
     {
-        return controlPoints_[controlPoints_.size()-1];
+        return points_[points_.size()-1];
     }
 
 
     // search table of cumulative distances to find which line-segment
     // we are on. Check the upper bound.
 
-    label i = 1;
-    while (distances_[i] < lambda)
+    label segmentI = 1;
+    while (param_[segmentI] < lambda)
     {
-        i++;
+        ++segmentI;
     }
-    i--;   // we now want the lower bound
+    --segmentI;   // we now want the lower bound
 
 
     // linear interpolation
     return
     (
-        controlPoints_[i]
-      + ( controlPoints_[i+1] - controlPoints_[i] )
-      * ( lambda - distances_[i] ) / ( distances_[i+1] - distances_[i] )
+        points_[segmentI]
+      + ( points_[segmentI+1] - points_[segmentI] )
+      * ( lambda - param_[segmentI] )
+      / ( param_[segmentI+1] - param_[segmentI] )
     );
 }
 
diff --git a/src/mesh/blockMesh/curvedEdges/polyLine.H b/src/mesh/blockMesh/curvedEdges/polyLine.H
index e549b8fb85d26da512475def74c7737cd72df955..ea8c59e389bf08cfa5a6d28c1cd5d1503342e107 100644
--- a/src/mesh/blockMesh/curvedEdges/polyLine.H
+++ b/src/mesh/blockMesh/curvedEdges/polyLine.H
@@ -26,11 +26,8 @@ Class
     Foam::polyLine
 
 Description
-    Define a series of control points, which can also be interpreted as a
-    series of straight line segments.
-
-    This is the basic polyLine class which implements just the line
-    (no topology - it is not derived from curvedEdge)
+    A series of straight line segments, which can also be interpreted as
+    a series of control points for splines, etc.
 
 SourceFiles
     polyLine.C
@@ -67,19 +64,25 @@ protected:
 
     // Protected data
 
-        //- The control points or ends of each segmen
-        pointField controlPoints_;
-
-        //- The rational (0-1) cumulative distance for each control-point
-        scalarList distances_;
+        //- The control points or ends of each segments
+        pointField points_;
 
         //- The real line length
         scalar lineLength_;
 
+        //- The rational (0-1) cumulative parameter value for each point
+        scalarList param_;
+
     // Protected member functions
 
-        //- Precalculate the rational cumulative distances and the line-length
-        void calcDistances();
+        //- Precalculate the rational cumulative parameter value
+        //  and the line-length
+        void calcParam();
+
+
+        //- Return the line segment and the local parameter [0..1]
+        //  corresponding to the global lambda [0..1]
+        label localParameter(scalar& lambda) const;
 
 public:
 
@@ -92,7 +95,10 @@ public:
     // Member Functions
 
         //- Return const-access to the control-points
-        const pointField& controlPoints() const;
+        const pointField& points() const;
+
+        //- Return the number of line segments
+        label nSegments() const;
 
         //- Return the point position corresponding to the curve parameter
         //  0 <= lambda <= 1
diff --git a/src/mesh/blockMesh/curvedEdges/polyLineEdge.C b/src/mesh/blockMesh/curvedEdges/polyLineEdge.C
index 522c6abe484c52aa39f7e881876d1f585f58064f..1f038a78a85af3e3812bb3b0b0bf93eaa2e5c7cc 100644
--- a/src/mesh/blockMesh/curvedEdges/polyLineEdge.C
+++ b/src/mesh/blockMesh/curvedEdges/polyLineEdge.C
@@ -48,14 +48,20 @@ Foam::polyLineEdge::polyLineEdge
 )
 :
     curvedEdge(ps, start, end),
-    polyLine(fullKnotList(ps, start_, end_, otherPoints))
+    polyLine(appendEndPoints(ps, start_, end_, otherPoints))
 {}
 
 
 Foam::polyLineEdge::polyLineEdge(const pointField& ps, Istream& is)
 :
     curvedEdge(ps, is),
-    polyLine(fullKnotList(ps, start_, end_, pointField(is)))
+    polyLine(appendEndPoints(ps, start_, end_, pointField(is)))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::polyLineEdge::~polyLineEdge()
 {}
 
 
diff --git a/src/mesh/blockMesh/curvedEdges/polyLineEdge.H b/src/mesh/blockMesh/curvedEdges/polyLineEdge.H
index 2c79765a980059fad45e696f0d379ff481e89cd3..e941bba716183daf3c111ae92bcb1925a781c2bf 100644
--- a/src/mesh/blockMesh/curvedEdges/polyLineEdge.H
+++ b/src/mesh/blockMesh/curvedEdges/polyLineEdge.H
@@ -83,9 +83,8 @@ public:
         polyLineEdge(const pointField&, Istream&);
 
 
-    // Destructor
-
-        virtual ~polyLineEdge(){}
+        //- Destructor
+        virtual ~polyLineEdge();
 
 
     // Member Functions
diff --git a/src/mesh/blockMesh/curvedEdges/splineEdge.C b/src/mesh/blockMesh/curvedEdges/splineEdge.C
new file mode 100644
index 0000000000000000000000000000000000000000..6c5df771a9cc19865a7b9559f571c105a547f396
--- /dev/null
+++ b/src/mesh/blockMesh/curvedEdges/splineEdge.C
@@ -0,0 +1,86 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "splineEdge.H"
+#include "addToRunTimeSelectionTable.H"
+
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(splineEdge, 0);
+    addToRunTimeSelectionTable(curvedEdge, splineEdge, Istream);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::splineEdge::splineEdge
+(
+    const pointField& points,
+    const label start,
+    const label end,
+    const pointField& otherknots
+)
+:
+    curvedEdge(points, start, end),
+    CatmullRomSpline(appendEndPoints(points, start, end, otherknots))
+{}
+
+
+Foam::splineEdge::splineEdge(const pointField& points, Istream& is)
+:
+    curvedEdge(points, is),
+    CatmullRomSpline(appendEndPoints(points, start_, end_, pointField(is)))
+{
+    token t(is);
+    is.putBack(t);
+
+    // might have start/end tangents that we currently ignore
+    if (t == token::BEGIN_LIST)
+    {
+        vector fstend(is);
+        vector sndend(is);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::point Foam::splineEdge::position(const scalar mu) const
+{
+    return CatmullRomSpline::position(mu);
+}
+
+
+Foam::scalar Foam::splineEdge::length() const
+{
+    return CatmullRomSpline::length();
+}
+
+
+// ************************************************************************* //
diff --git a/src/mesh/blockMesh/curvedEdges/splineEdge.H b/src/mesh/blockMesh/curvedEdges/splineEdge.H
new file mode 100644
index 0000000000000000000000000000000000000000..c1ad9f5f76868be578c04c374cec87854c45b86b
--- /dev/null
+++ b/src/mesh/blockMesh/curvedEdges/splineEdge.H
@@ -0,0 +1,111 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::splineEdge
+
+Description
+    A curvedEdge interface for Catmull-Rom splines.
+
+SourceFiles
+    splineEdge.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef splineEdge_H
+#define splineEdge_H
+
+#include "curvedEdge.H"
+#include "CatmullRomSpline.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class splineEdge Declaration
+\*---------------------------------------------------------------------------*/
+
+class splineEdge
+:
+    public curvedEdge,
+    public CatmullRomSpline
+{
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        splineEdge(const splineEdge&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const splineEdge&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("spline");
+
+
+    // Constructors
+
+        //- Construct from components
+        splineEdge
+        (
+            const pointField&,
+            const label start,
+            const label end,
+            const pointField& otherKnots
+        );
+
+        //- Construct from Istream setting pointsList
+        splineEdge(const pointField&, Istream&);
+
+
+    // Destructor
+
+        virtual ~splineEdge()
+        {}
+
+
+    // Member Functions
+
+        //- Return the point position corresponding to the curve parameter
+        //  0 <= lambda <= 1
+        virtual point position(const scalar) const;
+
+        //- Return the length of the simple spline curve
+        virtual scalar length() const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //