Commit e72a6234 authored by Mark Olesen's avatar Mark Olesen
Browse files

surfMesh changes

 - expose faceMap info in triangulate() - for use in inherited classes
 - surfMesh::triangulate() works with or without underlying pointField
 - onePatch tries to be more intelligent about retaining the patch name
parent d6b247a3
......@@ -199,7 +199,6 @@ int main(int argc, char *argv[])
if (args.options().found("clean"))
{
surf.cleanup(true);
surf.checkOrientation(true);
}
if (fromCsys.valid())
......
......@@ -104,13 +104,19 @@ int main(int argc, char *argv[])
{
triSurface surf(importName);
Info<< "Read surface:" << endl;
surf.writeStats(Info);
Info<< endl;
if (args.options().found("clean"))
{
Info<< "Cleaning up surface" << endl;
surf.cleanup(true);
surf.checkOrientation(true);
surf.writeStats(Info);
Info<< endl;
}
Info << "writing " << exportName;
Info<< "writing " << exportName;
if (scaleFactor <= 0)
{
Info<< " without scaling" << endl;
......@@ -119,6 +125,8 @@ int main(int argc, char *argv[])
{
Info<< " with scaling " << scaleFactor << endl;
surf.scalePoints(scaleFactor);
surf.writeStats(Info);
Info<< endl;
}
// write sorted by region
......@@ -128,13 +136,19 @@ int main(int argc, char *argv[])
{
UnsortedMeshedSurface<face> surf(importName);
Info<< "Read surface:" << endl;
surf.writeStats(Info);
Info<< endl;
if (args.options().found("clean"))
{
Info<< "Cleaning up surface" << endl;
surf.cleanup(true);
surf.checkOrientation(true);
surf.writeStats(Info);
Info<< endl;
}
Info << "writing " << exportName;
Info<< "writing " << exportName;
if (scaleFactor <= 0)
{
Info<< " without scaling" << endl;
......@@ -143,8 +157,9 @@ int main(int argc, char *argv[])
{
Info<< " with scaling " << scaleFactor << endl;
surf.scalePoints(scaleFactor);
surf.writeStats(Info);
Info<< endl;
}
surf.write(exportName);
}
#if 1
......@@ -152,10 +167,16 @@ int main(int argc, char *argv[])
{
MeshedSurface<triFace> surf(importName);
Info<< "Read surface:" << endl;
surf.writeStats(Info);
Info<< endl;
if (args.options().found("clean"))
{
Info<< "Cleaning up surface" << endl;
surf.cleanup(true);
surf.checkOrientation(true);
surf.writeStats(Info);
Info<< endl;
}
Info<< "writing " << exportName;
......@@ -167,6 +188,8 @@ int main(int argc, char *argv[])
{
Info<< " with scaling " << scaleFactor << endl;
surf.scalePoints(scaleFactor);
surf.writeStats(Info);
Info<< endl;
}
surf.write(exportName);
}
......@@ -175,10 +198,16 @@ int main(int argc, char *argv[])
{
MeshedSurface<face> surf(importName);
Info<< "Read surface:" << endl;
surf.writeStats(Info);
Info<< endl;
if (args.options().found("clean"))
{
Info<< "Cleaning up surface" << endl;
surf.cleanup(true);
surf.checkOrientation(true);
surf.writeStats(Info);
Info<< endl;
}
Info<< "writing " << exportName;
......@@ -190,6 +219,8 @@ int main(int argc, char *argv[])
{
Info<< " with scaling " << scaleFactor << endl;
surf.scalePoints(scaleFactor);
surf.writeStats(Info);
Info<< endl;
}
surf.write(exportName);
}
......
......@@ -420,13 +420,26 @@ Foam::MeshedSurface<Face>::~MeshedSurface()
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Face>
void Foam::MeshedSurface<Face>::onePatch()
void Foam::MeshedSurface<Face>::onePatch(const word& name)
{
word patchName(name);
if (!patchName.size())
{
if (patches_.size() >= 1)
{
patchName = patches_[0].name();
}
if (!patchName.size())
{
patchName = "patch0";
}
}
// set single default patch
patches_.setSize(1);
patches_[0] = surfGroup
(
"patch0",
patchName,
size(), // patch size
0, // patch start
0 // patch index
......@@ -438,9 +451,12 @@ template<class Face>
void Foam::MeshedSurface<Face>::checkPatches()
{
// extra safety, ensure we have at some patches,
// and they cover all the faces
// fix start silently
if (patches_.size() > 1)
// and they cover all the faces - fix start silently
if (patches_.size() <= 1)
{
onePatch();
}
else
{
label count = 0;
forAll(patches_, patchI)
......@@ -455,8 +471,7 @@ void Foam::MeshedSurface<Face>::checkPatches()
(
"MeshedSurface::checkPatches()\n"
)
<< "more nFaces " << size()
<< " than patches " << count
<< "more face " << size() << " than patches " << count
<< " ... extending final patch"
<< endl;
......@@ -468,25 +483,10 @@ void Foam::MeshedSurface<Face>::checkPatches()
(
"MeshedSurface::checkPatches()\n"
)
<< "more patches " << count
<< " than nFaces " << size()
<< "more patches " << count << " than faces " << size()
<< exit(FatalError);
}
}
else if (patches_.size() == 1)
{
// like onePatch, but preserve the name
patches_[0].size() = size();
patches_[0].start() = 0;
if (!patches_[0].name().size())
{
patches_[0].name() = "patch0";
}
}
else
{
onePatch();
}
}
......@@ -529,38 +529,52 @@ void Foam::MeshedSurface<Face>::sortFacesAndStore
template<class Face>
void Foam::MeshedSurface<Face>::remapRegions(List<label>& faceMap)
void Foam::MeshedSurface<Face>::remapFaces
(
const UList<label>& faceMap
)
{
// recalculate the patch start/size
if (faceMap.size())
if (&faceMap && faceMap.size())
{
label newFaceI = 0;
label oldPatchEnd = 0;
forAll(patches_, patchI)
if (patches_.size() == 0)
{
surfGroup& p = patches_[patchI];
onePatch();
}
else if (patches_.size() == 1)
{
// optimized for one-patch case
patches_[0].size() = faceMap.size();
}
else
{
label newFaceI = 0;
label oldPatchEnd = 0;
forAll(patches_, patchI)
{
surfGroup& p = patches_[patchI];
// adjust patch start
p.start() = newFaceI;
oldPatchEnd += p.size();
// adjust patch start
p.start() = newFaceI;
oldPatchEnd += p.size();
for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
{
if (faceMap[faceI] < oldPatchEnd)
{
++newFaceI;
}
else
for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
{
break;
if (faceMap[faceI] < oldPatchEnd)
{
++newFaceI;
}
else
{
break;
}
}
}
// adjust patch size
p.size() = newFaceI - p.start();
// adjust patch size
p.size() = newFaceI - p.start();
}
}
}
faceMap.clear();
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
......
......@@ -113,7 +113,7 @@ protected:
);
//- Set new regions from faceMap
virtual void remapRegions(List<label>& faceMap);
virtual void remapFaces(const UList<label>& faceMap);
public:
......@@ -255,8 +255,8 @@ public:
return patches_;
}
//- set a single patch
void onePatch();
//- set a single patch, optionally with a specific name
void onePatch(const word& name = word::null);
//- add patches
void addPatches
......
......@@ -25,8 +25,8 @@ License
\*---------------------------------------------------------------------------*/
#include "PrimitiveMeshedSurface.H"
#include "boundBox.H"
#include "mergePoints.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Face>
......@@ -214,7 +214,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
<< " faces" << endl;
}
faceLst.setSize(newFaceI);
remapRegions(faceMap);
remapFaces(faceMap);
}
faceMap.clear();
......@@ -374,7 +374,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
}
faceLst.setSize(newFaceI);
remapRegions(faceMap);
remapFaces(faceMap);
}
faceMap.clear();
......@@ -386,53 +386,110 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
template<class Face>
Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate()
{
return triangulate
(
const_cast<List<label>&>(List<label>::null())
);
}
template<class Face>
Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate
(
List<label>& faceMapOut
)
{
label nTri = 0;
label maxTri = 0; // the maximum number of triangles for any single face
List<Face>& faceLst = this->storedFaces();
// determine how many triangles are needed
// determine how many triangles will be needed
forAll(faceLst, faceI)
{
nTri += faceLst[faceI].size() - 2;
const label n = faceLst[faceI].nTriangles();
if (maxTri < n)
{
maxTri = n;
}
nTri += n;
}
// nothing to do
if (nTri <= faceLst.size())
{
if (&faceMapOut)
{
faceMapOut.clear();
}
return 0;
}
List<Face> newFaces(nTri);
List<label> faceMap(nTri);
List<label> faceMap;
// reuse storage from optional faceMap
if (&faceMapOut)
{
faceMap.transfer(faceMapOut);
}
faceMap.setSize(nTri);
// remember the number of *additional* faces
nTri -= faceLst.size();
label newFaceI = 0;
forAll(faceLst, faceI)
if (this->points().size() == 0)
{
const Face& f = faceLst[faceI];
triFace fTri;
// Do simple face triangulation around f[0].
// we could also use face::triangulation, but that requires points
// and doesn't currently template nicely
fTri[0] = f[0];
for (label fp = 1; fp < f.size() - 1; ++fp)
// triangulate without points
// simple face triangulation around f[0]
label newFaceI = 0;
forAll(faceLst, faceI)
{
label fp1 = (fp + 1) % f.size();
const Face& f = faceLst[faceI];
fTri[1] = f[fp];
fTri[2] = f[fp1];
for (label fp = 1; fp < f.size() - 1; ++fp)
{
label fp1 = (fp + 1) % f.size();
newFaces[newFaceI] = fTri;
faceMap[newFaceI] = faceI;
newFaceI++;
newFaces[newFaceI] = triFace(f[0], f[fp], f[fp1]);
faceMap[newFaceI] = faceI;
newFaceI++;
}
}
}
else
{
// triangulate with points
List<face> tmpTri(maxTri);
label newFaceI = 0;
forAll(faceLst, faceI)
{
// 'face' not '<Face>'
const face& f = faceLst[faceI];
label nTmp;
f.triangles(this->points(), nTmp, tmpTri);
for (label triI = 0; triI < nTmp; triI++)
{
newFaces[newFaceI] = Face
(
static_cast<UList<label>&>(tmpTri[triI])
);
faceMap[newFaceI] = faceI;
newFaceI++;
}
}
}
faceLst.transfer(newFaces);
remapRegions(faceMap);
remapFaces(faceMap);
// optionally return the faceMap
if (&faceMapOut)
{
faceMapOut.transfer(faceMap);
}
faceMap.clear();
// Topology can change because of renumbering
......@@ -443,12 +500,19 @@ Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate()
// dummy implementation to avoid a pure virtual class
template<class Face>
void Foam::PrimitiveMeshedSurface<Face>::remapRegions(List<label>& faceMap)
void Foam::PrimitiveMeshedSurface<Face>::remapFaces(const UList<label>&)
{
faceMap.clear();
}
template<class Face>
void Foam::PrimitiveMeshedSurface<Face>::writeStats(Ostream& os) const
{
os << "points : " << this->points().size() << nl
<< (this->isTri() ? "triangles : " : "faces : ")
<< this->size() << nl
<< "boundingBox : " << boundBox(this->points()) << endl;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
......
......@@ -85,7 +85,7 @@ protected:
}
//- Set new regions/patches from faceMap
virtual void remapRegions(List<label>& faceMap);
virtual void remapFaces(const UList<label>& faceMap);
public:
......@@ -94,6 +94,7 @@ public:
//- Face storage only handles triangulated faces
inline static bool isTri();
// Constructors
//- Construct null
......@@ -154,8 +155,19 @@ public:
//- Triangulate in-place
// Returning the number of triangles added
// Optionally returning a map of original face Ids (zero-sized when
// no triangulation was done)
virtual label triangulate();
//- Triangulate in-place, setting a map of original face Ids
// faceMap is zero-sized when no triangulation was done
virtual label triangulate(List<label>& faceMap);
// Write
void writeStats(Ostream& os) const;
};
......@@ -175,6 +187,18 @@ inline label PrimitiveMeshedSurface<triFace>::triangulate()
return 0;
}
//- Specialization for holding triangulated information
template<>
inline label PrimitiveMeshedSurface<triFace>::triangulate(List<label>& faceMap)
{
if (&faceMap)
{
faceMap.clear();
}
return 0;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -301,14 +301,27 @@ Foam::UnsortedMeshedSurface<Face>::~UnsortedMeshedSurface()
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Face>
void Foam::UnsortedMeshedSurface<Face>::onePatch()
void Foam::UnsortedMeshedSurface<Face>::onePatch(const word& name)
{
regions_.setSize(size());
regions_ = 0;
word patchName(name);
if (!patchName.size())
{
if (patches_.size() >= 1)
{
patchName = patches_[0].name();
}
if (!patchName.size())
{
patchName = "patch0";
}
}
// set single default patch
patches_.setSize(1);
patches_[0] = surfPatchIdentifier("patch0", 0);
patches_[0] = surfPatchIdentifier(patchName, 0);
}
......@@ -383,18 +396,34 @@ void Foam::UnsortedMeshedSurface<Face>::setPatches
template<class Face>
void Foam::UnsortedMeshedSurface<Face>::remapRegions(List<label>& faceMap)
void Foam::UnsortedMeshedSurface<Face>::remapFaces
(
const UList<label>& faceMap
)
{
// re-assign the region Ids
if (faceMap.size())
if (&faceMap && faceMap.size())
{
forAll(faceMap, faceI)
if (patches_.size() == 0)
{
onePatch();
}
else if (patches_.size() == 1)
{
faceMap[faceI] = regions_[faceMap[faceI]];
// optimized for one-patch case
regions_ = 0;
}
else
{
List<label> newRegions(faceMap.size());
forAll(faceMap, faceI)
{
newRegions[faceI] = regions_[faceMap[faceI]];
}
regions_.transfer(newRegions);
}
regions_.transfer(faceMap);
}
faceMap.clear();
}