Commit 88876e46 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: better handling of various face types in MeshedSurface (issue #294)

- ensure that MeshedSurface and UnsortedMeshedSurface can also work
  with labelledTri faces.

- nTriangles() convenience method for meshed surfaces

- MeshedSurface::addZonesToFaces() method to copy zone information
  into the labelledTri per-face region storage.
  The goal is to replace the triSurface reading routines with
  run-time selectable ones from surfMesh.
parent a32eff4e
......@@ -837,6 +837,61 @@ bool Foam::MeshedSurface<Face>::checkFaces
}
template<class Face>
Foam::label Foam::MeshedSurface<Face>::nTriangles() const
{
return nTriangles
(
const_cast<List<label>&>(List<label>::null())
);
}
template<class Face>
Foam::label Foam::MeshedSurface<Face>::nTriangles
(
List<label>& faceMap
) const
{
label nTri = 0;
const List<Face>& faceLst = surfFaces();
// Count triangles needed
forAll(faceLst, facei)
{
nTri += faceLst[facei].nTriangles();
}
// Nothing to do
if (nTri <= faceLst.size())
{
if (notNull(faceMap))
{
faceMap.clear();
}
}
else if (notNull(faceMap))
{
// face map requested
faceMap.setSize(nTri);
nTri = 0;
forAll(faceLst, facei)
{
label n = faceLst[facei].nTriangles();
while (n-- > 0)
{
faceMap[nTri++] = facei;
}
}
faceMap.setSize(nTri);
}
return nTri;
}
template<class Face>
Foam::label Foam::MeshedSurface<Face>::triangulate()
{
......@@ -888,14 +943,11 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
}
faceMap.setSize(nTri);
// remember the number of *additional* faces
nTri -= faceLst.size();
if (this->points().empty())
{
// triangulate without points
// simple face triangulation around f[0]
label newFacei = 0;
nTri = 0;
forAll(faceLst, facei)
{
const Face& f = faceLst[facei];
......@@ -904,9 +956,9 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
{
label fp1 = f.fcIndex(fp);
newFaces[newFacei] = triFace(f[0], f[fp], f[fp1]);
faceMap[newFacei] = facei;
newFacei++;
newFaces[nTri] = triFace(f[0], f[fp], f[fp1]);
faceMap[nTri] = facei;
nTri++;
}
}
}
......@@ -915,7 +967,7 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
// triangulate with points
List<face> tmpTri(maxTri);
label newFacei = 0;
nTri = 0;
forAll(faceLst, facei)
{
// 'face' not '<Face>'
......@@ -925,16 +977,19 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
f.triangles(this->points(), nTmp, tmpTri);
for (label triI = 0; triI < nTmp; triI++)
{
newFaces[newFacei] = Face
newFaces[nTri] = Face
(
static_cast<labelUList&>(tmpTri[triI])
);
faceMap[newFacei] = facei;
newFacei++;
faceMap[nTri] = facei;
nTri++;
}
}
}
// The number of *additional* faces
nTri -= faceLst.size();
faceLst.transfer(newFaces);
remapFaces(faceMap);
......@@ -947,6 +1002,7 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
// Topology can change because of renumbering
ParentType::clearOut();
return nTri;
}
......
......@@ -51,7 +51,7 @@ SourceFiles
#include "PatchTools.H"
#include "pointField.H"
#include "face.H"
#include "triFace.H"
#include "labelledTri.H"
#include "surfZoneList.H"
#include "surfaceFormatsCore.H"
......@@ -134,7 +134,10 @@ protected:
// Protected Member functions
//- Transfer points/zones and transcribe face -> triFace
//- Transfer points/zones from 'face' to other other shapes.
// Eg, transcribe face to triFace, or face -> labelledTri, including
// any addZonesToFaces adjustment.
// No general form, only specializations.
void transcribe(MeshedSurface<face>&);
//- Basic sanity check on zones
......@@ -386,6 +389,12 @@ public:
const bool cullEmpty=false
);
//- Propagate zone information on face regions.
// Normally a no-op, only used by the labelledTri specialization.
// Specializations return true, others return false.
bool addZonesToFaces();
//- Remove surface zones
virtual void removeZones();
......@@ -428,7 +437,14 @@ public:
const bool verbose=false
);
//- Triangulate in-place, returning the number of triangles added
//- Count number of triangles.
virtual label nTriangles() const;
//- Count number of triangles, returning a face map of original ids.
// The faceMap is zero-sized when no triangulation would be needed.
virtual label nTriangles(List<label>& faceMap) const;
//- Triangulate in-place, returning the number of triangles added.
virtual label triangulate();
//- Triangulate in-place, returning the number of triangles added
......@@ -436,7 +452,6 @@ public:
// The faceMap is zero-sized when no triangulation was done.
virtual label triangulate(List<label>& faceMap);
//- Return new surface.
// Returns return pointMap, faceMap from subsetMeshMap
MeshedSurface subsetMesh
......@@ -521,33 +536,10 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Specialization for holding triangulated information
template<>
inline bool MeshedSurface<triFace>::isTri()
{
return true;
}
//- Specialization for holding triangulated information
template<>
inline label MeshedSurface<triFace>::triangulate()
{
return 0;
}
//- Specialization for holding triangulated information
//- Specialization for labelledTri.
template<>
inline label MeshedSurface<triFace>::triangulate(List<label>& faceMap)
{
if (notNull(faceMap))
{
faceMap.clear();
}
bool MeshedSurface<labelledTri>::addZonesToFaces();
return 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -556,6 +548,8 @@ inline label MeshedSurface<triFace>::triangulate(List<label>& faceMap)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "MeshedSurfaceI.H"
#ifdef NoRepository
#include "MeshedSurface.C"
#endif
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -30,18 +30,34 @@ License
namespace Foam
{
// specialization: from face -> triFace
// Transcribe 'face' to 'face' (ie, just transfer)
template<>
void Foam::MeshedSurface<triFace>::transcribe(MeshedSurface<face>& surf)
void Foam::MeshedSurface<Foam::face>::transcribe
(
MeshedSurface<face>& surf
)
{
// first triangulate
this->transfer(surf);
this->addZonesToFaces(); // currently a no-op
}
// Transcribe 'face' to 'triFace'
// Transfer points/zones and triangulate faces
template<>
void Foam::MeshedSurface<Foam::triFace>::transcribe
(
MeshedSurface<face>& surf
)
{
// First triangulate
// - slightly wasteful for space, but manages adjusts the zones too!
surf.triangulate();
this->storedPoints().transfer(surf.storedPoints());
this->storedZones().transfer(surf.storedZones());
// transcribe from face -> triFace
List<face>& origFaces = surf.storedFaces();
List<triFace> newFaces(origFaces.size());
const List<face>& origFaces = surf.surfFaces();
List<triFace> newFaces(origFaces.size());
forAll(origFaces, facei)
{
newFaces[facei] = triFace
......@@ -52,18 +68,65 @@ namespace Foam
surf.clear();
this->storedFaces().transfer(newFaces);
this->addZonesToFaces(); // currently a no-op
}
// specialization: from face -> face
// Transcribe 'face' to 'labelledTri'
// Transfer points/zones and triangulate faces
template<>
void Foam::MeshedSurface<face>::transcribe(MeshedSurface<face>& surf)
void Foam::MeshedSurface<Foam::labelledTri>::transcribe
(
MeshedSurface<face>& surf
)
{
this->transfer(surf);
// First triangulate
// - slightly wasteful for space, but manages adjusts the zones too!
surf.triangulate();
this->storedPoints().transfer(surf.storedPoints());
this->storedZones().transfer(surf.storedZones());
// transcribe from face -> triFace
const List<face>& origFaces = surf.surfFaces();
List<labelledTri> newFaces(origFaces.size());
forAll(origFaces, facei)
{
newFaces[facei] = triFace
(
static_cast<const labelUList&>(origFaces[facei])
);
}
surf.clear();
this->storedFaces().transfer(newFaces);
this->addZonesToFaces(); // for labelledTri
}
// Propagate zone information on face regions for labelledTri.
template<>
bool Foam::MeshedSurface<Foam::labelledTri>::addZonesToFaces()
{
List<labelledTri>& faceLst = this->storedFaces();
const surfZoneList& zones = this->surfZones();
forAll(zones, zoneI)
{
const surfZone& zone = zones[zoneI];
label faceI = zone.start();
forAll(zone, i)
{
faceLst[faceI++].region() = zoneI;
}
}
return true;
}
} // end of namespace Foam
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// A triFace surface only handles triangulated faces
template<>
inline bool MeshedSurface<triFace>::isTri()
{
return true;
}
// A labelledTri surface only handles triangulated faces
template<>
inline bool MeshedSurface<labelledTri>::isTri()
{
return true;
}
// Number of triangles for a triFace surface
template<>
inline label MeshedSurface<triFace>::nTriangles() const
{
return ParentType::size();
}
// Number of triangles for a labelledTri surface
template<>
inline label MeshedSurface<labelledTri>::nTriangles() const
{
return ParentType::size();
}
// Inplace triangulation of triFace surface = no-op
template<>
inline label MeshedSurface<triFace>::triangulate()
{
return 0;
}
// Inplace triangulation of labelledTri surface = no-op
template<>
inline label MeshedSurface<labelledTri>::triangulate()
{
return 0;
}
// Inplace triangulation of triFace surface (with face map) = no-op
template<>
inline label MeshedSurface<triFace>::triangulate(List<label>& faceMap)
{
if (notNull(faceMap))
{
faceMap.clear();
}
return 0;
}
// Inplace triangulation of labelledTri surface (with face map) = no-op
template<>
inline label MeshedSurface<labelledTri>::triangulate(List<label>& faceMap)
{
if (notNull(faceMap))
{
faceMap.clear();
}
return 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -131,7 +131,7 @@ void Foam::MeshedSurface<Face>::addZones
const bool cullEmpty
)
{
label start = 0;
label start = 0;
label nZone = 0;
surfZoneList& zones = this->storedZones();
......@@ -162,7 +162,7 @@ void Foam::MeshedSurface<Face>::addZones
const bool cullEmpty
)
{
label start = 0;
label start = 0;
label nZone = 0;
surfZoneList& zones = this->storedZones();
......@@ -186,6 +186,14 @@ void Foam::MeshedSurface<Face>::addZones
}
template<class Face>
bool Foam::MeshedSurface<Face>::addZonesToFaces()
{
// Normally a no-op, only the specializations are used.
return false;
}
template<class Face>
void Foam::MeshedSurface<Face>::removeZones()
{
......
......@@ -46,6 +46,7 @@ namespace Foam
makeSurface(MeshedSurface, face)
makeSurface(MeshedSurface, triFace)
makeSurface(MeshedSurface, labelledTri)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -235,4 +235,41 @@ Foam::MeshedSurfaceProxy<Face>::~MeshedSurfaceProxy()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
namespace Foam
{
// Number of triangles for a triFace surface
template<>
inline label MeshedSurfaceProxy<triFace>::nTriangles() const
{
return this->size();
}
// Number of triangles for a labelledTri surface
template<>
inline label MeshedSurfaceProxy<labelledTri>::nTriangles() const
{
return this->size();
}
}
template<class Face>
inline Foam::label Foam::MeshedSurfaceProxy<Face>::nTriangles() const
{
label nTri = 0;
const List<Face>& faceLst = this->surfFaces();
forAll(faceLst, facei)
{
nTri += faceLst[facei].nTriangles();
}
return nTri;
}
// ************************************************************************* //
......@@ -38,8 +38,7 @@ SourceFiles
#define MeshedSurfaceProxy_H
#include "pointField.H"
#include "face.H"
#include "triFace.H"
#include "labelledTri.H"
#include "surfZoneList.H"
#include "surfaceFormatsCore.H"
......@@ -139,6 +138,12 @@ public:
// Access
//- The surface size is the number of faces
inline label size() const
{
return faces_.size();
}
//- Return const access to the points
inline const pointField& points() const
{
......@@ -171,6 +176,10 @@ public:
return faceMap_.size() == faces_.size();
}
//- Count number of triangles.
inline label nTriangles() const;
// Write
//- Generic write routine. Chooses writer based on extension.
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -46,6 +46,7 @@ namespace Foam
makeSurface(UnsortedMeshedSurface, face)
makeSurface(UnsortedMeshedSurface, triFace)
makeSurface(UnsortedMeshedSurface, labelledTri)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -49,7 +49,6 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
const fileName& filename
)
{
const bool mustTriangulate = this->isTri();
this->clear();
IFstream is(filename);
......@@ -199,7 +198,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
labelUList& f = static_cast<labelUList&>(verts);
if (mustTriangulate && f.size() > 3)
if (MeshedSurface<Face>::isTri() && f.size() > 3)
{