mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
STYLE: split up cuttingPlane source files
This commit is contained in:
@ -19,7 +19,9 @@ sampledSet/uniform/uniformSet.C
|
||||
sampledSet/array/arraySet.C
|
||||
sampledSet/shortestPath/shortestPathSet.C
|
||||
|
||||
surface/cuttingPlane/cuttingPlane.C
|
||||
surface/cutting/cuttingPlane.C
|
||||
surface/cutting/cuttingPlaneCuts.C
|
||||
surface/cutting/cuttingPlaneWalk.C
|
||||
surface/distanceSurface/distanceSurface.C
|
||||
surface/isoSurface/isoSurface.C
|
||||
surface/isoSurface/isoSurfaceCell.C
|
||||
|
||||
181
src/sampling/surface/cutting/cuttingPlane.C
Normal file
181
src/sampling/surface/cutting/cuttingPlane.C
Normal file
@ -0,0 +1,181 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2018 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 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 "cuttingPlane.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
int Foam::cuttingPlane::debug(Foam::debug::debugSwitch("cuttingPlane", 0));
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane(const plane& pln)
|
||||
:
|
||||
plane(pln)
|
||||
{}
|
||||
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const bitSet& cellIdLabels
|
||||
)
|
||||
:
|
||||
plane(pln)
|
||||
{
|
||||
performCut(mesh, triangulate, cellIdLabels);
|
||||
}
|
||||
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
bitSet&& cellIdLabels
|
||||
)
|
||||
:
|
||||
plane(pln)
|
||||
{
|
||||
performCut(mesh, triangulate, cellIdLabels);
|
||||
}
|
||||
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& cellIdLabels
|
||||
)
|
||||
:
|
||||
plane(pln)
|
||||
{
|
||||
performCut(mesh, triangulate, cellIdLabels);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::cuttingPlane::performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
bitSet&& cellIdLabels
|
||||
)
|
||||
{
|
||||
MeshStorage::clear();
|
||||
meshCells_.clear();
|
||||
|
||||
// Pre-populate with restriction
|
||||
bitSet cellCuts(std::move(cellIdLabels));
|
||||
|
||||
if (cellCuts.size())
|
||||
{
|
||||
cellCuts.resize(mesh.nCells());
|
||||
}
|
||||
|
||||
// For each mesh point, the encoded side (0,1,2) of the plane
|
||||
PackedList<2> sides;
|
||||
|
||||
// Determine cells that are (likely) cut
|
||||
// - some ambiguity when plane is exactly between cells
|
||||
const label nFaceCuts = calcCellCuts(mesh, sides, cellCuts);
|
||||
|
||||
// Find closed loop from cell cuts
|
||||
walkCellCuts(mesh, cellCuts, sides, triangulate, nFaceCuts);
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const bitSet& cellIdLabels
|
||||
)
|
||||
{
|
||||
bitSet subsetCells(cellIdLabels);
|
||||
|
||||
performCut(mesh, triangulate, std::move(subsetCells));
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& cellIdLabels
|
||||
)
|
||||
{
|
||||
bitSet subsetCells;
|
||||
|
||||
if (notNull(cellIdLabels))
|
||||
{
|
||||
// Pre-populate with restriction
|
||||
subsetCells.resize(mesh.nCells());
|
||||
subsetCells.set(cellIdLabels);
|
||||
}
|
||||
|
||||
performCut(mesh, triangulate, std::move(subsetCells));
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::remapFaces(const labelUList& faceMap)
|
||||
{
|
||||
if (notNull(faceMap) && !faceMap.empty())
|
||||
{
|
||||
MeshStorage::remapFaces(faceMap);
|
||||
|
||||
List<label> remappedCells(faceMap.size());
|
||||
forAll(faceMap, facei)
|
||||
{
|
||||
remappedCells[facei] = meshCells_[faceMap[facei]];
|
||||
}
|
||||
meshCells_.transfer(remappedCells);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::cuttingPlane::operator=(const cuttingPlane& rhs)
|
||||
{
|
||||
if (this == &rhs)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Attempted assignment to self"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
static_cast<MeshStorage&>(*this) = rhs;
|
||||
static_cast<plane&>(*this) = rhs;
|
||||
meshCells_ = rhs.meshCells();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -30,10 +30,6 @@ Description
|
||||
No attempt at resolving degenerate cases.
|
||||
Since the cut faces can be quite ugly, they will often be triangulated.
|
||||
|
||||
Note
|
||||
When the cutting plane coincides with a mesh face, the cell edge on the
|
||||
positive side of the plane is taken.
|
||||
|
||||
SourceFiles
|
||||
cuttingPlane.C
|
||||
|
||||
@ -43,7 +39,6 @@ SourceFiles
|
||||
#define cuttingPlane_H
|
||||
|
||||
#include "plane.H"
|
||||
#include "pointField.H"
|
||||
#include "faceList.H"
|
||||
#include "bitSet.H"
|
||||
#include "MeshedSurface.H"
|
||||
@ -79,26 +74,31 @@ class cuttingPlane
|
||||
|
||||
//- Determine cut cells, possibly restricted to a list of cells
|
||||
//
|
||||
// \param sides [out] For each mesh point, the encoded side of the
|
||||
// plane (0=BACK, 1=ONPLANE, 2=FRONT).
|
||||
// \param cellCuts [in,out] On input an empty set (ie, no restriction)
|
||||
// or subsetted cells. On output, the cells cut according to the
|
||||
// planeSides detection.
|
||||
// plane-sides detection.
|
||||
//
|
||||
// \return number of faces cut
|
||||
label calcCellCuts
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const PackedList<2>& planeSides,
|
||||
PackedList<2>& sides,
|
||||
bitSet& cellCuts
|
||||
);
|
||||
|
||||
//- Walk the cell cuts to create faces
|
||||
//
|
||||
// \param planeSides [in] Used to determine edge cuts
|
||||
// \param cellCuts [in] The cells to walk.
|
||||
// \param sides [in] For each mesh point, the encoded side of the
|
||||
// plane (0=BACK, 1=ONPLANE, 2=FRONT), which is used to determine
|
||||
// the edge cuts
|
||||
void walkCellCuts
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bitSet& cellCuts,
|
||||
const PackedList<2>& planeSides,
|
||||
const PackedList<2>& sides,
|
||||
const bool triangulate,
|
||||
const label nFaceCuts = 0
|
||||
);
|
||||
@ -115,20 +115,20 @@ protected:
|
||||
// Protected Member Functions
|
||||
|
||||
//- Cut mesh with existing plane, restricted to a list of cells
|
||||
// Reclaim memory for cellIdLabels
|
||||
void performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const bitSet& cellSelectionMask = bitSet()
|
||||
bitSet&& cellIdLabels
|
||||
);
|
||||
|
||||
//- Cut mesh with existing plane, restricted to a list of cells
|
||||
// Reclaim memory for cellSelectionMask
|
||||
void performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
bitSet&& cellSelectionMask
|
||||
const bitSet& cellIdLabels = bitSet()
|
||||
);
|
||||
|
||||
//- Cut mesh with existing plane, restricted to a list of cells
|
||||
196
src/sampling/surface/cutting/cuttingPlaneCuts.C
Normal file
196
src/sampling/surface/cutting/cuttingPlaneCuts.C
Normal file
@ -0,0 +1,196 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2018 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 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 "cuttingPlane.H"
|
||||
#include "volFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
// Check for face/plane intersection based on crossings
|
||||
// Took (-1,0,+1) from plane::sign and packed as (0,1,2).
|
||||
// Now use for left shift to obtain (1,2,4).
|
||||
//
|
||||
// Test accumulated value for an intersection with the plane.
|
||||
inline bool intersectsFace
|
||||
(
|
||||
const PackedList<2>& sides,
|
||||
const labelUList& indices
|
||||
)
|
||||
{
|
||||
unsigned accum = 0u;
|
||||
|
||||
for (const label pointi : indices)
|
||||
{
|
||||
accum |= (1u << sides[pointi]);
|
||||
}
|
||||
|
||||
// Accumulated value 3,5,6,7 indicates an intersection
|
||||
return (accum == 3 || accum >= 5);
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::cuttingPlane::calcCellCuts
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
PackedList<2>& sides,
|
||||
bitSet& cellCuts
|
||||
)
|
||||
{
|
||||
const faceList& faces = mesh.faces();
|
||||
const pointField& pts = mesh.points();
|
||||
|
||||
const label nCells = mesh.nCells();
|
||||
const label nFaces = mesh.nFaces();
|
||||
const label nInternFaces = mesh.nInternalFaces();
|
||||
|
||||
|
||||
// Classify sides of plane (0=BACK, 1=ONPLANE, 2=FRONT) for each point
|
||||
{
|
||||
const plane& pln = *this;
|
||||
const label len = pts.size();
|
||||
|
||||
sides.resize(len);
|
||||
|
||||
// From signed (-1,0,+1) to (0,1,2) for PackedList
|
||||
for (label i=0; i < len; ++i)
|
||||
{
|
||||
sides.set(i, unsigned(1 + pln.sign(pts[i], SMALL)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Detect cells cuts from the face cuts
|
||||
|
||||
label nFaceCuts = 0;
|
||||
|
||||
// 1st face cut of cell
|
||||
bitSet hasCut1(nCells);
|
||||
|
||||
// 2nd face cut of cell
|
||||
bitSet hasCut2(nCells);
|
||||
|
||||
for (label facei = 0; facei < nInternFaces; ++facei)
|
||||
{
|
||||
if (intersectsFace(sides, faces[facei]))
|
||||
{
|
||||
const label own = mesh.faceOwner()[facei];
|
||||
const label nei = mesh.faceNeighbour()[facei];
|
||||
|
||||
++nFaceCuts;
|
||||
|
||||
if (!hasCut1.set(own))
|
||||
{
|
||||
hasCut2.set(own);
|
||||
}
|
||||
if (!hasCut1.set(nei))
|
||||
{
|
||||
hasCut2.set(nei);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (label facei = nInternFaces; facei < nFaces; ++facei)
|
||||
{
|
||||
if (intersectsFace(sides, faces[facei]))
|
||||
{
|
||||
const label own = mesh.faceOwner()[facei];
|
||||
|
||||
++nFaceCuts;
|
||||
|
||||
if (!hasCut1.set(own))
|
||||
{
|
||||
hasCut2.set(own);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hasCut1.clearStorage(); // Not needed now
|
||||
|
||||
if (cellCuts.size())
|
||||
{
|
||||
cellCuts.resize(nCells); // safety
|
||||
cellCuts &= hasCut2; // restrict to cell subset
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<<"detected " << cellCuts.count() << "/" << nCells
|
||||
<< " cells cut, subsetted from "
|
||||
<< hasCut2.count() << "/" << nCells << " cells." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cellCuts = std::move(hasCut2);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<<"detected " << cellCuts.count() << "/" << nCells
|
||||
<< " cells cut." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (debug && isA<fvMesh>(mesh))
|
||||
{
|
||||
const fvMesh& fvm = dynamicCast<const fvMesh&>(mesh);
|
||||
|
||||
volScalarField cCuts
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cuttingPlane.cellCuts",
|
||||
fvm.time().timeName(),
|
||||
fvm.time(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
fvm,
|
||||
dimensionedScalar(dimless, Zero)
|
||||
);
|
||||
|
||||
auto& cCutsFld = cCuts.primitiveFieldRef();
|
||||
|
||||
for (const label celli : cellCuts)
|
||||
{
|
||||
cCutsFld[celli] = 1;
|
||||
}
|
||||
|
||||
Pout<< "Writing cut types:" << cCuts.objectPath() << endl;
|
||||
cCuts.write();
|
||||
}
|
||||
|
||||
|
||||
return nFaceCuts;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -2,8 +2,8 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
|
||||
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -24,17 +24,9 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "cuttingPlane.H"
|
||||
#include "fvMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "meshTools.H"
|
||||
#include "edgeHashes.H"
|
||||
#include "HashOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
int Foam::cuttingPlane::debug(Foam::debug::debugSwitch("cuttingPlane", 0));
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
@ -55,172 +47,11 @@ namespace Foam
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Classify sides of plane (0=BACK, 1=ONPLANE, 2=FRONT) for each point
|
||||
inline PackedList<2> classifySides(const plane& pln, const pointField& pts)
|
||||
{
|
||||
const label len = pts.size();
|
||||
|
||||
PackedList<2> output(len);
|
||||
|
||||
// From signed (-1,0,+1) to (0,1,2) for PackedList
|
||||
for (label i=0; i < len; ++i)
|
||||
{
|
||||
output.set(i, unsigned(1 + pln.sign(pts[i], SMALL)));
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
// Check for face/plane intersection based on crossings
|
||||
// Took (-1,0,+1) from plane::sign and packed as (0,1,2).
|
||||
// Now use for left shift to obtain (1,2,4).
|
||||
//
|
||||
// Test accumulated value for an intersection with the plane.
|
||||
inline bool intersectsFace
|
||||
(
|
||||
const PackedList<2>& sides,
|
||||
const labelUList& indices
|
||||
)
|
||||
{
|
||||
unsigned accum = 0u;
|
||||
|
||||
for (const label pointi : indices)
|
||||
{
|
||||
accum |= (1u << sides[pointi]);
|
||||
}
|
||||
|
||||
// Accumulated value 3,5,6,7 indicates an intersection
|
||||
return (accum == 3 || accum >= 5);
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::cuttingPlane::calcCellCuts
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const PackedList<2>& sides,
|
||||
bitSet& cellCuts
|
||||
)
|
||||
{
|
||||
const faceList& faces = mesh.faces();
|
||||
|
||||
const label nCells = mesh.nCells();
|
||||
const label nFaces = mesh.nFaces();
|
||||
const label nInternFaces = mesh.nInternalFaces();
|
||||
|
||||
// Detect cells cuts from the face cuts
|
||||
|
||||
label nFaceCuts = 0;
|
||||
|
||||
// 1st face cut of cell
|
||||
bitSet hasCut1(nCells);
|
||||
|
||||
// 2nd face cut of cell
|
||||
bitSet hasCut2(nCells);
|
||||
|
||||
for (label facei = 0; facei < nInternFaces; ++facei)
|
||||
{
|
||||
if (intersectsFace(sides, faces[facei]))
|
||||
{
|
||||
const label own = mesh.faceOwner()[facei];
|
||||
const label nei = mesh.faceNeighbour()[facei];
|
||||
|
||||
++nFaceCuts;
|
||||
|
||||
if (!hasCut1.set(own))
|
||||
{
|
||||
hasCut2.set(own);
|
||||
}
|
||||
if (!hasCut1.set(nei))
|
||||
{
|
||||
hasCut2.set(nei);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (label facei = nInternFaces; facei < nFaces; ++facei)
|
||||
{
|
||||
if (intersectsFace(sides, faces[facei]))
|
||||
{
|
||||
const label own = mesh.faceOwner()[facei];
|
||||
|
||||
++nFaceCuts;
|
||||
|
||||
if (!hasCut1.set(own))
|
||||
{
|
||||
hasCut2.set(own);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hasCut1.clearStorage(); // Not needed now
|
||||
|
||||
if (cellCuts.size())
|
||||
{
|
||||
cellCuts.resize(nCells); // safety
|
||||
cellCuts &= hasCut2; // restrict to cell subset
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<<"detected " << cellCuts.count() << "/" << nCells
|
||||
<< " cells cut, subsetted from "
|
||||
<< hasCut2.count() << "/" << nCells << " cells." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cellCuts = std::move(hasCut2);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<<"detected " << cellCuts.count() << "/" << nCells
|
||||
<< " cells cut." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (debug && isA<fvMesh>(mesh))
|
||||
{
|
||||
const fvMesh& fvm = dynamicCast<const fvMesh&>(mesh);
|
||||
|
||||
volScalarField debugField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cuttingPlane.cellCuts",
|
||||
fvm.time().timeName(),
|
||||
fvm.time(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
fvm,
|
||||
dimensionedScalar(dimless, Zero)
|
||||
);
|
||||
|
||||
auto& debugFld = debugField.primitiveFieldRef();
|
||||
|
||||
for (const label celli : cellCuts)
|
||||
{
|
||||
debugFld[celli] = 1;
|
||||
}
|
||||
|
||||
Pout<< "Writing cut types:"
|
||||
<< debugField.objectPath() << endl;
|
||||
|
||||
debugField.write();
|
||||
}
|
||||
|
||||
|
||||
return nFaceCuts;
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::walkCellCuts
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
@ -325,7 +156,7 @@ void Foam::cuttingPlane::walkCellCuts
|
||||
{
|
||||
edge e(f.faceEdge(fp));
|
||||
|
||||
// Action #1: detect edge intersection and orient edge
|
||||
// Action #1: orient edge and detect intersection
|
||||
if (!intersectEdgeOrient(sides, e))
|
||||
{
|
||||
continue;
|
||||
@ -356,8 +187,8 @@ void Foam::cuttingPlane::walkCellCuts
|
||||
// Expected id for the cut point
|
||||
cutPointId = dynCutPoints.size();
|
||||
|
||||
const point& p0 = points[e[0]];
|
||||
const point& p1 = points[e[1]];
|
||||
const point& p0 = points[e.first()];
|
||||
const point& p1 = points[e.last()];
|
||||
|
||||
// Action #2: edge cut alpha
|
||||
const scalar alpha =
|
||||
@ -365,41 +196,41 @@ void Foam::cuttingPlane::walkCellCuts
|
||||
|
||||
if (alpha < SMALL)
|
||||
{
|
||||
// -> equal(alpha, 0) with more tolerance
|
||||
pointCutType |= 0x1; // Cut at 0 (first)
|
||||
|
||||
if (endPoints.insert(e[0], cutPointId))
|
||||
const label endp = e.first();
|
||||
|
||||
if (endPoints.insert(endp, cutPointId))
|
||||
{
|
||||
localEndPoints.insert(e[0]);
|
||||
localEndPoints.insert(endp);
|
||||
dynCutPoints.append(p0);
|
||||
}
|
||||
else
|
||||
{
|
||||
cutPointId = endPoints[e[0]];
|
||||
cutPointId = endPoints[endp];
|
||||
}
|
||||
|
||||
pointCutType |= 0x1; // Cut at 0
|
||||
}
|
||||
else if (alpha >= (1.0 - SMALL))
|
||||
{
|
||||
// -> equal(alpha, 1) with more tolerance
|
||||
pointCutType |= 0x2; // Cut at 1 (last)
|
||||
|
||||
if (endPoints.insert(e[1], cutPointId))
|
||||
const label endp = e.last();
|
||||
|
||||
if (endPoints.insert(endp, cutPointId))
|
||||
{
|
||||
localEndPoints.insert(e[1]);
|
||||
localEndPoints.insert(endp);
|
||||
dynCutPoints.append(p1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cutPointId = endPoints[e[1]];
|
||||
cutPointId = endPoints[endp];
|
||||
}
|
||||
|
||||
pointCutType |= 0x2; // Cut at 1
|
||||
}
|
||||
else
|
||||
{
|
||||
dynCutPoints.append((1-alpha)*p0 + alpha*p1);
|
||||
|
||||
pointCutType |= 0x4; // Cut between
|
||||
|
||||
dynCutPoints.append((1-alpha)*p0 + alpha*p1);
|
||||
}
|
||||
|
||||
// Introduce new edge cut point
|
||||
@ -565,152 +396,4 @@ void Foam::cuttingPlane::walkCellCuts
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane(const plane& pln)
|
||||
:
|
||||
plane(pln)
|
||||
{}
|
||||
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const bitSet& cellIdLabels
|
||||
)
|
||||
:
|
||||
plane(pln)
|
||||
{
|
||||
performCut(mesh, triangulate, cellIdLabels);
|
||||
}
|
||||
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
bitSet&& cellIdLabels
|
||||
)
|
||||
:
|
||||
plane(pln)
|
||||
{
|
||||
performCut(mesh, triangulate, cellIdLabels);
|
||||
}
|
||||
|
||||
|
||||
Foam::cuttingPlane::cuttingPlane
|
||||
(
|
||||
const plane& pln,
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& cellIdLabels
|
||||
)
|
||||
:
|
||||
plane(pln)
|
||||
{
|
||||
performCut(mesh, triangulate, cellIdLabels);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::cuttingPlane::performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
bitSet&& cellIdLabels
|
||||
)
|
||||
{
|
||||
MeshStorage::clear();
|
||||
meshCells_.clear();
|
||||
|
||||
// Pre-populate with restriction
|
||||
bitSet cellCuts(std::move(cellIdLabels));
|
||||
|
||||
if (cellCuts.size())
|
||||
{
|
||||
cellCuts.resize(mesh.nCells());
|
||||
}
|
||||
|
||||
// Classification of points with respect to the plane
|
||||
PackedList<2> sides = classifySides(*this, mesh.points());
|
||||
|
||||
// Determine cells that are (likely) cut
|
||||
// - some ambiguity when plane is exactly between cells
|
||||
const label nFaceCuts = calcCellCuts(mesh, sides, cellCuts);
|
||||
|
||||
// Find closed loop from cell cuts
|
||||
walkCellCuts(mesh, cellCuts, sides, triangulate, nFaceCuts);
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const bitSet& cellIdLabels
|
||||
)
|
||||
{
|
||||
bitSet subsetCells(cellIdLabels);
|
||||
|
||||
performCut(mesh, triangulate, std::move(subsetCells));
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::performCut
|
||||
(
|
||||
const primitiveMesh& mesh,
|
||||
const bool triangulate,
|
||||
const labelUList& cellIdLabels
|
||||
)
|
||||
{
|
||||
bitSet subsetCells;
|
||||
|
||||
if (notNull(cellIdLabels))
|
||||
{
|
||||
// Pre-populate with restriction
|
||||
subsetCells.resize(mesh.nCells());
|
||||
subsetCells.set(cellIdLabels);
|
||||
}
|
||||
|
||||
performCut(mesh, triangulate, std::move(subsetCells));
|
||||
}
|
||||
|
||||
|
||||
void Foam::cuttingPlane::remapFaces(const labelUList& faceMap)
|
||||
{
|
||||
if (notNull(faceMap) && !faceMap.empty())
|
||||
{
|
||||
MeshStorage::remapFaces(faceMap);
|
||||
|
||||
List<label> newCutCells(faceMap.size());
|
||||
forAll(faceMap, facei)
|
||||
{
|
||||
newCutCells[facei] = meshCells_[faceMap[facei]];
|
||||
}
|
||||
meshCells_.transfer(newCutCells);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::cuttingPlane::operator=(const cuttingPlane& rhs)
|
||||
{
|
||||
if (this == &rhs)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Attempted assignment to self"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
static_cast<MeshStorage&>(*this) = rhs;
|
||||
static_cast<plane&>(*this) = rhs;
|
||||
meshCells_ = rhs.meshCells();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user