ENH: support different triSurface loading options

- "single" = One region for all files
 - "file"   = One region for each file
 - "offset" = Offset regions per file
 - "merge"  = Merge regions by name

These specifications provide finer control when loading multiple
surfaces.
This commit is contained in:
Mark Olesen 2017-05-29 18:25:23 +02:00
parent 67237e9385
commit 6563c98d6c
2 changed files with 170 additions and 16 deletions

View File

@ -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;
}

View File

@ -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;
};