diff --git a/applications/utilities/surface/surfaceHookUp/Make/files b/applications/utilities/surface/surfaceHookUp/Make/files new file mode 100644 index 0000000000..b495b65457 --- /dev/null +++ b/applications/utilities/surface/surfaceHookUp/Make/files @@ -0,0 +1,3 @@ +surfaceHookUp.C + +EXE = $(FOAM_APPBIN)/surfaceHookUp diff --git a/applications/utilities/surface/surfaceHookUp/Make/options b/applications/utilities/surface/surfaceHookUp/Make/options new file mode 100644 index 0000000000..db53089d48 --- /dev/null +++ b/applications/utilities/surface/surfaceHookUp/Make/options @@ -0,0 +1,9 @@ +EXE_INC = \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/fileFormats/lnInclude \ + -I$(LIB_SRC)/triSurface/lnInclude + +EXE_LIBS = \ + -lmeshTools \ + -lfileFormats \ + -ltriSurface diff --git a/applications/utilities/surface/surfaceHookUp/surfaceHookUp.C b/applications/utilities/surface/surfaceHookUp/surfaceHookUp.C new file mode 100644 index 0000000000..61829b404b --- /dev/null +++ b/applications/utilities/surface/surfaceHookUp/surfaceHookUp.C @@ -0,0 +1,525 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 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 + +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" + +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 + ) + ); + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + argList::addNote + ( + "hook surfaces to other surfaces by moving and retriangulating their" + "boundary edges to match other surface boundary edges" + ); + argList::noParallel(); + argList::validArgs.append("hookTolerance"); + +# include "addDictOption.H" + +# include "setRootCase.H" +# include "createTime.H" + + const word dictName("surfaceHookUpDict"); +# include "setSystemRunTimeDictionaryIO.H" + + Info<< "Reading " << dictName << nl << endl; + + const IOdictionary dict(dictIO); + + const scalar dist(args.argRead(1)); + const scalar matchTolerance(SMALL); + + Info<< "Hooking distance = " << dist << endl; + + searchableSurfaces surfs + ( + IOobject + ( + "surfacesToHook", + runTime.constant(), + "triSurface", + runTime + ), + dict + ); + + Info<< nl << "Reading surfaces: " << endl; + forAll(surfs, surfI) + { + Info<< incrIndent; + Info<< nl << indent << "Surface = " << surfs.names()[surfI] << endl; + + const wordList& regions = surfs[surfI].regions(); + forAll(regions, surfRegionI) + { + Info<< incrIndent; + Info<< indent << "Regions = " << regions[surfRegionI] << endl; + Info<< decrIndent; + } + Info<< decrIndent; + } + + PtrList > bEdgeTrees(surfs.size()); + labelListList treeBoundaryEdges(surfs.size()); + + List > newFaces(surfs.size()); + List > newPoints(surfs.size()); + List visitedFace(surfs.size()); + + PtrList newSurfaces(surfs.size()); + forAll(surfs, surfI) + { + const triSurfaceMesh& surf = + refCast(surfs[surfI]); + + newSurfaces.set + ( + surfI, + new triSurfaceMesh + ( + IOobject + ( + "hookedSurface_" + surfs.names()[surfI], + runTime.constant(), + "triSurface", + runTime + ), + surf + ) + ); + } + + label nChanged = 0; + label nIters = 0; + + do + { + Info<< nl << "Iteration = " << nIters++ << endl; + nChanged = 0; + + createBoundaryEdgeTrees(newSurfaces, bEdgeTrees, treeBoundaryEdges); + + forAll(newSurfaces, surfI) + { + const triSurface& newSurf = newSurfaces[surfI]; + + newFaces[surfI] = newSurf.localFaces(); + newPoints[surfI] = newSurf.localPoints(); + visitedFace[surfI] = PackedBoolList(newSurf.size(), false); + } + + forAll(newSurfaces, surfI) + { + const triSurface& surf = newSurfaces[surfI]; + + List bPointsTobEdges(surf.boundaryPoints().size()); + labelList bPointsHitTree(surf.boundaryPoints().size(), -1); + + const labelListList& pointEdges = surf.pointEdges(); + + forAll(bPointsTobEdges, bPointI) + { + pointIndexHit& nearestHit = bPointsTobEdges[bPointI]; + + const label pointI = surf.boundaryPoints()[bPointI]; + const point& samplePt = surf.localPoints()[pointI]; + + const labelList& pEdges = pointEdges[pointI]; + + // Add edges connected to the edge to the shapeMask + DynamicList