ENH: surface: various updates to the surface utilities

surfaceBooleanFeatures: use CGAL for intersection
surfaceCheck: write surface zoning as vtk file
surfaceInflate: new utility to offset surface
surfacePatch: replacement for surfaceAutoPatch. Also does cutting of surfaces.
This commit is contained in:
mattijs
2015-11-10 15:04:32 +00:00
parent 4f9e48bfc5
commit c6a3d4f3c5
36 changed files with 4963 additions and 555 deletions

View File

@ -0,0 +1,7 @@
searchableSurfaceModifier/searchableSurfaceModifier.C
searchableSurfaceModifier/autoPatch.C
searchableSurfaceModifier/cut.C
surfacePatch.C
EXE = $(FOAM_APPBIN)/surfacePatch

View File

@ -0,0 +1,10 @@
EXE_INC = \
-IsearchableSurfaceModifier \
-I$(LIB_SRC)/triSurface/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-ltriSurface \
-lmeshTools

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 3 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, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "autoPatch.H"
#include "addToRunTimeSelectionTable.H"
#include "surfaceFeatures.H"
#include "triSurfaceMesh.H"
#include "PatchTools.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace searchableSurfaceModifiers
{
defineTypeNameAndDebug(autoPatch, 0);
addToRunTimeSelectionTable
(
searchableSurfaceModifier,
autoPatch,
dictionary
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::searchableSurfaceModifiers::autoPatch::autoPatch
(
const searchableSurfaces& geometry,
const dictionary& dict
)
:
searchableSurfaceModifier(geometry, dict),
featureAngle_(readScalar(dict.lookup("featureAngle")))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::searchableSurfaceModifiers::autoPatch::~autoPatch()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::searchableSurfaceModifiers::autoPatch::modify
(
const labelList& regions,
searchableSurface& geom
) const
{
triSurface& surf = refCast<triSurfaceMesh>(geom);
surfaceFeatures set(surf, 180.0-featureAngle_);
Info<< nl
<< "Feature set:" << nl
<< " feature points : " << set.featurePoints().size() << nl
<< " feature edges : " << set.featureEdges().size() << nl
<< " of which" << nl
<< " region edges : " << set.nRegionEdges() << nl
<< " external edges : " << set.nExternalEdges() << nl
<< " internal edges : " << set.nInternalEdges() << nl
<< endl;
// Get per-edge status.
boolList borderEdge(surf.nEdges(), false);
forAll(set.featureEdges(), i)
{
borderEdge[set.featureEdges()[i]] = true;
}
bool changed = false;
forAll(regions, i)
{
label regionI = regions[i];
labelList subRegion(surf.size(), -1);
label nSub = 0;
forAll(surf, faceI)
{
if (surf[faceI].region() == regionI && subRegion[faceI] == -1)
{
PatchTools::markZone(surf, borderEdge, faceI, nSub, subRegion);
nSub++;
}
}
Info<< "For region " << surf.patches()[regionI].name()
<< " detected sub regions " << nSub << endl;
if (nSub > 1)
{
label nOldPatches = surf.patches().size();
for (label subI = 0; subI < nSub; subI++)
{
geometricSurfacePatch patch
(
surf.patches()[regionI].geometricType(),
surf.patches()[regionI].name() + Foam::name(subI),
surf.patches().size()
);
Info<< "For region " << surf.patches()[regionI].name()
<< " creating region " << patch.name() << endl;
surf.patches().append(patch);
}
forAll(subRegion, faceI)
{
if (subRegion[faceI] != -1)
{
surf[faceI].region() = nOldPatches + subRegion[faceI];
}
}
changed = true;
}
}
return changed;
}
// ************************************************************************* //

View File

@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 3 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, see <http://www.gnu.org/licenses/>.
Class
Foam::searchableSurfaceModifier::autoPatch
Description
Patchify triangles based on a feature angle. Replacement of surfaceAutoPatch
SourceFiles
autoPatch.C
\*---------------------------------------------------------------------------*/
#ifndef autoPatch_H
#define autoPatch_H
#include "searchableSurfaceModifier.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace searchableSurfaceModifiers
{
/*---------------------------------------------------------------------------*\
Class autoPatch Declaration
\*---------------------------------------------------------------------------*/
class autoPatch
:
public searchableSurfaceModifier
{
// Private data
//- Feature angle
const scalar featureAngle_;
// Private Member Functions
public:
//- Runtime type information
TypeName("autoPatch");
// Constructors
//- Construct from dictionary
autoPatch(const searchableSurfaces&, const dictionary&);
//- Clone
autoPtr<searchableSurfaceModifier> clone() const
{
notImplemented("autoPtr<searchableSurfaceModifier> clone() const");
return autoPtr<searchableSurfaceModifier>(NULL);
}
//- Destructor
virtual ~autoPatch();
// Member Functions
//- Apply this selector
virtual bool modify(const labelList& regions, searchableSurface&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace searchableSurfaceModifiers
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,390 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 3 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, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "cut.H"
#include "addToRunTimeSelectionTable.H"
#include "searchableSurfaces.H"
#include "triSurfaceMesh.H"
#include "searchableBox.H"
#include "searchableRotatedBox.H"
#include "surfaceIntersection.H"
#include "intersectedSurface.H"
#include "edgeIntersections.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace searchableSurfaceModifiers
{
defineTypeNameAndDebug(cut, 0);
addToRunTimeSelectionTable(searchableSurfaceModifier, cut, dictionary);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::searchableSurfaceModifiers::cut::triangulate
(
const faceList& fcs,
pointField& pts,
triSurface& cutSurf
) const
{
label nTris = 0;
forAll(fcs, i)
{
nTris += fcs[i].size()-2;
}
DynamicList<labelledTri> tris(nTris);
forAll(fcs, i)
{
const face& f = fcs[i];
// Triangulate around vertex 0
for (label fp = 1; fp < f.size()-1; fp++)
{
tris.append(labelledTri(f[0], f[fp], f[f.fcIndex(fp)], i));
}
}
geometricSurfacePatchList patches(fcs.size());
forAll(patches, patchI)
{
patches[patchI] = geometricSurfacePatch
(
"",
"patch" + Foam::name(patchI),
patchI
);
}
cutSurf = triSurface(tris.xfer(), patches, pts.xfer());
}
Foam::triSurface& Foam::searchableSurfaceModifiers::cut::triangulate
(
const searchableSurface& cutter,
triSurface& cutSurf
) const
{
if (isA<searchableBox>(cutter))
{
const searchableBox& bb = refCast<const searchableBox>(cutter);
pointField pts(bb.points());
triangulate(treeBoundBox::faces, pts, cutSurf);
return cutSurf;
}
else if (isA<searchableRotatedBox>(cutter))
{
const searchableRotatedBox& bb =
refCast<const searchableRotatedBox>(cutter);
pointField pts(bb.points());
triangulate(treeBoundBox::faces, pts, cutSurf);
return cutSurf;
}
else if (isA<triSurfaceMesh>(cutter))
{
return const_cast<triSurfaceMesh&>
(
refCast<const triSurfaceMesh>(cutter)
);
}
else
{
FatalErrorIn
(
"searchableSurfaceModifiers::cut::triangulate\n"
"(\n"
" const searchableSurface&,\n"
" triSurface&\n"
")"
) << "Triangulation only supported for triSurfaceMesh, searchableBox"
<< ", not for surface " << cutter.name()
<< " of type " << cutter.type()
<< exit(FatalError);
return const_cast<triSurfaceMesh&>
(
refCast<const triSurfaceMesh>(cutter)
);
}
}
// Keep on shuffling surface points until no more degenerate intersections.
// Moves both surfaces and updates set of edge cuts.
bool Foam::searchableSurfaceModifiers::cut::intersectSurfaces
(
triSurface& surf1,
edgeIntersections& edgeCuts1,
triSurface& surf2,
edgeIntersections& edgeCuts2
) const
{
bool hasMoved1 = false;
bool hasMoved2 = false;
for (label iter = 0; iter < 10; iter++)
{
Info<< "Determining intersections of surf1 edges with surf2"
<< " faces" << endl;
// Determine surface1 edge intersections. Allow surface to be moved.
// Number of iterations needed to resolve degenerates
label nIters1 = 0;
{
triSurfaceSearch querySurf2(surf2);
scalarField surf1PointTol
(
1E-6*edgeIntersections::minEdgeLength(surf1)
);
// Determine raw intersections
edgeCuts1 = edgeIntersections
(
surf1,
querySurf2,
surf1PointTol
);
// Shuffle a bit to resolve degenerate edge-face hits
{
pointField points1(surf1.points());
nIters1 =
edgeCuts1.removeDegenerates
(
5, // max iterations
surf1,
querySurf2,
surf1PointTol,
points1 // work array
);
if (nIters1 != 0)
{
// Update geometric quantities
surf1.movePoints(points1);
hasMoved1 = true;
}
}
}
Info<< "Determining intersections of surf2 edges with surf1"
<< " faces" << endl;
label nIters2 = 0;
{
triSurfaceSearch querySurf1(surf1);
scalarField surf2PointTol
(
1E-6*edgeIntersections::minEdgeLength(surf2)
);
// Determine raw intersections
edgeCuts2 = edgeIntersections
(
surf2,
querySurf1,
surf2PointTol
);
// Shuffle a bit to resolve degenerate edge-face hits
{
pointField points2(surf2.points());
nIters2 =
edgeCuts2.removeDegenerates
(
5, // max iterations
surf2,
querySurf1,
surf2PointTol,
points2 // work array
);
if (nIters2 != 0)
{
// Update geometric quantities
surf2.movePoints(points2);
hasMoved2 = true;
}
}
}
if (nIters1 == 0 && nIters2 == 0)
{
//Info<< "** Resolved all intersections to be proper"
// << "edge-face pierce" << endl;
break;
}
}
//if (hasMoved1)
//{
// fileName newFile("surf1.ftr");
// Info<< "Surface 1 has been moved. Writing to " << newFile
// << endl;
// surf1.write(newFile);
//}
//
//if (hasMoved2)
//{
// fileName newFile("surf2.ftr");
// Info<< "Surface 2 has been moved. Writing to " << newFile
// << endl;
// surf2.write(newFile);
//}
return hasMoved1 || hasMoved2;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::searchableSurfaceModifiers::cut::cut
(
const searchableSurfaces& geometry,
const dictionary& dict
)
:
searchableSurfaceModifier(geometry, dict),
cutterNames_(dict_.lookup("cutters"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::searchableSurfaceModifiers::cut::~cut()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::searchableSurfaceModifiers::cut::modify
(
const labelList& regions,
searchableSurface& geom
) const
{
triSurface& surf = refCast<triSurfaceMesh>(geom);
bool changed = false;
// Find the surfaces to cut with
forAll(cutterNames_, cutNameI)
{
labelList geomIDs =
findStrings(cutterNames_[cutNameI], geometry_.names());
forAll(geomIDs, j)
{
label geomI = geomIDs[j];
const searchableSurface& cutter = geometry_[geomI];
// Triangulate
triSurface work;
triSurface& cutSurf = triangulate(cutter, work);
// Determine intersection (with perturbation)
edgeIntersections edge1Cuts;
edgeIntersections edge2Cuts;
intersectSurfaces
(
surf,
edge1Cuts,
cutSurf,
edge2Cuts
);
// Determine intersection edges
surfaceIntersection inter(surf, edge1Cuts, cutSurf, edge2Cuts);
// Use intersection edges to cut up faces. (does all the hard work)
intersectedSurface surf3(surf, true, inter);
// Mark triangles based on whether they are inside or outside
List<volumeType> volTypes;
cutter.getVolumeType(surf3.faceCentres(), volTypes);
label nInside = 0;
forAll(volTypes, i)
{
if (volTypes[i] == volumeType::INSIDE)
{
nInside++;
}
}
// Add a patch for inside the box
if (nInside > 0 && surf3.patches().size() > 0)
{
geometricSurfacePatchList newPatches(surf3.patches());
label sz = newPatches.size();
newPatches.setSize(sz+1);
newPatches[sz] = geometricSurfacePatch
(
newPatches[sz-1].geometricType(),
newPatches[sz-1].name() + "_inside",
newPatches[sz-1].index()
);
Info<< "Moving " << nInside << " out of " << surf3.size()
<< " triangles to region "
<< newPatches[sz].name() << endl;
List<labelledTri> newTris(surf3);
forAll(volTypes, i)
{
if (volTypes[i] == volumeType::INSIDE)
{
newTris[i].region() = sz;
}
}
pointField newPoints(surf3.points());
surf = triSurface(newTris.xfer(), newPatches, newPoints.xfer());
changed = true;
}
}
}
return changed;
}
// ************************************************************************* //

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 3 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, see <http://www.gnu.org/licenses/>.
Class
Foam::searchableSurfaceModifier::cut
Description
Patchify triangles based on orientation w.r.t other (triangulated or
triangulatable) surfaces
SourceFiles
cut.C
\*---------------------------------------------------------------------------*/
#ifndef cut_H
#define cut_H
#include "searchableSurfaceModifier.H"
#include "wordReList.H"
#include "faceList.H"
#include "pointField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class edgeIntersections;
namespace searchableSurfaceModifiers
{
/*---------------------------------------------------------------------------*\
Class cut Declaration
\*---------------------------------------------------------------------------*/
class cut
:
public searchableSurfaceModifier
{
// Private data
//- Name of surfaces to cut with
const wordReList cutterNames_;
// Private Member Functions
//- Triangulate faces around 0th vertex
void triangulate(const faceList&, pointField&, triSurface&) const;
//- Triangulate searchableSurface (currently only supported for
// searchableBox and triSurfaceMesh)
triSurface& triangulate(const searchableSurface&, triSurface&) const;
//- Intersect surfaces. Perturb to avoid degenerates.
bool intersectSurfaces
(
triSurface& surf1,
edgeIntersections& edgeCuts1,
triSurface& surf2,
edgeIntersections& edgeCuts2
) const;
public:
//- Runtime type information
TypeName("cut");
// Constructors
//- Construct from dictionary
cut(const searchableSurfaces&, const dictionary&);
//- Clone
autoPtr<searchableSurfaceModifier> clone() const
{
notImplemented("autoPtr<searchableSurfaceModifier> clone() const");
return autoPtr<searchableSurfaceModifier>(NULL);
}
//- Destructor
virtual ~cut();
// Member Functions
//- Apply this selector
virtual bool modify(const labelList& regions, searchableSurface&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace searchableSurfaceModifiers
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 3 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, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "searchableSurfaceModifier.H"
#include "triSurface.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(searchableSurfaceModifier, 0);
defineRunTimeSelectionTable(searchableSurfaceModifier, dictionary);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::searchableSurfaceModifier::searchableSurfaceModifier
(
const searchableSurfaces& geometry,
const dictionary& dict
)
:
geometry_(geometry),
dict_(dict)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::searchableSurfaceModifier::~searchableSurfaceModifier()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::searchableSurfaceModifier>
Foam::searchableSurfaceModifier::New
(
const word& type,
const searchableSurfaces& geometry,
const dictionary& dict
)
{
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(type);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"searchableSurfaceModifier::New"
"(const word&, const searchableSurfaces&, const dictionary&)"
) << "Unknown searchableSurfaceModifier type "
<< type << nl << nl
<< "Valid searchableSurfaceModifier types : " << endl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<searchableSurfaceModifier>(cstrIter()(geometry, dict));
}
// ************************************************************************* //

View File

@ -0,0 +1,134 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 3 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, see <http://www.gnu.org/licenses/>.
Class
Foam::searchableSurfaceModifier
Description
Changing a surface
SourceFiles
searchableSurfaceModifier.C
\*---------------------------------------------------------------------------*/
#ifndef searchableSurfaceModifier_H
#define searchableSurfaceModifier_H
#include "dictionary.H"
#include "typeInfo.H"
#include "runTimeSelectionTables.H"
#include "autoPtr.H"
#include "labelList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class triSurface;
class searchableSurface;
class searchableSurfaces;
/*---------------------------------------------------------------------------*\
Class searchableSurfaceModifier Declaration
\*---------------------------------------------------------------------------*/
class searchableSurfaceModifier
{
protected:
// Protected data
const searchableSurfaces& geometry_;
//- Input dictionary
const dictionary dict_;
public:
//- Runtime type information
TypeName("searchableSurfaceModifier");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
searchableSurfaceModifier,
dictionary,
(
const searchableSurfaces& geometry,
const dictionary& dict
),
(geometry, dict)
);
// Constructors
//- Construct from dictionary
searchableSurfaceModifier(const searchableSurfaces&, const dictionary&);
//- Clone
autoPtr<searchableSurfaceModifier> clone() const
{
notImplemented("autoPtr<searchableSurfaceModifier> clone() const");
return autoPtr<searchableSurfaceModifier>(NULL);
}
// Selectors
//- Return a reference to the selected searchableSurfaceModifier
static autoPtr<searchableSurfaceModifier> New
(
const word& type,
const searchableSurfaces&,
const dictionary& dict
);
//- Destructor
virtual ~searchableSurfaceModifier();
// Member Functions
//- Do any operation on surface. Return true if anything changed
virtual bool modify(const labelList&, searchableSurface&) const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,169 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 3 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, see <http://www.gnu.org/licenses/>.
Application
surfacePatch
Description
Patches (regionises) a surface using a user-selectable method.
The current methods are either based on a geometric feature angle
(a replacement for the surfaceAutoPatch functionality) or on intersecting
a set of searchableSurfaces - this will re-triangulate the intersecting
triangles and regonise the resulting triangles according to being
inside/outside the surface.
\*---------------------------------------------------------------------------*/
#include "triSurface.H"
#include "argList.H"
#include "Time.H"
#include "triSurfaceMesh.H"
#include "searchableSurfaces.H"
#include "searchableSurfaceModifier.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::validArgs.clear();
argList::noParallel();
#include "addDictOption.H"
#include "setRootCase.H"
#include "createTime.H"
const word dictName("surfacePatchDict");
#include "setSystemRunTimeDictionaryIO.H"
const IOdictionary meshDict(dictIO);
// Read geometry
// ~~~~~~~~~~~~~
searchableSurfaces allGeometry
(
IOobject
(
"abc", // dummy name
runTime.constant(), // instance
triSurfaceMesh::meshSubDir, // local
runTime, // registry
IOobject::MUST_READ,
IOobject::NO_WRITE
),
meshDict.subDict("geometry"),
meshDict.lookupOrDefault("singleRegionName", true)
);
const dictionary& surfacesDict = meshDict.subDict("surfaces");
forAllConstIter(dictionary, surfacesDict, surfacesIter)
{
if (surfacesIter().isDict())
{
const word& surfName = surfacesIter().keyword();
const dictionary& surfDict = surfacesIter().dict();
// Look up surface
searchableSurface& surf = allGeometry[surfName];
bool changed = false;
// Check for modifier on global level
if (surfDict.found("type"))
{
autoPtr<searchableSurfaceModifier> modifier
(
searchableSurfaceModifier::New
(
surfDict.lookup("type"),
allGeometry,
surfDict
)
);
if (modifier().modify(identity(surf.regions().size()), surf))
{
changed = true;
}
}
// Check for modifier on a per-region level
if (surfDict.found("regions"))
{
const dictionary& regionsDict = surfDict.subDict("regions");
forAllConstIter(dictionary, regionsDict, regionsIter)
{
const dictionary& regionDict = regionsIter().dict();
const keyType& regionName = regionsIter().keyword();
autoPtr<searchableSurfaceModifier> modifier
(
searchableSurfaceModifier::New
(
regionDict.lookup("type"),
allGeometry,
regionDict
)
);
labelList regionIDs =
findStrings(regionName, surf.regions());
if (modifier().modify(regionIDs, surf))
{
changed = true;
}
}
}
if (changed)
{
const fileName name(surf.name());
surf.rename(name.lessExt() + "_patched." + name.ext());
Info<< "Writing repatched surface " << name << " to "
<< surf.name() << nl << endl;
surf.write();
}
else
{
Info<< "Surface " << surf.name() << " unchanged" << nl << endl;
}
}
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,69 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object createPatchDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
geometry
{
box
{
type searchableRotatedBox;
// box rotated 45 degrees around z axis
span (1 1 1);
origin (0 0 0);
e1 (1 1 0);
e3 (0 0 1);
}
singleTri.obj
{
type triSurfaceMesh;
}
unitCube_me.stl
{
type triSurfaceMesh;
}
};
surfaces
{
unitCube_me.stl
{
regions
{
// Divide region 'maxZ' into multiple regions according to
// a geometric feature angle
maxZ
{
type autoPatch;
featureAngle 60;
}
}
}
singleTri.obj
{
// Regionise surface according to triangles (after cutting) being
// inside or outside the 'box' geometry
type cut;
cutters (box);
}
}
// ************************************************************************* //