diff --git a/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.C b/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.C
index d5e6d4d8e7135ac879f7b9642b6fcc2a23381864..d40c00877671782dcd92cfd5df4c7c9b75769281 100644
--- a/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.C
+++ b/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.C
@@ -28,6 +28,15 @@ License
 #include "Time.H"
 #include "OSspecific.H"
 
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::Enum<Foam::triSurfaceLoader::loadingOption>
+Foam::triSurfaceLoader::loadingOptionNames
+(
+    SINGLE_REGION, { "single", "file", "offset", "merge" }
+);
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::triSurfaceLoader::triSurfaceLoader(const fileName& directory)
@@ -201,24 +210,56 @@ Foam::label Foam::triSurfaceLoader::select(const wordReList& matcher)
 }
 
 
-Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load() const
+Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load
+(
+    const enum loadingOption opt
+) const
 {
+    autoPtr<triSurface> output;
+
     if (selected_.empty())
     {
-        return autoPtr<triSurface>();
+        return output;
     }
     else if (selected_.size() == 1)
     {
-        return autoPtr<triSurface>(new triSurface(directory_/selected_[0]));
+        output.set(new triSurface(directory_/selected_[0]));
+
+        triSurface& surf = output();
+
+        if
+        (
+            opt == loadingOption::SINGLE_REGION
+         || opt == loadingOption::FILE_REGION
+        )
+        {
+            for (labelledTri& f : surf)
+            {
+                f.region() = 0;
+            }
+
+            if (surf.patches().size())
+            {
+                surf.patches().setSize(1);
+            }
+            else
+            {
+                surf.patches().append
+                (
+                    geometricSurfacePatch(selected_[0].lessExt(), 0)
+                );
+            }
+        }
+
+        return output;
     }
 
+
     List<labelledTri> faces;
     pointField points;
-    label regoff = 0; // region offset
 
-    // collect all patches, preserving names.
-    // This will be horrible for output, but is good if we are relying on
-    // the names for defining baffles.
+    Map<label> oldToNew;
+    HashTable<label> patchNameLookup;
     DynamicList<geometricSurfacePatch> patches(16*selected_.size());
 
     forAll(selected_, surfi)
@@ -227,22 +268,114 @@ Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load() const
 
         List<labelledTri> addfaces(addsurf.xferFaces());
         List<point> addpoints(addsurf.xferPoints());
-        patches.append(addsurf.patches());
 
+        // Offset the points for all additional surfaces
         if (surfi)
         {
-            const label ptoff = points.size(); // point offset
+            const label ptoff = points.size();
 
-            forAll(addfaces, facei)
+            for (labelledTri& f : addfaces)
             {
-                labelledTri& f = addfaces[facei];
                 forAll(f, fi)
                 {
                     f[fi] += ptoff;
                 }
-                f.region() += regoff;
+            }
+        }
+
+        switch (opt)
+        {
+            case loadingOption::SINGLE_REGION:
+            {
+                for (labelledTri& f : addfaces)
+                {
+                    f.region() = 0;
+                }
+
+                if (patches.empty() && !addsurf.patches().empty())
+                {
+                    patches.append(addsurf.patches().first());
+                }
+
+                break;
+            }
+
+            case loadingOption::FILE_REGION:
+            {
+                for (labelledTri& f : addfaces)
+                {
+                    f.region() = surfi;
+                }
+
+                // Use surface name for region
+                patches.append
+                (
+                    geometricSurfacePatch(selected_[surfi].lessExt(), surfi)
+                );
+
+                break;
+            }
+
+            case loadingOption::OFFSET_REGION:
+            {
+                // Collect all patches, preserving names.
+                // This will be horrible for output, but is good if we rely
+                // on the names for defining baffles.
+
+                // region offset
+                const label regoff = patches.size();
+                patches.append(addsurf.patches());
+
+                if (surfi)
+                {
+                    for (labelledTri& f : addfaces)
+                    {
+                        f.region() += regoff;
+                    }
+                }
+                break;
             }
 
+            case loadingOption::MERGE_REGION:
+            {
+                // Merge by name
+                geometricSurfacePatchList& addpatches = addsurf.patches();
+
+                // Build lookup tables with name->id and localId -> mergedId
+                oldToNew.clear();
+                forAll(addpatches, patchi)
+                {
+                    geometricSurfacePatch& p = addpatches[patchi];
+                    const word& patchName = p.name();
+
+                    label patchId = patches.size();
+                    if (patchNameLookup.insert(patchName, patchId))
+                    {
+                        p.index() = patchId;
+                        patches.append(p);
+                    }
+                    else
+                    {
+                        patchId = patchNameLookup[patchName];
+                    }
+
+                    oldToNew.insert(patchi, patchId);
+                }
+
+                if (surfi)
+                {
+                    // Relabel regions accordingly
+                    for (labelledTri& f : addfaces)
+                    {
+                        f.region() = oldToNew[f.region()];
+                    }
+                }
+                break;
+            }
+        }
+
+        if (surfi)
+        {
             faces.append(addfaces);
             points.append(addpoints);
         }
@@ -251,11 +384,11 @@ Foam::autoPtr<Foam::triSurface> Foam::triSurfaceLoader::load() const
             faces.transfer(addfaces);
             points.transfer(addpoints);
         }
-
-        regoff += addsurf.patches().size();
     }
 
-    return autoPtr<triSurface>(new triSurface(faces, patches, points, true));
+    output.set(new triSurface(faces, patches, points, true));
+
+    return output;
 }
 
 
diff --git a/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.H b/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.H
index aec554ec5285cb2a064ddb757e4942b8a1f7767f..7332026f765d7f6d74dc7ceb78ed6d36b78c845c 100644
--- a/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.H
+++ b/src/meshTools/triSurface/triSurfaceLoader/triSurfaceLoader.H
@@ -42,6 +42,7 @@ SourceFiles
 
 #include "triSurface.H"
 #include "wordReList.H"
+#include "Enum.H"
 #include "hashedWordList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -59,6 +60,23 @@ class Time;
 
 class triSurfaceLoader
 {
+public:
+
+    //- The file loading options for triSurfaceLoader
+    enum loadingOption
+    {
+        SINGLE_REGION,  //!< "single" = One region for all files
+        FILE_REGION,    //!< "file"   = One region for each file
+        OFFSET_REGION,  //!< "offset" = Offset regions per file
+        MERGE_REGION    //!< "merge"  = Merge regions by name
+    };
+
+    //- The loading enumeration names
+    static const Enum<loadingOption> loadingOptionNames;
+
+
+private:
+
     // Private data
 
         //- The directory to load from (eg, case/constant/triSurface)
@@ -136,7 +154,10 @@ public:
         label select(const wordReList& matcher);
 
         //- Load a single file, or load and combine multiple selected files
-        autoPtr<triSurface> load() const;
+        autoPtr<triSurface> load
+        (
+            const enum loadingOption opt = loadingOption::OFFSET_REGION
+        ) const;
 
 };