/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2011 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 .
\*---------------------------------------------------------------------------*/
#include "triangle.H"
#include "triSurface.H"
#include "triSurfaceTools.H"
#include "triSurfaceSearch.H"
#include "argList.H"
#include "OFstream.H"
#include "surfaceIntersection.H"
#include "SortableList.H"
#include "PatchTools.H"
using namespace Foam;
// Does face use valid vertices?
bool validTri
(
const bool verbose,
const triSurface& surf,
const label faceI
)
{
// Simple check on indices ok.
const labelledTri& f = surf[faceI];
forAll(f, fp)
{
if (f[fp] < 0 || f[fp] >= surf.points().size())
{
WarningIn("validTri(const triSurface&, const label)")
<< "triangle " << faceI << " vertices " << f
<< " uses point indices outside point range 0.."
<< surf.points().size()-1 << endl;
return false;
}
}
if ((f[0] == f[1]) || (f[0] == f[2]) || (f[1] == f[2]))
{
WarningIn("validTri(const triSurface&, const label)")
<< "triangle " << faceI
<< " uses non-unique vertices " << f
<< " coords:" << f.points(surf.points())
<< endl;
return false;
}
// duplicate triangle check
const labelList& fFaces = surf.faceFaces()[faceI];
// Check if faceNeighbours use same points as this face.
// Note: discards normal information - sides of baffle are merged.
forAll(fFaces, i)
{
label nbrFaceI = fFaces[i];
if (nbrFaceI <= faceI)
{
// lower numbered faces already checked
continue;
}
const labelledTri& nbrF = surf[nbrFaceI];
if
(
((f[0] == nbrF[0]) || (f[0] == nbrF[1]) || (f[0] == nbrF[2]))
&& ((f[1] == nbrF[0]) || (f[1] == nbrF[1]) || (f[1] == nbrF[2]))
&& ((f[2] == nbrF[0]) || (f[2] == nbrF[1]) || (f[2] == nbrF[2]))
)
{
WarningIn("validTri(const triSurface&, const label)")
<< "triangle " << faceI << " vertices " << f
<< " has the same vertices as triangle " << nbrFaceI
<< " vertices " << nbrF
<< " coords:" << f.points(surf.points())
<< endl;
return false;
}
}
return true;
}
labelList countBins
(
const scalar min,
const scalar max,
const label nBins,
const scalarField& vals
)
{
scalar dist = nBins/(max - min);
labelList binCount(nBins, 0);
forAll(vals, i)
{
scalar val = vals[i];
label index = -1;
if (Foam::mag(val - min) < SMALL)
{
index = 0;
}
else if (val >= max - SMALL)
{
index = nBins - 1;
}
else
{
index = label((val - min)*dist);
if ((index < 0) || (index >= nBins))
{
WarningIn
(
"countBins(const scalar, const scalar, const label"
", const scalarField&)"
) << "value " << val << " at index " << i
<< " outside range " << min << " .. " << max << endl;
if (index < 0)
{
index = 0;
}
else
{
index = nBins - 1;
}
}
}
binCount[index]++;
}
return binCount;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noParallel();
argList::validArgs.append("surfaceFile");
argList::addBoolOption
(
"checkSelfIntersection",
"also check for self-intersection"
);
argList::addBoolOption
(
"verbose",
"verbose operation"
);
argList::addBoolOption
(
"blockMesh",
"write vertices/blocks for blockMeshDict"
);
argList args(argc, argv);
const fileName surfFileName = args[1];
const bool checkSelfIntersect = args.optionFound("checkSelfIntersection");
const bool verbose = args.optionFound("verbose");
Info<< "Reading surface from " << surfFileName << " ..." << nl << endl;
// Read
// ~~~~
triSurface surf(surfFileName);
Info<< "Statistics:" << endl;
surf.writeStats(Info);
Info<< endl;
// write bounding box corners
if (args.optionFound("blockMesh"))
{
pointField cornerPts(boundBox(surf.points()).points());
Info<<"// blockMeshDict info" << nl
<<"vertices\n(" << nl;
forAll(cornerPts, ptI)
{
Info << " " << cornerPts[ptI] << nl;
}
// number of divisions needs adjustment later
Info<<");\n" << nl
<<"blocks\n"
<<"(\n"
<<" hex (0 1 2 3 4 5 6 7) (10 10 10) simpleGrading (1 1 1)\n"
<<");\n" << nl;
Info<<"edges\n();" << nl
<<"patches\n();" << endl;
}
// Region sizes
// ~~~~~~~~~~~~
{
labelList regionSize(surf.patches().size(), 0);
forAll(surf, faceI)
{
label region = surf[faceI].region();
if (region < 0 || region >= regionSize.size())
{
WarningIn(args.executable())
<< "Triangle " << faceI << " vertices " << surf[faceI]
<< " has region " << region << " which is outside the range"
<< " of regions 0.." << surf.patches().size()-1
<< endl;
}
else
{
regionSize[region]++;
}
}
Info<< "Region\tSize" << nl
<< "------\t----" << nl;
forAll(surf.patches(), patchI)
{
Info<< surf.patches()[patchI].name() << '\t'
<< regionSize[patchI] << nl;
}
Info<< nl << endl;
}
// Check triangles
// ~~~~~~~~~~~~~~~
{
DynamicList