/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2017-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- 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 "surfaceFeatures.H" #include "triSurface.H" #include "indexedOctree.H" #include "treeDataEdge.H" #include "treeDataPoint.H" #include "meshTools.H" #include "Fstream.H" #include "unitConversion.H" #include "edgeHashes.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { defineTypeNameAndDebug(surfaceFeatures, 0); const scalar surfaceFeatures::parallelTolerance = sin(degToRad(1.0)); //! \cond fileScope // Check if the point is on the line static bool onLine(const Foam::point& p, const linePointRef& line) { const point& a = line.start(); const point& b = line.end(); if ( (p.x() < min(a.x(), b.x()) || p.x() > max(a.x(), b.x())) || (p.y() < min(a.y(), b.y()) || p.y() > max(a.y(), b.y())) || (p.z() < min(a.z(), b.z()) || p.z() > max(a.z(), b.z())) ) { return false; } return true; } //! \endcond } // End namespace Foam // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // Foam::pointIndexHit Foam::surfaceFeatures::edgeNearest ( const linePointRef& line, const point& sample ) { pointHit eHit = line.nearestDist(sample); // Classification of position on edge. label endPoint; if (eHit.hit()) { // Nearest point is on edge itself. // Note: might be at or very close to endpoint. We should use tolerance // here. endPoint = -1; } else { // Nearest point has to be one of the end points. Find out // which one. if ( eHit.point().distSqr(line.start()) < eHit.point().distSqr(line.end()) ) { endPoint = 0; } else { endPoint = 1; } } return pointIndexHit(eHit, endPoint); } // Go from selected edges only to a value for every edge Foam::List Foam::surfaceFeatures::toStatus() const { List edgeStat(surf_.nEdges(), NONE); // Region edges first for (label i = 0; i < externalStart_; i++) { edgeStat[featureEdges_[i]] = REGION; } // External edges for (label i = externalStart_; i < internalStart_; i++) { edgeStat[featureEdges_[i]] = EXTERNAL; } // Internal edges for (label i = internalStart_; i < featureEdges_.size(); i++) { edgeStat[featureEdges_[i]] = INTERNAL; } return edgeStat; } // Set from value for every edge void Foam::surfaceFeatures::setFromStatus ( const List& edgeStat, const scalar includedAngle ) { // Count label nRegion = 0; label nExternal = 0; label nInternal = 0; forAll(edgeStat, edgeI) { if (edgeStat[edgeI] == REGION) { nRegion++; } else if (edgeStat[edgeI] == EXTERNAL) { nExternal++; } else if (edgeStat[edgeI] == INTERNAL) { nInternal++; } } externalStart_ = nRegion; internalStart_ = externalStart_ + nExternal; // Copy featureEdges_.setSize(internalStart_ + nInternal); label regionI = 0; label externalI = externalStart_; label internalI = internalStart_; forAll(edgeStat, edgeI) { if (edgeStat[edgeI] == REGION) { featureEdges_[regionI++] = edgeI; } else if (edgeStat[edgeI] == EXTERNAL) { featureEdges_[externalI++] = edgeI; } else if (edgeStat[edgeI] == INTERNAL) { featureEdges_[internalI++] = edgeI; } } const scalar minCos = Foam::cos(degToRad(180.0 - includedAngle)); calcFeatPoints(edgeStat, minCos); } //construct feature points where more than 2 feature edges meet void Foam::surfaceFeatures::calcFeatPoints ( const List& edgeStat, const scalar minCos ) { DynamicList