/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014-2017 OpenFOAM Foundation
\\/ 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 .
Application
surfaceHookUp
Group
grpSurfaceUtilities
Description
Find close open edges and stitches the surface along them
Usage
- surfaceHookUp hookDistance [OPTION]
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "triSurfaceMesh.H"
#include "indexedOctree.H"
#include "treeBoundBox.H"
#include "PackedBoolList.H"
#include "unitConversion.H"
#include "searchableSurfaces.H"
#include "IOdictionary.H"
using namespace Foam;
// Split facei along edgeI at position newPointi
void greenRefine
(
const triSurface& surf,
const label facei,
const label edgeI,
const label newPointi,
DynamicList& newFaces
)
{
const labelledTri& f = surf.localFaces()[facei];
const edge& e = surf.edges()[edgeI];
// Find index of edge in face.
label fp0 = findIndex(f, e[0]);
label fp1 = f.fcIndex(fp0);
label fp2 = f.fcIndex(fp1);
if (f[fp1] == e[1])
{
// Edge oriented like face
newFaces.append
(
labelledTri
(
f[fp0],
newPointi,
f[fp2],
f.region()
)
);
newFaces.append
(
labelledTri
(
newPointi,
f[fp1],
f[fp2],
f.region()
)
);
}
else
{
newFaces.append
(
labelledTri
(
f[fp2],
newPointi,
f[fp1],
f.region()
)
);
newFaces.append
(
labelledTri
(
newPointi,
f[fp0],
f[fp1],
f.region()
)
);
}
}
//scalar checkEdgeAngle
//(
// const triSurface& surf,
// const label edgeIndex,
// const label pointIndex,
// const scalar& angle
//)
//{
// const edge& e = surf.edges()[edgeIndex];
// vector eVec = e.vec(surf.localPoints());
// eVec /= mag(eVec) + SMALL;
// const labelList& pEdges = surf.pointEdges()[pointIndex];
//
// forAll(pEdges, eI)
// {
// const edge& nearE = surf.edges()[pEdges[eI]];
// vector nearEVec = nearE.vec(surf.localPoints());
// nearEVec /= mag(nearEVec) + SMALL;
// const scalar dot = eVec & nearEVec;
// const scalar minCos = degToRad(angle);
// if (mag(dot) > minCos)
// {
// return false;
// }
// }
// return true;
//}
void createBoundaryEdgeTrees
(
const PtrList& surfs,
PtrList>& bEdgeTrees,
labelListList& treeBoundaryEdges
)
{
forAll(surfs, surfI)
{
const triSurface& surf = surfs[surfI];
// Boundary edges
treeBoundaryEdges[surfI] =
labelList
(
identity(surf.nEdges() - surf.nInternalEdges())
+ surf.nInternalEdges()
);
Random rndGen(17301893);
// Slightly extended bb. Slightly off-centred just so on symmetric
// geometry there are less face/edge aligned items.
treeBoundBox bb
(
treeBoundBox(UList(surf.localPoints())).extend(rndGen, 1e-4)
);
bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
bEdgeTrees.set
(
surfI,
new indexedOctree
(
treeDataEdge
(
false, // cachebb
surf.edges(), // edges
surf.localPoints(), // points
treeBoundaryEdges[surfI] // selected edges
),
bb, // bb
8, // maxLevel
10, // leafsize
3.0 // duplicity
)
);
}
}
class findNearestOpSubset
{
const indexedOctree& tree_;
DynamicList