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
This commit is contained in:
Mark Olesen
2008-11-22 11:22:34 +01:00
parent d6b247a3b1
commit e72a6234d6
12 changed files with 289 additions and 145 deletions

View File

@ -199,7 +199,6 @@ int main(int argc, char *argv[])
if (args.options().found("clean")) if (args.options().found("clean"))
{ {
surf.cleanup(true); surf.cleanup(true);
surf.checkOrientation(true);
} }
if (fromCsys.valid()) if (fromCsys.valid())

View File

@ -104,10 +104,16 @@ int main(int argc, char *argv[])
{ {
triSurface surf(importName); triSurface surf(importName);
Info<< "Read surface:" << endl;
surf.writeStats(Info);
Info<< endl;
if (args.options().found("clean")) if (args.options().found("clean"))
{ {
Info<< "Cleaning up surface" << endl;
surf.cleanup(true); surf.cleanup(true);
surf.checkOrientation(true); surf.writeStats(Info);
Info<< endl;
} }
Info<< "writing " << exportName; Info<< "writing " << exportName;
@ -119,6 +125,8 @@ int main(int argc, char *argv[])
{ {
Info<< " with scaling " << scaleFactor << endl; Info<< " with scaling " << scaleFactor << endl;
surf.scalePoints(scaleFactor); surf.scalePoints(scaleFactor);
surf.writeStats(Info);
Info<< endl;
} }
// write sorted by region // write sorted by region
@ -128,10 +136,16 @@ int main(int argc, char *argv[])
{ {
UnsortedMeshedSurface<face> surf(importName); UnsortedMeshedSurface<face> surf(importName);
Info<< "Read surface:" << endl;
surf.writeStats(Info);
Info<< endl;
if (args.options().found("clean")) if (args.options().found("clean"))
{ {
Info<< "Cleaning up surface" << endl;
surf.cleanup(true); surf.cleanup(true);
surf.checkOrientation(true); surf.writeStats(Info);
Info<< endl;
} }
Info<< "writing " << exportName; Info<< "writing " << exportName;
@ -143,8 +157,9 @@ int main(int argc, char *argv[])
{ {
Info<< " with scaling " << scaleFactor << endl; Info<< " with scaling " << scaleFactor << endl;
surf.scalePoints(scaleFactor); surf.scalePoints(scaleFactor);
surf.writeStats(Info);
Info<< endl;
} }
surf.write(exportName); surf.write(exportName);
} }
#if 1 #if 1
@ -152,10 +167,16 @@ int main(int argc, char *argv[])
{ {
MeshedSurface<triFace> surf(importName); MeshedSurface<triFace> surf(importName);
Info<< "Read surface:" << endl;
surf.writeStats(Info);
Info<< endl;
if (args.options().found("clean")) if (args.options().found("clean"))
{ {
Info<< "Cleaning up surface" << endl;
surf.cleanup(true); surf.cleanup(true);
surf.checkOrientation(true); surf.writeStats(Info);
Info<< endl;
} }
Info<< "writing " << exportName; Info<< "writing " << exportName;
@ -167,6 +188,8 @@ int main(int argc, char *argv[])
{ {
Info<< " with scaling " << scaleFactor << endl; Info<< " with scaling " << scaleFactor << endl;
surf.scalePoints(scaleFactor); surf.scalePoints(scaleFactor);
surf.writeStats(Info);
Info<< endl;
} }
surf.write(exportName); surf.write(exportName);
} }
@ -175,10 +198,16 @@ int main(int argc, char *argv[])
{ {
MeshedSurface<face> surf(importName); MeshedSurface<face> surf(importName);
Info<< "Read surface:" << endl;
surf.writeStats(Info);
Info<< endl;
if (args.options().found("clean")) if (args.options().found("clean"))
{ {
Info<< "Cleaning up surface" << endl;
surf.cleanup(true); surf.cleanup(true);
surf.checkOrientation(true); surf.writeStats(Info);
Info<< endl;
} }
Info<< "writing " << exportName; Info<< "writing " << exportName;
@ -190,6 +219,8 @@ int main(int argc, char *argv[])
{ {
Info<< " with scaling " << scaleFactor << endl; Info<< " with scaling " << scaleFactor << endl;
surf.scalePoints(scaleFactor); surf.scalePoints(scaleFactor);
surf.writeStats(Info);
Info<< endl;
} }
surf.write(exportName); surf.write(exportName);
} }

View File

@ -420,13 +420,26 @@ Foam::MeshedSurface<Face>::~MeshedSurface()
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Face> 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 // set single default patch
patches_.setSize(1); patches_.setSize(1);
patches_[0] = surfGroup patches_[0] = surfGroup
( (
"patch0", patchName,
size(), // patch size size(), // patch size
0, // patch start 0, // patch start
0 // patch index 0 // patch index
@ -438,9 +451,12 @@ template<class Face>
void Foam::MeshedSurface<Face>::checkPatches() void Foam::MeshedSurface<Face>::checkPatches()
{ {
// extra safety, ensure we have at some patches, // extra safety, ensure we have at some patches,
// and they cover all the faces // and they cover all the faces - fix start silently
// fix start silently if (patches_.size() <= 1)
if (patches_.size() > 1) {
onePatch();
}
else
{ {
label count = 0; label count = 0;
forAll(patches_, patchI) forAll(patches_, patchI)
@ -455,8 +471,7 @@ void Foam::MeshedSurface<Face>::checkPatches()
( (
"MeshedSurface::checkPatches()\n" "MeshedSurface::checkPatches()\n"
) )
<< "more nFaces " << size() << "more face " << size() << " than patches " << count
<< " than patches " << count
<< " ... extending final patch" << " ... extending final patch"
<< endl; << endl;
@ -468,25 +483,10 @@ void Foam::MeshedSurface<Face>::checkPatches()
( (
"MeshedSurface::checkPatches()\n" "MeshedSurface::checkPatches()\n"
) )
<< "more patches " << count << "more patches " << count << " than faces " << size()
<< " than nFaces " << size()
<< exit(FatalError); << 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,10 +529,24 @@ void Foam::MeshedSurface<Face>::sortFacesAndStore
template<class Face> 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 // recalculate the patch start/size
if (faceMap.size()) if (&faceMap && faceMap.size())
{
if (patches_.size() == 0)
{
onePatch();
}
else if (patches_.size() == 1)
{
// optimized for one-patch case
patches_[0].size() = faceMap.size();
}
else
{ {
label newFaceI = 0; label newFaceI = 0;
label oldPatchEnd = 0; label oldPatchEnd = 0;
@ -560,7 +574,7 @@ void Foam::MeshedSurface<Face>::remapRegions(List<label>& faceMap)
p.size() = newFaceI - p.start(); p.size() = newFaceI - p.start();
} }
} }
faceMap.clear(); }
} }
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //

View File

@ -113,7 +113,7 @@ protected:
); );
//- Set new regions from faceMap //- Set new regions from faceMap
virtual void remapRegions(List<label>& faceMap); virtual void remapFaces(const UList<label>& faceMap);
public: public:
@ -255,8 +255,8 @@ public:
return patches_; return patches_;
} }
//- set a single patch //- set a single patch, optionally with a specific name
void onePatch(); void onePatch(const word& name = word::null);
//- add patches //- add patches
void addPatches void addPatches

View File

@ -25,8 +25,8 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "PrimitiveMeshedSurface.H" #include "PrimitiveMeshedSurface.H"
#include "boundBox.H"
#include "mergePoints.H" #include "mergePoints.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Face> template<class Face>
@ -214,7 +214,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
<< " faces" << endl; << " faces" << endl;
} }
faceLst.setSize(newFaceI); faceLst.setSize(newFaceI);
remapRegions(faceMap); remapFaces(faceMap);
} }
faceMap.clear(); faceMap.clear();
@ -374,7 +374,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
} }
faceLst.setSize(newFaceI); faceLst.setSize(newFaceI);
remapRegions(faceMap); remapFaces(faceMap);
} }
faceMap.clear(); faceMap.clear();
@ -386,53 +386,110 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
template<class Face> template<class Face>
Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate() 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 nTri = 0;
label maxTri = 0; // the maximum number of triangles for any single face
List<Face>& faceLst = this->storedFaces(); List<Face>& faceLst = this->storedFaces();
// determine how many triangles are needed // determine how many triangles will be needed
forAll(faceLst, faceI) forAll(faceLst, faceI)
{ {
nTri += faceLst[faceI].size() - 2; const label n = faceLst[faceI].nTriangles();
if (maxTri < n)
{
maxTri = n;
}
nTri += n;
} }
// nothing to do // nothing to do
if (nTri <= faceLst.size()) if (nTri <= faceLst.size())
{ {
if (&faceMapOut)
{
faceMapOut.clear();
}
return 0; return 0;
} }
List<Face> newFaces(nTri); 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 // remember the number of *additional* faces
nTri -= faceLst.size(); nTri -= faceLst.size();
if (this->points().size() == 0)
{
// triangulate without points
// simple face triangulation around f[0]
label newFaceI = 0; label newFaceI = 0;
forAll(faceLst, faceI) forAll(faceLst, faceI)
{ {
const Face& f = faceLst[faceI]; 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) for (label fp = 1; fp < f.size() - 1; ++fp)
{ {
label fp1 = (fp + 1) % f.size(); label fp1 = (fp + 1) % f.size();
fTri[1] = f[fp]; newFaces[newFaceI] = triFace(f[0], f[fp], f[fp1]);
fTri[2] = f[fp1];
newFaces[newFaceI] = fTri;
faceMap[newFaceI] = faceI; faceMap[newFaceI] = faceI;
newFaceI++; 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); faceLst.transfer(newFaces);
remapRegions(faceMap); remapFaces(faceMap);
// optionally return the faceMap
if (&faceMapOut)
{
faceMapOut.transfer(faceMap);
}
faceMap.clear(); faceMap.clear();
// Topology can change because of renumbering // Topology can change because of renumbering
@ -443,12 +500,19 @@ Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate()
// dummy implementation to avoid a pure virtual class // dummy implementation to avoid a pure virtual class
template<class Face> 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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //

View File

@ -85,7 +85,7 @@ protected:
} }
//- Set new regions/patches from faceMap //- Set new regions/patches from faceMap
virtual void remapRegions(List<label>& faceMap); virtual void remapFaces(const UList<label>& faceMap);
public: public:
@ -94,6 +94,7 @@ public:
//- Face storage only handles triangulated faces //- Face storage only handles triangulated faces
inline static bool isTri(); inline static bool isTri();
// Constructors // Constructors
//- Construct null //- Construct null
@ -154,8 +155,19 @@ public:
//- Triangulate in-place //- Triangulate in-place
// Returning the number of triangles added // Returning the number of triangles added
// Optionally returning a map of original face Ids (zero-sized when
// no triangulation was done)
virtual label triangulate(); 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; 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 } // End namespace Foam

View File

@ -301,14 +301,27 @@ Foam::UnsortedMeshedSurface<Face>::~UnsortedMeshedSurface()
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Face> template<class Face>
void Foam::UnsortedMeshedSurface<Face>::onePatch() void Foam::UnsortedMeshedSurface<Face>::onePatch(const word& name)
{ {
regions_.setSize(size()); regions_.setSize(size());
regions_ = 0; 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 // set single default patch
patches_.setSize(1); 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> 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 // re-assign the region Ids
if (faceMap.size()) if (&faceMap && faceMap.size())
{ {
if (patches_.size() == 0)
{
onePatch();
}
else if (patches_.size() == 1)
{
// optimized for one-patch case
regions_ = 0;
}
else
{
List<label> newRegions(faceMap.size());
forAll(faceMap, faceI) forAll(faceMap, faceI)
{ {
faceMap[faceI] = regions_[faceMap[faceI]]; newRegions[faceI] = regions_[faceMap[faceI]];
}
regions_.transfer(newRegions);
} }
regions_.transfer(faceMap);
} }
faceMap.clear();
} }

View File

@ -125,7 +125,7 @@ protected:
} }
//- Set new regions from faceMap //- Set new regions from faceMap
virtual void remapRegions(List<label>& faceMap); virtual void remapFaces(const UList<label>& faceMap);
public: public:
@ -281,7 +281,8 @@ public:
List<surfGroup> sortedRegions(labelList& faceMap) const; List<surfGroup> sortedRegions(labelList& faceMap) const;
//- Set regions to 0 and set a single patch //- Set regions to 0 and set a single patch
void onePatch(); // Optionally with a specific name
void onePatch(const word& name = word::null);
//- Set regions and patches //- Set regions and patches
void setPatches(const surfGroupList&); void setPatches(const surfGroupList&);

View File

@ -223,20 +223,13 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
if (mustTriangulate && f.size() > 3) if (mustTriangulate && f.size() > 3)
{ {
triFace fTri; // simple face triangulation about f[0]
// points may be incomplete
// simple face triangulation about f[0]. for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
// cannot use face::triangulation
// since points are incomplete
fTri[0] = verts[0];
for (label fp1 = 1; fp1 < verts.size() - 1; ++fp1)
{ {
label fp2 = (fp1 + 1) % verts.size(); label fp2 = (fp1 + 1) % f.size();
fTri[1] = verts[fp1]; dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
fTri[2] = verts[fp2];
dynFaces.append(fTri);
sizes[patchI]++; sizes[patchI]++;
} }
} }

View File

@ -178,19 +178,13 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
if (mustTriangulate && f.size() > 3) if (mustTriangulate && f.size() > 3)
{ {
triFace fTri; // simple face triangulation about f[0]
// points may be incomplete
// simple face triangulation about f[0].
// Cannot use face::triangulation since points are incomplete
fTri[0] = f[0];
for (label fp1 = 1; fp1 < f.size() - 1; fp1++) for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
{ {
label fp2 = (fp1 + 1) % f.size(); label fp2 = (fp1 + 1) % f.size();
fTri[1] = f[fp1]; dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
fTri[2] = f[fp2];
dynFaces.append(fTri);
dynRegions.append(regionI); dynRegions.append(regionI);
dynSizes[regionI]++; dynSizes[regionI]++;
} }

View File

@ -126,18 +126,13 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
if (mustTriangulate && f.size() > 3) if (mustTriangulate && f.size() > 3)
{ {
triFace fTri; // simple face triangulation about f[0]
// cannot use face::triangulation (points may be incomplete)
// simple face triangulation about f[0].
fTri[0] = f[0];
for (label fp1 = 1; fp1 < f.size() - 1; fp1++) for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
{ {
label fp2 = (fp1 + 1) % f.size(); label fp2 = (fp1 + 1) % f.size();
fTri[1] = f[fp1]; dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
fTri[2] = f[fp2];
dynFaces.append(fTri);
} }
} }
else else

View File

@ -190,7 +190,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
{ {
face f(vertices); face f(vertices);
faceList triFaces(f.nTriangles(this->points())); faceList triFaces(f.nTriangles());
label nTri = 0; label nTri = 0;
f.triangles(this->points(), nTri, triFaces); f.triangles(this->points(), nTri, triFaces);