diff --git a/applications/utilities/surface/surfaceSubset/surfaceSubset.C b/applications/utilities/surface/surfaceSubset/surfaceSubset.C index 9df166e6e28ee194e01e067a32a994a3995d5999..195835523860a8ff9218ed7aaaef74a8a41a6970 100644 --- a/applications/utilities/surface/surfaceSubset/surfaceSubset.C +++ b/applications/utilities/surface/surfaceSubset/surfaceSubset.C @@ -31,6 +31,7 @@ Description \*---------------------------------------------------------------------------*/ #include "triSurface.H" +#include "triSurfaceSearch.H" #include "argList.H" #include "OFstream.H" #include "IFstream.H" @@ -40,6 +41,7 @@ Description #include "indexedOctree.H" #include "treeDataTriSurface.H" #include "Random.H" +#include "volumeType.H" using namespace Foam; @@ -242,26 +244,16 @@ int main(int argc, char *argv[]) // Read surface to select on triSurface selectSurf(surfName); - // bb of surface - treeBoundBox bb(selectSurf.localPoints()); - - // Random number generator - Random rndGen(354543); - - // search engine - indexedOctree<treeDataTriSurface> selectTree + triSurfaceSearch searchSelectSurf ( - treeDataTriSurface - ( - selectSurf, - indexedOctree<treeDataTriSurface>::perturbTol() - ), - bb.extend(rndGen, 1e-4), // slightly randomize bb - 8, // maxLevel - 10, // leafsize - 3.0 // duplicity + selectSurf, + indexedOctree<treeDataTriSurface>::perturbTol(), + 8 ); + const indexedOctree<treeDataTriSurface>& selectTree = + searchSelectSurf.tree(); + // Check if face (centre) is in outside or inside. forAll(facesToSubset, faceI) { @@ -269,14 +261,13 @@ int main(int argc, char *argv[]) { const point fc(surf1[faceI].centre(surf1.points())); - indexedOctree<treeDataTriSurface>::volumeType t = - selectTree.getVolumeType(fc); + volumeType t = selectTree.getVolumeType(fc); if ( outside - ? (t == indexedOctree<treeDataTriSurface>::OUTSIDE) - : (t == indexedOctree<treeDataTriSurface>::INSIDE) + ? (t == volumeType::OUTSIDE) + : (t == volumeType::INSIDE) ) { facesToSubset[faceI] = true; diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index c7d000e8511396116aa6424da8cd63308809490b..19a8138fe5d1fc5f988befd6d5f388e639052c93 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -627,6 +627,7 @@ $(interpolationWeights)/splineInterpolationWeights/splineInterpolationWeights.C algorithms/indexedOctree/indexedOctreeName.C algorithms/indexedOctree/treeDataCell.C +algorithms/indexedOctree/volumeType.C algorithms/dynamicIndexedOctree/dynamicIndexedOctreeName.C diff --git a/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicIndexedOctree.C b/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicIndexedOctree.C index b18b2892cb8205db1ea80f0b522aa74aa8e3351e..92b2932510469a73455cdd89aedc3e43a8efb1fb 100644 --- a/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicIndexedOctree.C +++ b/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicIndexedOctree.C @@ -334,15 +334,14 @@ void Foam::dynamicIndexedOctree<Type>::recursiveSubDivision // Recurses to determine status of lowest level boxes. Level above is // combination of octants below. template<class Type> -typename Foam::dynamicIndexedOctree<Type>::volumeType -Foam::dynamicIndexedOctree<Type>::calcVolumeType +Foam::volumeType Foam::dynamicIndexedOctree<Type>::calcVolumeType ( const label nodeI ) const { const node& nod = nodes_[nodeI]; - volumeType myType = UNKNOWN; + volumeType myType = volumeType::UNKNOWN; for (direction octant = 0; octant < nod.subNodes_.size(); octant++) { @@ -359,7 +358,7 @@ Foam::dynamicIndexedOctree<Type>::calcVolumeType { // Contents. Depending on position in box might be on either // side. - subType = MIXED; + subType = volumeType::MIXED; } else { @@ -378,13 +377,13 @@ Foam::dynamicIndexedOctree<Type>::calcVolumeType // Combine sub node types into type for treeNode. Result is 'mixed' if // types differ among subnodes. - if (myType == UNKNOWN) + if (myType == volumeType::UNKNOWN) { myType = subType; } else if (subType != myType) { - myType = MIXED; + myType = volumeType::MIXED; } } return myType; @@ -392,8 +391,7 @@ Foam::dynamicIndexedOctree<Type>::calcVolumeType template<class Type> -typename Foam::dynamicIndexedOctree<Type>::volumeType -Foam::dynamicIndexedOctree<Type>::getVolumeType +Foam::volumeType Foam::dynamicIndexedOctree<Type>::getVolumeType ( const label nodeI, const point& sample @@ -403,22 +401,22 @@ Foam::dynamicIndexedOctree<Type>::getVolumeType direction octant = nod.bb_.subOctant(sample); - volumeType octantType = volumeType(nodeTypes_.get((nodeI<<3)+octant)); + volumeType octantType = volumeType::type(nodeTypes_.get((nodeI<<3)+octant)); - if (octantType == INSIDE) + if (octantType == volumeType::INSIDE) { return octantType; } - else if (octantType == OUTSIDE) + else if (octantType == volumeType::OUTSIDE) { return octantType; } - else if (octantType == UNKNOWN) + else if (octantType == volumeType::UNKNOWN) { // Can happen for e.g. non-manifold surfaces. return octantType; } - else if (octantType == MIXED) + else if (octantType == volumeType::MIXED) { labelBits index = nod.subNodes_[octant]; @@ -447,7 +445,7 @@ Foam::dynamicIndexedOctree<Type>::getVolumeType << "Empty subnode has invalid volume type MIXED." << abort(FatalError); - return UNKNOWN; + return volumeType::UNKNOWN; } } else @@ -462,14 +460,13 @@ Foam::dynamicIndexedOctree<Type>::getVolumeType << "Node has invalid volume type " << octantType << abort(FatalError); - return UNKNOWN; + return volumeType::UNKNOWN; } } template<class Type> -typename Foam::dynamicIndexedOctree<Type>::volumeType -Foam::dynamicIndexedOctree<Type>::getSide +Foam::volumeType Foam::dynamicIndexedOctree<Type>::getSide ( const vector& outsideNormal, const vector& vec @@ -477,11 +474,11 @@ Foam::dynamicIndexedOctree<Type>::getSide { if ((outsideNormal&vec) >= 0) { - return OUTSIDE; + return volumeType::OUTSIDE; } else { - return INSIDE; + return volumeType::INSIDE; } } @@ -2582,15 +2579,14 @@ const Foam::labelList& Foam::dynamicIndexedOctree<Type>::findIndices // Determine type (inside/outside/mixed) per node. template<class Type> -typename Foam::dynamicIndexedOctree<Type>::volumeType -Foam::dynamicIndexedOctree<Type>::getVolumeType +Foam::volumeType Foam::dynamicIndexedOctree<Type>::getVolumeType ( const point& sample ) const { if (nodes_.empty()) { - return UNKNOWN; + return volumeType::UNKNOWN; } if (nodeTypes_.size() != 8*nodes_.size()) @@ -2598,7 +2594,7 @@ Foam::dynamicIndexedOctree<Type>::getVolumeType // Calculate type for every octant of node. nodeTypes_.setSize(8*nodes_.size()); - nodeTypes_ = UNKNOWN; + nodeTypes_ = volumeType::UNKNOWN; calcVolumeType(0); @@ -2611,21 +2607,21 @@ Foam::dynamicIndexedOctree<Type>::getVolumeType forAll(nodeTypes_, i) { - volumeType type = volumeType(nodeTypes_.get(i)); + volumeType type = volumeType::type(nodeTypes_.get(i)); - if (type == UNKNOWN) + if (type == volumeType::UNKNOWN) { nUNKNOWN++; } - else if (type == MIXED) + else if (type == volumeType::MIXED) { nMIXED++; } - else if (type == INSIDE) + else if (type == volumeType::INSIDE) { nINSIDE++; } - else if (type == OUTSIDE) + else if (type == volumeType::OUTSIDE) { nOUTSIDE++; } diff --git a/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicIndexedOctree.H b/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicIndexedOctree.H index 0bbf7a0e2ea76808020ba80aa74af13abb807eec..e0a298855f9019869207fa84cde1047c9828fd44 100644 --- a/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicIndexedOctree.H +++ b/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicIndexedOctree.H @@ -43,6 +43,7 @@ SourceFiles #include "HashSet.H" #include "labelBits.H" #include "PackedList.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -83,16 +84,6 @@ public: // Data types - //- volume types - enum volumeType - { - UNKNOWN = 0, - MIXED = 1, - INSIDE = 2, - OUTSIDE = 3 - }; - - //- Tree node. Has up pointer and down pointers. class node { diff --git a/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.C b/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.C index ebc93a63c7b5820efe1353835a1fb6fd567a5a1a..821e4ff5007bb35a1f2d07d45a98ef2a2ca0f01c 100644 --- a/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.C +++ b/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -57,13 +57,13 @@ Foam::dynamicTreeDataPoint::shapePoints() const //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. -Foam::label Foam::dynamicTreeDataPoint::getVolumeType +Foam::volumeType Foam::dynamicTreeDataPoint::getVolumeType ( const dynamicIndexedOctree<dynamicTreeDataPoint>& oc, const point& sample ) const { - return dynamicIndexedOctree<dynamicTreeDataPoint>::UNKNOWN; + return volumeType::UNKNOWN; } diff --git a/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.H b/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.H index 2cbdc0005798ba88ff03bc96cee55aebbca51589..529d923b742cadf046b19348a8d3f1b25d23a31a 100644 --- a/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.H +++ b/src/OpenFOAM/algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -43,6 +43,7 @@ SourceFiles #include "pointField.H" #include "treeBoundBox.H" #include "linePointRef.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -92,7 +93,7 @@ public: //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. - label getVolumeType + volumeType getVolumeType ( const dynamicIndexedOctree<dynamicTreeDataPoint>&, const point& diff --git a/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.C b/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.C index 83ac739941284b74848944396492962e4d5f5964..945f9d989ce6a9f870c2a6ba7732a28decd2b62f 100644 --- a/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.C +++ b/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.C @@ -356,15 +356,14 @@ Foam::label Foam::indexedOctree<Type>::compactContents // Recurses to determine status of lowest level boxes. Level above is // combination of octants below. template<class Type> -typename Foam::indexedOctree<Type>::volumeType -Foam::indexedOctree<Type>::calcVolumeType +Foam::volumeType Foam::indexedOctree<Type>::calcVolumeType ( const label nodeI ) const { const node& nod = nodes_[nodeI]; - volumeType myType = UNKNOWN; + volumeType myType = volumeType::UNKNOWN; for (direction octant = 0; octant < nod.subNodes_.size(); octant++) { @@ -381,7 +380,7 @@ Foam::indexedOctree<Type>::calcVolumeType { // Contents. Depending on position in box might be on either // side. - subType = MIXED; + subType = volumeType::MIXED; } else { @@ -389,10 +388,7 @@ Foam::indexedOctree<Type>::calcVolumeType // of its bounding box. const treeBoundBox subBb = nod.bb_.subBbox(octant); - subType = volumeType - ( - shapes_.getVolumeType(*this, subBb.midpoint()) - ); + subType = shapes_.getVolumeType(*this, subBb.midpoint()); } // Store octant type @@ -400,13 +396,13 @@ Foam::indexedOctree<Type>::calcVolumeType // Combine sub node types into type for treeNode. Result is 'mixed' if // types differ among subnodes. - if (myType == UNKNOWN) + if (myType == volumeType::UNKNOWN) { myType = subType; } else if (subType != myType) { - myType = MIXED; + myType = volumeType::MIXED; } } return myType; @@ -414,8 +410,7 @@ Foam::indexedOctree<Type>::calcVolumeType template<class Type> -typename Foam::indexedOctree<Type>::volumeType -Foam::indexedOctree<Type>::getVolumeType +Foam::volumeType Foam::indexedOctree<Type>::getVolumeType ( const label nodeI, const point& sample @@ -425,22 +420,22 @@ Foam::indexedOctree<Type>::getVolumeType direction octant = nod.bb_.subOctant(sample); - volumeType octantType = volumeType(nodeTypes_.get((nodeI<<3)+octant)); + volumeType octantType = volumeType::type(nodeTypes_.get((nodeI<<3)+octant)); - if (octantType == INSIDE) + if (octantType == volumeType::INSIDE) { return octantType; } - else if (octantType == OUTSIDE) + else if (octantType == volumeType::OUTSIDE) { return octantType; } - else if (octantType == UNKNOWN) + else if (octantType == volumeType::UNKNOWN) { // Can happen for e.g. non-manifold surfaces. return octantType; } - else if (octantType == MIXED) + else if (octantType == volumeType::MIXED) { labelBits index = nod.subNodes_[octant]; @@ -469,7 +464,7 @@ Foam::indexedOctree<Type>::getVolumeType << "Empty subnode has invalid volume type MIXED." << abort(FatalError); - return UNKNOWN; + return volumeType::UNKNOWN; } } else @@ -484,14 +479,13 @@ Foam::indexedOctree<Type>::getVolumeType << "Node has invalid volume type " << octantType << abort(FatalError); - return UNKNOWN; + return volumeType::UNKNOWN; } } template<class Type> -typename Foam::indexedOctree<Type>::volumeType -Foam::indexedOctree<Type>::getSide +Foam::volumeType Foam::indexedOctree<Type>::getSide ( const vector& outsideNormal, const vector& vec @@ -499,11 +493,11 @@ Foam::indexedOctree<Type>::getSide { if ((outsideNormal&vec) >= 0) { - return OUTSIDE; + return volumeType::OUTSIDE; } else { - return INSIDE; + return volumeType::INSIDE; } } @@ -576,6 +570,7 @@ Foam::indexedOctree<Type>::getSide // Find nearest point starting from nodeI template<class Type> +template<class FindNearestOp> void Foam::indexedOctree<Type>::findNearest ( const label nodeI, @@ -583,7 +578,9 @@ void Foam::indexedOctree<Type>::findNearest scalar& nearestDistSqr, label& nearestShapeI, - point& nearestPoint + point& nearestPoint, + + const FindNearestOp& fnOp ) const { const node& nod = nodes_[nodeI]; @@ -614,7 +611,9 @@ void Foam::indexedOctree<Type>::findNearest nearestDistSqr, nearestShapeI, - nearestPoint + nearestPoint, + + fnOp ); } } @@ -631,7 +630,7 @@ void Foam::indexedOctree<Type>::findNearest ) ) { - shapes_.findNearest + fnOp ( contents_[getContent(index)], sample, @@ -648,6 +647,7 @@ void Foam::indexedOctree<Type>::findNearest // Find nearest point to line. template<class Type> +template<class FindNearestOp> void Foam::indexedOctree<Type>::findNearest ( const label nodeI, @@ -656,7 +656,9 @@ void Foam::indexedOctree<Type>::findNearest treeBoundBox& tightest, label& nearestShapeI, point& linePoint, - point& nearestPoint + point& nearestPoint, + + const FindNearestOp& fnOp ) const { const node& nod = nodes_[nodeI]; @@ -687,7 +689,9 @@ void Foam::indexedOctree<Type>::findNearest tightest, nearestShapeI, linePoint, - nearestPoint + nearestPoint, + + fnOp ); } } @@ -697,7 +701,7 @@ void Foam::indexedOctree<Type>::findNearest if (subBb.overlaps(tightest)) { - shapes_.findNearest + fnOp ( contents_[getContent(index)], ln, @@ -1620,6 +1624,7 @@ Foam::word Foam::indexedOctree<Type>::faceString // hitInfo.point = coordinate of intersection of ray with bounding box // hitBits = posbits of point on bounding box template<class Type> +template<class FindIntersectOp> void Foam::indexedOctree<Type>::traverseNode ( const bool findAny, @@ -1632,7 +1637,9 @@ void Foam::indexedOctree<Type>::traverseNode const direction octant, pointIndexHit& hitInfo, - direction& hitBits + direction& hitBits, + + const FindIntersectOp& fiOp ) const { if (debug) @@ -1667,7 +1674,7 @@ void Foam::indexedOctree<Type>::traverseNode label shapeI = indices[elemI]; point pt; - bool hit = shapes_.intersects(shapeI, start, end, pt); + bool hit = fiOp(shapeI, start, end, pt); // Note that intersection of shape might actually be // in a neighbouring box. For findAny this is not important. @@ -1695,13 +1702,7 @@ void Foam::indexedOctree<Type>::traverseNode label shapeI = indices[elemI]; point pt; - bool hit = shapes_.intersects - ( - shapeI, - start, - nearestPoint, - pt - ); + bool hit = fiOp(shapeI, start, nearestPoint, pt); // Note that intersection of shape might actually be // in a neighbouring box. Since we need to maintain strict @@ -1774,7 +1775,9 @@ void Foam::indexedOctree<Type>::traverseNode octant, hitInfo, - hitBits + hitBits, + + fiOp ); } } @@ -1782,6 +1785,7 @@ void Foam::indexedOctree<Type>::traverseNode // Find first intersection template<class Type> +template<class FindIntersectOp> Foam::pointIndexHit Foam::indexedOctree<Type>::findLine ( const bool findAny, @@ -1789,6 +1793,7 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine const point& treeEnd, const label startNodeI, const direction startOctant, + const FindIntersectOp& fiOp, const bool verbose ) const { @@ -1864,7 +1869,9 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine octant, hitInfo, - hitFaceID + hitFaceID, + + fiOp ); // Did we hit a triangle? @@ -1948,7 +1955,8 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine treeEnd, startNodeI, startOctant, - true //verbose + fiOp, + true //verbose, ); } if (debug) @@ -2007,11 +2015,13 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine // Find first intersection template<class Type> +template<class FindIntersectOp> Foam::pointIndexHit Foam::indexedOctree<Type>::findLine ( const bool findAny, const point& start, - const point& end + const point& end, + const FindIntersectOp& fiOp ) const { pointIndexHit hitInfo; @@ -2069,7 +2079,8 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine trackStart, trackEnd, parentNodeI, - octant + octant, + fiOp ); } @@ -2656,6 +2667,25 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findNearest const point& sample, const scalar startDistSqr ) const +{ + return findNearest + ( + sample, + startDistSqr, + typename Type::findNearestOp(*this) + ); +} + + +template <class Type> +template <class FindNearestOp> +Foam::pointIndexHit Foam::indexedOctree<Type>::findNearest +( + const point& sample, + const scalar startDistSqr, + + const FindNearestOp& fnOp +) const { scalar nearestDistSqr = startDistSqr; label nearestShapeI = -1; @@ -2670,7 +2700,9 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findNearest nearestDistSqr, nearestShapeI, - nearestPoint + nearestPoint, + + fnOp ); } @@ -2685,6 +2717,27 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findNearest treeBoundBox& tightest, point& linePoint ) const +{ + return findNearest + ( + ln, + tightest, + linePoint, + typename Type::findNearestOp(*this) + ); +} + + +template <class Type> +template <class FindNearestOp> +Foam::pointIndexHit Foam::indexedOctree<Type>::findNearest +( + const linePointRef& ln, + treeBoundBox& tightest, + point& linePoint, + + const FindNearestOp& fnOp +) const { label nearestShapeI = -1; point nearestPoint = vector::zero; @@ -2699,7 +2752,9 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findNearest tightest, nearestShapeI, linePoint, - nearestPoint + nearestPoint, + + fnOp ); } @@ -2715,7 +2770,13 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine const point& end ) const { - return findLine(false, start, end); + return findLine + ( + false, + start, + end, + typename Type::findIntersectOp(*this) + ); } @@ -2727,7 +2788,41 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLineAny const point& end ) const { - return findLine(true, start, end); + return findLine + ( + true, + start, + end, + typename Type::findIntersectOp(*this) + ); +} + + +// Find nearest intersection +template <class Type> +template <class FindIntersectOp> +Foam::pointIndexHit Foam::indexedOctree<Type>::findLine +( + const point& start, + const point& end, + const FindIntersectOp& fiOp +) const +{ + return findLine(false, start, end, fiOp); +} + + +// Find nearest intersection +template <class Type> +template <class FindIntersectOp> +Foam::pointIndexHit Foam::indexedOctree<Type>::findLineAny +( + const point& start, + const point& end, + const FindIntersectOp& fiOp +) const +{ + return findLine(true, start, end, fiOp); } @@ -2871,23 +2966,29 @@ const Foam::labelList& Foam::indexedOctree<Type>::findIndices // Determine type (inside/outside/mixed) per node. template<class Type> -typename Foam::indexedOctree<Type>::volumeType -Foam::indexedOctree<Type>::getVolumeType +Foam::volumeType Foam::indexedOctree<Type>::getVolumeType ( const point& sample ) const { if (nodes_.empty()) { - return UNKNOWN; + return volumeType::UNKNOWN; } +// // If the sample is not within the octree, then have to query shapes +// // directly +// if (!nodes_[0].bb_.contains(sample)) +// { +// return volumeType(shapes_.getVolumeType(*this, sample)); +// } + if (nodeTypes_.size() != 8*nodes_.size()) { // Calculate type for every octant of node. nodeTypes_.setSize(8*nodes_.size()); - nodeTypes_ = UNKNOWN; + nodeTypes_ = volumeType::UNKNOWN; calcVolumeType(0); @@ -2900,21 +3001,21 @@ Foam::indexedOctree<Type>::getVolumeType forAll(nodeTypes_, i) { - volumeType type = volumeType(nodeTypes_.get(i)); + volumeType type = volumeType::type(nodeTypes_.get(i)); - if (type == UNKNOWN) + if (type == volumeType::UNKNOWN) { nUNKNOWN++; } - else if (type == MIXED) + else if (type == volumeType::MIXED) { nMIXED++; } - else if (type == INSIDE) + else if (type == volumeType::INSIDE) { nINSIDE++; } - else if (type == OUTSIDE) + else if (type == volumeType::OUTSIDE) { nOUTSIDE++; } diff --git a/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.H b/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.H index 6a5c56ac7bb2d7f7900677668d274beeffba177e..229993e406ca3d56ac06b6a2a610983901c260eb 100644 --- a/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.H +++ b/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.H @@ -42,6 +42,7 @@ SourceFiles #include "HashSet.H" #include "labelBits.H" #include "PackedList.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -74,16 +75,6 @@ public: // Data types - //- volume types - enum volumeType - { - UNKNOWN = 0, - MIXED = 1, - INSIDE = 2, - OUTSIDE = 3 - }; - - //- Tree node. Has up pointer and down pointers. class node { @@ -212,6 +203,7 @@ private: // Query //- Find nearest point to line. + template <class FindNearestOp> void findNearest ( const label nodeI, @@ -220,7 +212,9 @@ private: treeBoundBox& tightest, label& nearestShapeI, point& linePoint, - point& nearestPoint + point& nearestPoint, + + const FindNearestOp& fnOp ) const; //- Return bbox of octant @@ -294,6 +288,7 @@ private: // intersection point. // findAny=true : return any intersection // findAny=false: return nearest (to start) intersection + template <class FindIntersectOp> void traverseNode ( const bool findAny, @@ -306,10 +301,13 @@ private: const direction octantI, pointIndexHit& hitInfo, - direction& faceID + direction& faceID, + + const FindIntersectOp& fiOp ) const; //- Find any or nearest intersection + template <class FindIntersectOp> pointIndexHit findLine ( const bool findAny, @@ -317,6 +315,7 @@ private: const point& treeEnd, const label startNodeI, const direction startOctantI, + const FindIntersectOp& fiOp, const bool verbose = false ) const; @@ -328,11 +327,13 @@ private: // ) const; //- Find any or nearest intersection of line between start and end. + template <class FindIntersectOp> pointIndexHit findLine ( const bool findAny, const point& start, - const point& end + const point& end, + const FindIntersectOp& fiOp ) const; //- Find all elements intersecting box. @@ -528,15 +529,24 @@ public: // Queries + pointIndexHit findNearest + ( + const point& sample, + const scalar nearestDistSqr + ) const; + //- Calculate nearest point on nearest shape. // Returns // - bool : any point found nearer than nearestDistSqr // - label: index in shapes // - point: actual nearest point found + template <class FindNearestOp> pointIndexHit findNearest ( const point& sample, - const scalar nearestDistSqr + const scalar nearestDistSqr, + + const FindNearestOp& fnOp ) const; // bool findAnyOverlap @@ -553,6 +563,7 @@ public: // ) const; //- Low level: calculate nearest starting from subnode. + template <class FindNearestOp> void findNearest ( const label nodeI, @@ -560,7 +571,9 @@ public: scalar& nearestDistSqr, label& nearestShapeI, - point& nearestPoint + point& nearestPoint, + + const FindNearestOp& fnOp ) const; //- Find nearest to line. @@ -577,6 +590,16 @@ public: point& linePoint ) const; + template <class FindNearestOp> + pointIndexHit findNearest + ( + const linePointRef& ln, + treeBoundBox& tightest, + point& linePoint, + + const FindNearestOp& fnOp + ) const; + //- Find nearest intersection of line between start and end. pointIndexHit findLine ( @@ -591,6 +614,24 @@ public: const point& end ) const; + //- Find nearest intersection of line between start and end. + template <class FindIntersectOp> + pointIndexHit findLine + ( + const point& start, + const point& end, + const FindIntersectOp& fiOp + ) const; + + //- Find any intersection of line between start and end. + template <class FindIntersectOp> + pointIndexHit findLineAny + ( + const point& start, + const point& end, + const FindIntersectOp& fiOp + ) const; + //- Find (in no particular order) indices of all shapes inside or // overlapping bounding box (i.e. all shapes not outside box) labelList findBox(const treeBoundBox& bb) const; diff --git a/src/OpenFOAM/algorithms/indexedOctree/treeDataCell.C b/src/OpenFOAM/algorithms/indexedOctree/treeDataCell.C index e4d78fc83d6d5e22bbad3598446f546dc28f391c..2ab17d0de855e57bbb6def51fefbc446da6fa3ce 100644 --- a/src/OpenFOAM/algorithms/indexedOctree/treeDataCell.C +++ b/src/OpenFOAM/algorithms/indexedOctree/treeDataCell.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -133,6 +133,24 @@ Foam::treeDataCell::treeDataCell } +Foam::treeDataCell::findNearestOp::findNearestOp +( + const indexedOctree<treeDataCell>& tree +) +: + tree_(tree) +{} + + +Foam::treeDataCell::findIntersectOp::findIntersectOp +( + const indexedOctree<treeDataCell>& tree +) +: + tree_(tree) +{} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // Foam::pointField Foam::treeDataCell::shapePoints() const @@ -175,7 +193,7 @@ bool Foam::treeDataCell::contains } -void Foam::treeDataCell::findNearest +void Foam::treeDataCell::findNearestOp::operator() ( const labelUList& indices, const point& sample, @@ -185,23 +203,51 @@ void Foam::treeDataCell::findNearest point& nearestPoint ) const { + const treeDataCell& shape = tree_.shapes(); + forAll(indices, i) { label index = indices[i]; - label cellI = cellLabels_[index]; - scalar distSqr = magSqr(sample - mesh_.cellCentres()[cellI]); + label cellI = shape.cellLabels()[index]; + scalar distSqr = magSqr(sample - shape.mesh().cellCentres()[cellI]); if (distSqr < nearestDistSqr) { nearestDistSqr = distSqr; minIndex = index; - nearestPoint = mesh_.cellCentres()[cellI]; + nearestPoint = shape.mesh().cellCentres()[cellI]; } } } -bool Foam::treeDataCell::intersects +void Foam::treeDataCell::findNearestOp::operator() +( + const labelUList& indices, + const linePointRef& ln, + + treeBoundBox& tightest, + label& minIndex, + point& linePoint, + point& nearestPoint +) const +{ + notImplemented + ( + "treeDataCell::findNearestOp::operator()" + "(" + " const labelUList&," + " const linePointRef&," + " treeBoundBox&," + " label&," + " point&," + " point&" + ") const" + ); +} + + +bool Foam::treeDataCell::findIntersectOp::operator() ( const label index, const point& start, @@ -209,10 +255,12 @@ bool Foam::treeDataCell::intersects point& intersectionPoint ) const { + const treeDataCell& shape = tree_.shapes(); + // Do quick rejection test - if (cacheBb_) + if (shape.cacheBb_) { - const treeBoundBox& cellBb = bbs_[index]; + const treeBoundBox& cellBb = shape.bbs_[index]; if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0) { @@ -222,7 +270,7 @@ bool Foam::treeDataCell::intersects } else { - const treeBoundBox cellBb = calcCellBb(cellLabels_[index]); + const treeBoundBox cellBb = shape.calcCellBb(shape.cellLabels_[index]); if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0) { @@ -238,7 +286,7 @@ bool Foam::treeDataCell::intersects // Disable picking up intersections behind us. scalar oldTol = intersection::setPlanarTol(0.0); - const cell& cFaces = mesh_.cells()[cellLabels_[index]]; + const cell& cFaces = shape.mesh_.cells()[shape.cellLabels_[index]]; const vector dir(end - start); scalar minDistSqr = magSqr(dir); @@ -246,13 +294,13 @@ bool Foam::treeDataCell::intersects forAll(cFaces, i) { - const face& f = mesh_.faces()[cFaces[i]]; + const face& f = shape.mesh_.faces()[cFaces[i]]; pointHit inter = f.ray ( start, dir, - mesh_.points(), + shape.mesh_.points(), intersection::HALF_RAY ); diff --git a/src/OpenFOAM/algorithms/indexedOctree/treeDataCell.H b/src/OpenFOAM/algorithms/indexedOctree/treeDataCell.H index 476266faf9a741f1c93eb6962876331fb67fa760..c302f6cbecedd3e1400f29ce40f531145f805dc1 100644 --- a/src/OpenFOAM/algorithms/indexedOctree/treeDataCell.H +++ b/src/OpenFOAM/algorithms/indexedOctree/treeDataCell.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -38,6 +38,7 @@ SourceFiles #include "polyMesh.H" #include "treeBoundBoxList.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -80,6 +81,56 @@ class treeDataCell public: + + class findNearestOp + { + const indexedOctree<treeDataCell>& tree_; + + public: + + findNearestOp(const indexedOctree<treeDataCell>& tree); + + void operator() + ( + const labelUList& indices, + const point& sample, + + scalar& nearestDistSqr, + label& minIndex, + point& nearestPoint + ) const; + + void operator() + ( + const labelUList& indices, + const linePointRef& ln, + + treeBoundBox& tightest, + label& minIndex, + point& linePoint, + point& nearestPoint + ) const; + }; + + + class findIntersectOp + { + const indexedOctree<treeDataCell>& tree_; + + public: + + findIntersectOp(const indexedOctree<treeDataCell>& tree); + + bool operator() + ( + const label index, + const point& start, + const point& end, + point& intersectionPoint + ) const; + }; + + // Declare name of the class and its debug switch ClassName("treeDataCell"); @@ -146,7 +197,7 @@ public: //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. - label getVolumeType + volumeType getVolumeType ( const indexedOctree<treeDataCell>&, const point& @@ -157,7 +208,7 @@ public: "treeDataCell::getVolumeType" "(const indexedOctree<treeDataCell>&, const point&)" ); - return -1; + return volumeType::UNKNOWN; } //- Does (bb of) shape at index overlap bb @@ -173,49 +224,6 @@ public: const label index, const point& sample ) const; - - //- Calculates nearest (to sample) point in shape. - // Returns actual point and distance (squared) - void findNearest - ( - const labelUList& indices, - const point& sample, - - scalar& nearestDistSqr, - label& nearestIndex, - point& nearestPoint - ) const; - - //- Calculates nearest (to line) point in shape. - // Returns point and distance (squared) - void findNearest - ( - const labelUList& indices, - const linePointRef& ln, - - treeBoundBox& tightest, - label& minIndex, - point& linePoint, - point& nearestPoint - ) const - { - notImplemented - ( - "treeDataCell::findNearest" - "(const labelUList&, const linePointRef&, ..)" - ); - } - - //- Calculate intersection of shape with ray. Sets result - // accordingly - bool intersects - ( - const label index, - const point& start, - const point& end, - point& result - ) const; - }; diff --git a/src/OpenFOAM/algorithms/indexedOctree/volumeType.C b/src/OpenFOAM/algorithms/indexedOctree/volumeType.C new file mode 100644 index 0000000000000000000000000000000000000000..95868f6c0c3f58e105b82ece76ecda59924daf50 --- /dev/null +++ b/src/OpenFOAM/algorithms/indexedOctree/volumeType.C @@ -0,0 +1,79 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "volumeType.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + template<> + const char* Foam::NamedEnum + < + Foam::volumeType, + 4 + >::names[] = + { + "unknown", + "mixed", + "inside", + "outside" + }; +} + +const Foam::NamedEnum<Foam::volumeType, 4> Foam::volumeType::names; + + +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // + +Foam::Istream& Foam::operator>>(Istream& is, volumeType& vt) +{ + // Read beginning of volumeType + is.readBegin("volumeType"); + + int type; + is >> type; + + vt.t_ = static_cast<volumeType::type>(type); + + // Read end of volumeType + is.readEnd("volumeType"); + + // Check state of Istream + is.check("operator>>(Istream&, volumeType&)"); + + return is; +} + + +Foam::Ostream& Foam::operator<<(Ostream& os, const volumeType& vt) +{ + os << static_cast<int>(vt.t_); + + return os; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/algorithms/indexedOctree/volumeType.H b/src/OpenFOAM/algorithms/indexedOctree/volumeType.H new file mode 100644 index 0000000000000000000000000000000000000000..7bdfc043e6024e5b3a2417dbd4d8960b4927515a --- /dev/null +++ b/src/OpenFOAM/algorithms/indexedOctree/volumeType.H @@ -0,0 +1,127 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-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 <http://www.gnu.org/licenses/>. + +Class + Foam::volumeType + +Description + +SourceFiles + volumeType.C + +\*---------------------------------------------------------------------------*/ + +#ifndef volumeType_H +#define volumeType_H + +#include "NamedEnum.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of friend functions and operators + +class volumeType; +Istream& operator>>(Istream& is, volumeType&); +Ostream& operator<<(Ostream& os, const volumeType& C); + + +/*---------------------------------------------------------------------------*\ + Class volumeType Declaration +\*---------------------------------------------------------------------------*/ + +class volumeType +{ +public: + + //- Volume types + enum type + { + UNKNOWN = 0, + MIXED = 1, + INSIDE = 2, + OUTSIDE = 3 + }; + + +private: + + // Private data + + //- Volume type + type t_; + + +public: + + // Static data + + static const NamedEnum<volumeType, 4> names; + + + // Constructors + + //- Construct null + volumeType() + : + t_(UNKNOWN) + {} + + //- Construct from components + volumeType(type t) + : + t_(t) + {} + + + // Member Functions + + operator type() const + { + return t_; + } + + + // IOstream operators + + friend Istream& operator>>(Istream& is, volumeType& vt); + friend Ostream& operator<<(Ostream& os, const volumeType& vt); +}; + + +//- Data associated with volumeType type are contiguous +template<> +inline bool contiguous<volumeType>() {return true;} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H index f878a6f969deba67665afa3aab561d7a2426448f..c322c7856faae1accc1c36db8790131b1eb3e5c5 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H @@ -92,14 +92,23 @@ void inplaceMapKey(const labelUList& oldToNew, Container&); template<class T> void sortedOrder(const UList<T>&, labelList& order); +template<class T, class Cmp> +void sortedOrder(const UList<T>&, labelList& order, const Cmp& cmp); + //- Generate (sorted) indices corresponding to duplicate list values template<class T> void duplicateOrder(const UList<T>&, labelList& order); +template<class T, class Cmp> +void duplicateOrder(const UList<T>&, labelList& order, const Cmp& cmp); + //- Generate (sorted) indices corresponding to unique list values template<class T> void uniqueOrder(const UList<T>&, labelList& order); +template<class T, class Cmp> +void uniqueOrder(const UList<T>&, labelList& order, const Cmp& cmp); + //- Extract elements of List when select is a certain value. // eg, to extract all selected elements: // subset<bool, labelList>(selectedElems, true, lst); diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C index ab6f9bf511e90a28abee4852d5e1d0ee4a40a53e..29ea65055121aedf96dc1ac262601134c97e6953 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C @@ -180,6 +180,18 @@ void Foam::sortedOrder const UList<T>& lst, labelList& order ) +{ + sortedOrder(lst, order, typename UList<T>::less(lst)); +} + + +template<class T, class Cmp> +void Foam::sortedOrder +( + const UList<T>& lst, + labelList& order, + const Cmp& cmp +) { // list lengths must be identical if (order.size() != lst.size()) @@ -193,7 +205,7 @@ void Foam::sortedOrder { order[elemI] = elemI; } - Foam::stableSort(order, typename UList<T>::less(lst)); + Foam::stableSort(order, cmp); } @@ -203,6 +215,18 @@ void Foam::duplicateOrder const UList<T>& lst, labelList& order ) +{ + duplicateOrder(lst, order, typename UList<T>::less(lst)); +} + + +template<class T, class Cmp> +void Foam::duplicateOrder +( + const UList<T>& lst, + labelList& order, + const Cmp& cmp +) { if (lst.size() < 2) { @@ -210,7 +234,7 @@ void Foam::duplicateOrder return; } - sortedOrder(lst, order); + sortedOrder(lst, order, cmp); label n = 0; for (label i = 0; i < order.size() - 1; ++i) @@ -231,7 +255,19 @@ void Foam::uniqueOrder labelList& order ) { - sortedOrder(lst, order); + uniqueOrder(lst, order, typename UList<T>::less(lst)); +} + + +template<class T, class Cmp> +void Foam::uniqueOrder +( + const UList<T>& lst, + labelList& order, + const Cmp& cmp +) +{ + sortedOrder(lst, order, cmp); if (order.size() > 1) { diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C b/src/OpenFOAM/containers/Lists/SortableList/SortableList.C index e7613ab1ab2c6fff2bdbb724e2f1c1018d631b83..d610a56a04cdf408325dcb8a8b1b805d53945563 100644 --- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C +++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,26 +23,7 @@ License \*---------------------------------------------------------------------------*/ -// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // - -template<class T> -void Foam::SortableList<T>::sortIndices(List<label>& order) const -{ - // list lengths must be identical - if (order.size() != this->size()) - { - // avoid copying any elements, they are overwritten anyhow - order.clear(); - order.setSize(this->size()); - } - - forAll(order, elemI) - { - order[elemI] = elemI; - } - Foam::stableSort(order, typename UList<T>::less(*this)); -} - +#include "ListOps.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -113,7 +94,7 @@ Foam::List<T>& Foam::SortableList<T>::shrink() template<class T> void Foam::SortableList<T>::sort() { - sortIndices(indices_); + sortedOrder(*this, indices_); List<T> lst(this->size()); forAll(indices_, i) @@ -128,13 +109,12 @@ void Foam::SortableList<T>::sort() template<class T> void Foam::SortableList<T>::reverseSort() { - sortIndices(indices_); + sortedOrder(*this, indices_, typename UList<T>::greater(*this)); List<T> lst(this->size()); - label endI = indices_.size(); forAll(indices_, i) { - lst[--endI] = this->operator[](indices_[i]); + lst[i] = this->operator[](indices_[i]); } List<T>::transfer(lst); diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H index 1e62f39109e7952b9594441ba156db2bec227259..2d7b31a9e89ff315670d6608d23882528294d985 100644 --- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H +++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -59,8 +59,6 @@ class SortableList //- Original indices labelList indices_; - //- Resize, fill and sort the parameter according to the list values - void sortIndices(List<label>&) const; public: diff --git a/src/OpenFOAM/containers/Lists/UList/UList.H b/src/OpenFOAM/containers/Lists/UList/UList.H index 92557d3d352936354a00c01b8ca8cca78676cfaf..f61d6df7493ee2a7309aa2925b394002f236abd7 100644 --- a/src/OpenFOAM/containers/Lists/UList/UList.H +++ b/src/OpenFOAM/containers/Lists/UList/UList.H @@ -113,6 +113,24 @@ public: } }; + //- Greater function class that can be used for sorting + class greater + { + const UList<T>& values_; + + public: + + greater(const UList<T>& values) + : + values_(values) + {} + + bool operator()(const label a, const label b) + { + return values_[a] > values_[b]; + } + }; + // Constructors diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H index 24ad5d3d1ccf920dd401a01b81edbe5354635d06..11f7d966bf7d1379fac7264751bf137131da1554 100644 --- a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H +++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -169,6 +169,16 @@ public: const scalar tol = 0.0 ) const; + inline pointHit intersection + ( + const point& p, + const vector& q, + const point& ctr, + const pointField& points, + const intersection::algorithm alg, + const scalar tol = 0.0 + ) const; + //- Return nearest point to face inline pointHit nearestPoint ( diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H index 6326c5cc6649246d7f67566ce51ed9ee1c36f3ed..b956780df4138ec0f0c4c8b7c52154bc292cdfd1 100644 --- a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H +++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -273,6 +273,20 @@ inline Foam::pointHit Foam::triFace::intersection } +inline Foam::pointHit Foam::triFace::intersection +( + const point& p, + const vector& q, + const point& ctr, + const pointField& points, + const intersection::algorithm alg, + const scalar tol +) const +{ + return intersection(p, q, points, alg, tol); +} + + inline Foam::pointHit Foam::triFace::nearestPoint ( const point& p, diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H index 36e792326dfaaf11e594396b1bae817e9953ec5f..e0800452a177d7cd26cdc1db1f9272e9e75a7d31 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H +++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H @@ -54,6 +54,7 @@ namespace Foam class polyMesh; class PackedBoolList; +class boundBox; /*---------------------------------------------------------------------------*\ Class PatchTools Declaration @@ -140,6 +141,21 @@ public: labelList& faceMap ); + //- + template + < + class Face, + template<class> class FaceList, + class PointField, + class PointType + > + static void calcBounds + ( + const PrimitivePatch<Face, FaceList, PointField, PointType>& p, + boundBox& bb, + label& nPoints + ); + //- Return edge-face addressing sorted by angle around the edge. // Orientation is anticlockwise looking from edge.vec(localPoints()) template @@ -271,7 +287,6 @@ public: List<Face>& mergedFaces, labelList& pointMergeMap ); - }; diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C index 4fc6ca13c712f58c08906fcbc9272e80eba9932b..8ecd790b1ee6f1dd9cd5483b05d7f9c7e0922451 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C +++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -27,6 +27,8 @@ Description \*---------------------------------------------------------------------------*/ #include "PatchTools.H" +#include "PackedBoolList.H" +#include "boundBox.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -222,4 +224,45 @@ Foam::PatchTools::subsetMap } +template +< + class Face, + template<class> class FaceList, + class PointField, + class PointType +> +void Foam::PatchTools::calcBounds +( + const PrimitivePatch<Face, FaceList, PointField, PointType>& p, + boundBox& bb, + label& nPoints +) +{ + // Unfortunately nPoints constructs meshPoints() so do compact version + // ourselves + const PointField& points = p.points(); + + PackedBoolList pointIsUsed(points.size()); + + nPoints = 0; + bb = boundBox::invertedBox; + + forAll(p, faceI) + { + const Face& f = p[faceI]; + + forAll(f, fp) + { + label pointI = f[fp]; + if (pointIsUsed.set(pointI, 1u)) + { + bb.min() = ::Foam::min(bb.min(), points[pointI]); + bb.max() = ::Foam::max(bb.max(), points[pointI]); + nPoints++; + } + } + } +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/meshes/primitiveShapes/objectHit/PointHit.H b/src/OpenFOAM/meshes/primitiveShapes/objectHit/PointHit.H index 716bf88f734f9685622bf347b72b9c55ac293728..3e2e4dd6986d8cbfd8ef8df5edb6d0145fac3cdf 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/objectHit/PointHit.H +++ b/src/OpenFOAM/meshes/primitiveShapes/objectHit/PointHit.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -81,6 +81,15 @@ public: // Constructors + //- Construct null + PointHit() + : + hit_(false), + hitPoint_(vector::zero), + distance_(GREAT), + eligibleMiss_(false) + {} + //- Construct from components PointHit ( diff --git a/src/OpenFOAM/meshes/primitiveShapes/plane/plane.H b/src/OpenFOAM/meshes/primitiveShapes/plane/plane.H index 3d4e25211c10508a884ca36ee733b2946691c2f6..3a47e6bf2ea0c9e0b7fdacfcd39885163cedaede 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/plane/plane.H +++ b/src/OpenFOAM/meshes/primitiveShapes/plane/plane.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -26,7 +26,7 @@ Class Description Geometric class that creates a 2D plane and can return the intersection - point between a line and the plane. + point between a line and the plane. SourceFiles plane.C @@ -62,6 +62,14 @@ class plane { public: + //- Side of the plane + enum side + { + NORMAL, + FLIP + }; + + //- A direction and a reference point class ray { @@ -182,6 +190,10 @@ public: //- Return the cutting point between this plane and two other planes point planePlaneIntersect(const plane&, const plane&) const; + //- Return the side of the plane that the point is on. + // If the point is on the plane, then returns NORMAL. + side sideOfPlane(const point& p) const; + //- Write to dictionary void writeDict(Ostream&) const; diff --git a/src/dynamicMesh/boundaryMesh/boundaryMesh.C b/src/dynamicMesh/boundaryMesh/boundaryMesh.C index 1abf219dfb58dfd1306c8835ce0333c16952fb45..ad204d7c157fd9dad6c692a2b10447017a0fd924 100644 --- a/src/dynamicMesh/boundaryMesh/boundaryMesh.C +++ b/src/dynamicMesh/boundaryMesh/boundaryMesh.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -924,6 +924,11 @@ Foam::labelList Foam::boundaryMesh::getNearest bbMax.y() += 2*tol; bbMax.z() += 2*tol; + const scalar planarTol = + indexedOctree<treeDataPrimitivePatch<uindirectPrimitivePatch> >:: + perturbTol(); + + // Create the octrees indexedOctree < @@ -933,7 +938,8 @@ Foam::labelList Foam::boundaryMesh::getNearest treeDataPrimitivePatch<uindirectPrimitivePatch> ( false, // cacheBb - leftPatch + leftPatch, + planarTol ), overallBb, 10, // maxLevel @@ -948,7 +954,8 @@ Foam::labelList Foam::boundaryMesh::getNearest treeDataPrimitivePatch<uindirectPrimitivePatch> ( false, // cacheBb - rightPatch + rightPatch, + planarTol ), overallBb, 10, // maxLevel diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolationScheme/surfaceInterpolationScheme.C b/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolationScheme/surfaceInterpolationScheme.C index 1a699590953e2e94da8d701e8f989521169ebf47..f66c3acfa6e047eba3f95f563e74824a9a7cb3cd 100644 --- a/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolationScheme/surfaceInterpolationScheme.C +++ b/src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolationScheme/surfaceInterpolationScheme.C @@ -241,7 +241,7 @@ surfaceInterpolationScheme<Type>::interpolate //- Return the face-interpolate of the given cell field -// with the given weigting factors +// with the given weighting factors template<class Type> tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > surfaceInterpolationScheme<Type>::interpolate diff --git a/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C b/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C index a45a06a6b2c735d34770d51937a9d9f536ac75e3..f53968532c36a0b54c38a0a215bf92517b904793 100644 --- a/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C +++ b/src/mesh/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C @@ -31,6 +31,7 @@ License #include "labelPair.H" #include "searchableSurfacesQueries.H" #include "UPtrList.H" +#include "volumeType.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -1302,7 +1303,7 @@ void Foam::refinementSurfaces::findInside if (allGeometry_[surfaces_[surfI]].hasVolumeType()) { - List<searchableSurface::volumeType> volType; + List<volumeType> volType; allGeometry_[surfaces_[surfI]].getVolumeType(pt, volType); forAll(volType, pointI) @@ -1312,11 +1313,11 @@ void Foam::refinementSurfaces::findInside if ( ( - volType[pointI] == triSurfaceMesh::INSIDE + volType[pointI] == volumeType::INSIDE && zoneInside_[surfI] == INSIDE ) || ( - volType[pointI] == triSurfaceMesh::OUTSIDE + volType[pointI] == volumeType::OUTSIDE && zoneInside_[surfI] == OUTSIDE ) ) diff --git a/src/mesh/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C b/src/mesh/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C index bc3289f18e13055f6189ffa357300e970e6ad499..a7a44f3fbfb388de08469b2a80f6616d4b31c685 100644 --- a/src/mesh/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C +++ b/src/mesh/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -31,6 +31,7 @@ License #include "searchableSurfaces.H" #include "orientedSurface.H" #include "pointIndexHit.H" +#include "volumeType.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -329,7 +330,7 @@ void Foam::shellSurfaces::findHigherLevel candidateMap.setSize(candidateI); // Do the expensive nearest test only for the candidate points. - List<searchableSurface::volumeType> volType; + List<volumeType> volType; allGeometry_[shells_[shellI]].getVolumeType(candidates, volType); forAll(volType, i) @@ -340,11 +341,11 @@ void Foam::shellSurfaces::findHigherLevel ( ( modes_[shellI] == INSIDE - && volType[i] == searchableSurface::INSIDE + && volType[i] == volumeType::INSIDE ) || ( modes_[shellI] == OUTSIDE - && volType[i] == searchableSurface::OUTSIDE + && volType[i] == volumeType::OUTSIDE ) ) { diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C index 920c78228682b85f6bcfbf1143e77eb5a85667b2..9c145081342bd8b36d0e3cf4a5a9d9b26ce89d03 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C @@ -210,7 +210,12 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::resetTree() ( new indexedOctree<treeType> ( - treeType(false, tgtPatch_), + treeType + ( + false, + tgtPatch_, + indexedOctree<treeType>::perturbTol() + ), bb, // overall search domain 8, // maxLevel 10, // leaf size diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files index f11e6fc4712a237cb2bf553d83850e0d9b79d10e..91bbbc11fd2ea7df9c1a0fec04b4dc37ded5b369 100644 --- a/src/meshTools/Make/files +++ b/src/meshTools/Make/files @@ -160,6 +160,7 @@ $(intersectedSurface)/intersectedSurface.C $(intersectedSurface)/edgeSurface.C triSurface/triSurfaceSearch/triSurfaceSearch.C +triSurface/triSurfaceSearch/triSurfaceRegionSearch.C triSurface/triangleFuncs/triangleFuncs.C triSurface/surfaceFeatures/surfaceFeatures.C triSurface/triSurfaceTools/triSurfaceTools.C diff --git a/src/meshTools/cellClassification/cellClassification.C b/src/meshTools/cellClassification/cellClassification.C index 09e84ac93c0d1d032a240649ce14e8165d60da65..800d007f6fb66e7dc8c7400966a46724e3086503 100644 --- a/src/meshTools/cellClassification/cellClassification.C +++ b/src/meshTools/cellClassification/cellClassification.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -34,6 +34,7 @@ License #include "ListOps.H" #include "meshTools.H" #include "cpuTime.H" +#include "triSurface.H" #include "globalMeshData.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // diff --git a/src/meshTools/cellClassification/cellClassification.H b/src/meshTools/cellClassification/cellClassification.H index aeb7a8102c59ff0e6bf3581237b0503319dd17b8..b040819fb2330ec5a0a73adde4c20a7d1e7ab5a0 100644 --- a/src/meshTools/cellClassification/cellClassification.H +++ b/src/meshTools/cellClassification/cellClassification.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -107,9 +107,7 @@ namespace Foam class triSurfaceSearch; class meshSearch; class polyMesh; -class polyMesh; class primitiveMesh; -class triSurface; /*---------------------------------------------------------------------------*\ Class cellClassification Declaration diff --git a/src/meshTools/indexedOctree/treeDataEdge.C b/src/meshTools/indexedOctree/treeDataEdge.C index 567fae04786363a0e404fbed217d38bc3cb30559..4d0b9b4d813624bb635424c125b1f61e7e3f0d07 100644 --- a/src/meshTools/indexedOctree/treeDataEdge.C +++ b/src/meshTools/indexedOctree/treeDataEdge.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -96,6 +96,24 @@ Foam::treeDataEdge::treeDataEdge } +Foam::treeDataEdge::findNearestOp::findNearestOp +( + const indexedOctree<treeDataEdge>& tree +) +: + tree_(tree) +{} + + +Foam::treeDataEdge::findIntersectOp::findIntersectOp +( + const indexedOctree<treeDataEdge>& tree +) +: + tree_(tree) +{} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // Foam::pointField Foam::treeDataEdge::shapePoints() const @@ -114,13 +132,13 @@ Foam::pointField Foam::treeDataEdge::shapePoints() const //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. -Foam::label Foam::treeDataEdge::getVolumeType +Foam::volumeType Foam::treeDataEdge::getVolumeType ( const indexedOctree<treeDataEdge>& oc, const point& sample ) const { - return indexedOctree<treeDataEdge>::UNKNOWN; + return volumeType::UNKNOWN; } @@ -165,9 +183,7 @@ bool Foam::treeDataEdge::overlaps } -// Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex, -// nearestPoint. -void Foam::treeDataEdge::findNearest +void Foam::treeDataEdge::findNearestOp::operator() ( const labelUList& indices, const point& sample, @@ -177,13 +193,15 @@ void Foam::treeDataEdge::findNearest point& nearestPoint ) const { + const treeDataEdge& shape = tree_.shapes(); + forAll(indices, i) { const label index = indices[i]; - const edge& e = edges_[edgeLabels_[index]]; + const edge& e = shape.edges()[shape.edgeLabels()[index]]; - pointHit nearHit = e.line(points_).nearestDist(sample); + pointHit nearHit = e.line(shape.points()).nearestDist(sample); scalar distSqr = sqr(nearHit.distance()); @@ -197,9 +215,7 @@ void Foam::treeDataEdge::findNearest } -//- Calculates nearest (to line) point in shape. -// Returns point and distance (squared) -void Foam::treeDataEdge::findNearest +void Foam::treeDataEdge::findNearestOp::operator() ( const labelUList& indices, const linePointRef& ln, @@ -210,6 +226,8 @@ void Foam::treeDataEdge::findNearest point& nearestPoint ) const { + const treeDataEdge& shape = tree_.shapes(); + // Best so far scalar nearestDistSqr = magSqr(linePoint - nearestPoint); @@ -217,13 +235,13 @@ void Foam::treeDataEdge::findNearest { const label index = indices[i]; - const edge& e = edges_[edgeLabels_[index]]; + const edge& e = shape.edges()[shape.edgeLabels()[index]]; // Note: could do bb test ? Worthwhile? // Nearest point on line point ePoint, lnPt; - scalar dist = e.line(points_).nearestDist(ln, ePoint, lnPt); + scalar dist = e.line(shape.points()).nearestDist(ln, ePoint, lnPt); scalar distSqr = sqr(dist); if (distSqr < nearestDistSqr) @@ -252,4 +270,21 @@ void Foam::treeDataEdge::findNearest } +bool Foam::treeDataEdge::findIntersectOp::operator() +( + const label index, + const point& start, + const point& end, + point& result +) const +{ + notImplemented + ( + "treeDataEdge::intersects(const label, const point&," + "const point&, point&)" + ); + return false; +} + + // ************************************************************************* // diff --git a/src/meshTools/indexedOctree/treeDataEdge.H b/src/meshTools/indexedOctree/treeDataEdge.H index 9a8deadb73c2883e9869bb80442ad2dd289e8b9a..12fd0d6aa10ba98c5db55977549b4775d58ca4d7 100644 --- a/src/meshTools/indexedOctree/treeDataEdge.H +++ b/src/meshTools/indexedOctree/treeDataEdge.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -37,6 +37,7 @@ SourceFiles #include "treeBoundBoxList.H" #include "linePointRef.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -86,6 +87,58 @@ class treeDataEdge public: + + class findNearestOp + { + const indexedOctree<treeDataEdge>& tree_; + + public: + + findNearestOp(const indexedOctree<treeDataEdge>& tree); + + void operator() + ( + const labelUList& indices, + const point& sample, + + scalar& nearestDistSqr, + label& minIndex, + point& nearestPoint + ) const; + + void operator() + ( + const labelUList& indices, + const linePointRef& ln, + + treeBoundBox& tightest, + label& minIndex, + point& linePoint, + point& nearestPoint + ) const; + }; + + + class findIntersectOp + { + const indexedOctree<treeDataEdge>& tree_; + + public: + + findIntersectOp(const indexedOctree<treeDataEdge>& tree); + + //- Calculate intersection of triangle with ray. Sets result + // accordingly + bool operator() + ( + const label index, + const point& start, + const point& end, + point& intersectionPoint + ) const; + }; + + // Declare name of the class and its debug switch ClassName("treeDataEdge"); @@ -116,6 +169,16 @@ public: // Access + const edgeList& edges() const + { + return edges_; + } + + const pointField& points() const + { + return points_; + } + const labelList& edgeLabels() const { return edgeLabels_; @@ -135,7 +198,7 @@ public: //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. - label getVolumeType + volumeType getVolumeType ( const indexedOctree<treeDataEdge>&, const point& @@ -155,50 +218,6 @@ public: const point& centre, const scalar radiusSqr ) const; - - //- Calculates nearest (to sample) point in shape. - // Returns actual point and distance (squared) - void findNearest - ( - const labelUList& indices, - const point& sample, - - scalar& nearestDistSqr, - label& nearestIndex, - point& nearestPoint - ) const; - - //- Calculates nearest (to line) point in shape. - // Returns point and distance (squared) - void findNearest - ( - const labelUList& indices, - const linePointRef& ln, - - treeBoundBox& tightest, - label& minIndex, - point& linePoint, - point& nearestPoint - ) const; - - //- Calculate intersection of shape with ray. Sets result - // accordingly - bool intersects - ( - const label index, - const point& start, - const point& end, - point& result - ) const - { - notImplemented - ( - "treeDataEdge::intersects(const label, const point&," - "const point&, point&)" - ); - return false; - } - }; diff --git a/src/meshTools/indexedOctree/treeDataFace.C b/src/meshTools/indexedOctree/treeDataFace.C index 9699416c13412d5e68cf62c0333500f5f9a16440..578a0de2ae056be937f97f226e847f10285ccbab 100644 --- a/src/meshTools/indexedOctree/treeDataFace.C +++ b/src/meshTools/indexedOctree/treeDataFace.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -145,6 +145,24 @@ Foam::treeDataFace::treeDataFace } +Foam::treeDataFace::findNearestOp::findNearestOp +( + const indexedOctree<treeDataFace>& tree +) +: + tree_(tree) +{} + + +Foam::treeDataFace::findIntersectOp::findIntersectOp +( + const indexedOctree<treeDataFace>& tree +) +: + tree_(tree) +{} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // Foam::pointField Foam::treeDataFace::shapePoints() const @@ -162,7 +180,7 @@ Foam::pointField Foam::treeDataFace::shapePoints() const //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. -Foam::label Foam::treeDataFace::getVolumeType +Foam::volumeType Foam::treeDataFace::getVolumeType ( const indexedOctree<treeDataFace>& oc, const point& sample @@ -415,7 +433,7 @@ Foam::label Foam::treeDataFace::getVolumeType // - tolerances are wrong. (if e.g. face has zero area) // - or (more likely) surface is not closed. - return indexedOctree<treeDataFace>::UNKNOWN; + return volumeType::UNKNOWN; } @@ -477,9 +495,7 @@ bool Foam::treeDataFace::overlaps } -// Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex, -// nearestPoint. -void Foam::treeDataFace::findNearest +void Foam::treeDataFace::findNearestOp::operator() ( const labelUList& indices, const point& sample, @@ -489,13 +505,15 @@ void Foam::treeDataFace::findNearest point& nearestPoint ) const { + const treeDataFace& shape = tree_.shapes(); + forAll(indices, i) { const label index = indices[i]; - const face& f = mesh_.faces()[faceLabels_[index]]; + const face& f = shape.mesh().faces()[shape.faceLabels()[index]]; - pointHit nearHit = f.nearestPoint(sample, mesh_.points()); + pointHit nearHit = f.nearestPoint(sample, shape.mesh().points()); scalar distSqr = sqr(nearHit.distance()); if (distSqr < nearestDistSqr) @@ -508,7 +526,33 @@ void Foam::treeDataFace::findNearest } -bool Foam::treeDataFace::intersects +void Foam::treeDataFace::findNearestOp::operator() +( + const labelUList& indices, + const linePointRef& ln, + + treeBoundBox& tightest, + label& minIndex, + point& linePoint, + point& nearestPoint +) const +{ + notImplemented + ( + "treeDataFace::findNearestOp::operator()" + "(" + " const labelUList&," + " const linePointRef&," + " treeBoundBox&," + " label&," + " point&," + " point&" + ") const" + ); +} + + +bool Foam::treeDataFace::findIntersectOp::operator() ( const label index, const point& start, @@ -516,10 +560,12 @@ bool Foam::treeDataFace::intersects point& intersectionPoint ) const { + const treeDataFace& shape = tree_.shapes(); + // Do quick rejection test - if (cacheBb_) + if (shape.cacheBb_) { - const treeBoundBox& faceBb = bbs_[index]; + const treeBoundBox& faceBb = shape.bbs_[index]; if ((faceBb.posBits(start) & faceBb.posBits(end)) != 0) { @@ -528,16 +574,16 @@ bool Foam::treeDataFace::intersects } } - const label faceI = faceLabels_[index]; + const label faceI = shape.faceLabels_[index]; const vector dir(end - start); - pointHit inter = mesh_.faces()[faceI].intersection + pointHit inter = shape.mesh_.faces()[faceI].intersection ( start, dir, - mesh_.faceCentres()[faceI], - mesh_.points(), + shape.mesh_.faceCentres()[faceI], + shape.mesh_.points(), intersection::HALF_RAY ); diff --git a/src/meshTools/indexedOctree/treeDataFace.H b/src/meshTools/indexedOctree/treeDataFace.H index 2b8ab258318cadc6d6e7a80168f2bc0938f47893..3867ba0206289f721d6bb037b70c251a515371fe 100644 --- a/src/meshTools/indexedOctree/treeDataFace.H +++ b/src/meshTools/indexedOctree/treeDataFace.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -39,6 +39,8 @@ SourceFiles #include "indexedOctree.H" #include "treeBoundBoxList.H" #include "PackedBoolList.H" +#include "primitiveMesh.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -46,7 +48,7 @@ namespace Foam { // Forward declaration of classes -class primitiveMesh; +//class primitiveMesh; //template<class Type> class indexedOctree; class polyPatch; @@ -90,6 +92,58 @@ class treeDataFace public: + + class findNearestOp + { + const indexedOctree<treeDataFace>& tree_; + + public: + + findNearestOp(const indexedOctree<treeDataFace>& tree); + + void operator() + ( + const labelUList& indices, + const point& sample, + + scalar& nearestDistSqr, + label& minIndex, + point& nearestPoint + ) const; + + void operator() + ( + const labelUList& indices, + const linePointRef& ln, + + treeBoundBox& tightest, + label& minIndex, + point& linePoint, + point& nearestPoint + ) const; + }; + + + class findIntersectOp + { + const indexedOctree<treeDataFace>& tree_; + + public: + + findIntersectOp(const indexedOctree<treeDataFace>& tree); + + //- Calculate intersection of triangle with ray. Sets result + // accordingly + bool operator() + ( + const label index, + const point& start, + const point& end, + point& intersectionPoint + ) const; + }; + + // Declare name of the class and its debug switch ClassName("treeDataFace"); @@ -147,7 +201,7 @@ public: //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. - label getVolumeType + volumeType getVolumeType ( const indexedOctree<treeDataFace>&, const point& @@ -159,49 +213,6 @@ public: const label index, const treeBoundBox& sampleBb ) const; - - //- Calculates nearest (to sample) point in shape. - // Returns actual point and distance (squared) - void findNearest - ( - const labelUList& indices, - const point& sample, - - scalar& nearestDistSqr, - label& nearestIndex, - point& nearestPoint - ) const; - - //- Calculates nearest (to line) point in shape. - // Returns point and distance (squared) - void findNearest - ( - const labelUList& indices, - const linePointRef& ln, - - treeBoundBox& tightest, - label& minIndex, - point& linePoint, - point& nearestPoint - ) const - { - notImplemented - ( - "treeDataFace::findNearest" - "(const labelUList&, const linePointRef&, ..)" - ); - } - - //- Calculate intersection of shape with ray. Sets result - // accordingly - bool intersects - ( - const label index, - const point& start, - const point& end, - point& result - ) const; - }; diff --git a/src/meshTools/indexedOctree/treeDataPoint.C b/src/meshTools/indexedOctree/treeDataPoint.C index 1d7f3d133ec2710e5ad64f1adb12723456db8cd0..fd7f4404b418cbab465ca6eb95b21505bdb8ddf5 100644 --- a/src/meshTools/indexedOctree/treeDataPoint.C +++ b/src/meshTools/indexedOctree/treeDataPoint.C @@ -57,6 +57,24 @@ Foam::treeDataPoint::treeDataPoint {} +Foam::treeDataPoint::findNearestOp::findNearestOp +( + const indexedOctree<treeDataPoint>& tree +) +: + tree_(tree) +{} + + +Foam::treeDataPoint::findIntersectOp::findIntersectOp +( + const indexedOctree<treeDataPoint>& tree +) +: + tree_(tree) +{} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // Foam::pointField Foam::treeDataPoint::shapePoints() const @@ -74,13 +92,13 @@ Foam::pointField Foam::treeDataPoint::shapePoints() const //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. -Foam::label Foam::treeDataPoint::getVolumeType +Foam::volumeType Foam::treeDataPoint::getVolumeType ( const indexedOctree<treeDataPoint>& oc, const point& sample ) const { - return indexedOctree<treeDataPoint>::UNKNOWN; + return volumeType::UNKNOWN; } @@ -115,9 +133,7 @@ bool Foam::treeDataPoint::overlaps } -// Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex, -// nearestPoint. -void Foam::treeDataPoint::findNearest +void Foam::treeDataPoint::findNearestOp::operator() ( const labelUList& indices, const point& sample, @@ -127,12 +143,19 @@ void Foam::treeDataPoint::findNearest point& nearestPoint ) const { + const treeDataPoint& shape = tree_.shapes(); + forAll(indices, i) { const label index = indices[i]; - label pointI = (useSubset_ ? pointLabels_[index] : index); + label pointI = + ( + shape.useSubset() + ? shape.pointLabels()[index] + : index + ); - const point& pt = points_[pointI]; + const point& pt = shape.points()[pointI]; scalar distSqr = magSqr(pt - sample); @@ -146,9 +169,7 @@ void Foam::treeDataPoint::findNearest } -//- Calculates nearest (to line) point in shape. -// Returns point and distance (squared) -void Foam::treeDataPoint::findNearest +void Foam::treeDataPoint::findNearestOp::operator() ( const labelUList& indices, const linePointRef& ln, @@ -159,6 +180,8 @@ void Foam::treeDataPoint::findNearest point& nearestPoint ) const { + const treeDataPoint& shape = tree_.shapes(); + // Best so far scalar nearestDistSqr = GREAT; if (minIndex >= 0) @@ -169,9 +192,14 @@ void Foam::treeDataPoint::findNearest forAll(indices, i) { const label index = indices[i]; - label pointI = (useSubset_ ? pointLabels_[index] : index); + label pointI = + ( + shape.useSubset() + ? shape.pointLabels()[index] + : index + ); - const point& shapePt = points_[pointI]; + const point& shapePt = shape.points()[pointI]; if (tightest.contains(shapePt)) { @@ -206,4 +234,21 @@ void Foam::treeDataPoint::findNearest } +bool Foam::treeDataPoint::findIntersectOp::operator() +( + const label index, + const point& start, + const point& end, + point& result +) const +{ + notImplemented + ( + "treeDataPoint::intersects(const label, const point&," + "const point&, point&)" + ); + return false; +} + + // ************************************************************************* // diff --git a/src/meshTools/indexedOctree/treeDataPoint.H b/src/meshTools/indexedOctree/treeDataPoint.H index f867a3274acf02f04c7786c623cf501b142ec152..020f60a11d14452cb21c0c678f7cca11486e1f51 100644 --- a/src/meshTools/indexedOctree/treeDataPoint.H +++ b/src/meshTools/indexedOctree/treeDataPoint.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -43,6 +43,7 @@ SourceFiles #include "pointField.H" #include "treeBoundBox.H" #include "linePointRef.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -69,6 +70,58 @@ class treeDataPoint public: + + class findNearestOp + { + const indexedOctree<treeDataPoint>& tree_; + + public: + + findNearestOp(const indexedOctree<treeDataPoint>& tree); + + void operator() + ( + const labelUList& indices, + const point& sample, + + scalar& nearestDistSqr, + label& minIndex, + point& nearestPoint + ) const; + + void operator() + ( + const labelUList& indices, + const linePointRef& ln, + + treeBoundBox& tightest, + label& minIndex, + point& linePoint, + point& nearestPoint + ) const; + }; + + + class findIntersectOp + { + const indexedOctree<treeDataPoint>& tree_; + + public: + + findIntersectOp(const indexedOctree<treeDataPoint>& tree); + + //- Calculate intersection of triangle with ray. Sets result + // accordingly + bool operator() + ( + const label index, + const point& start, + const point& end, + point& intersectionPoint + ) const; + }; + + // Declare name of the class and its debug switch ClassName("treeDataPoint"); @@ -106,6 +159,11 @@ public: return points_; } + bool useSubset() const + { + return useSubset_; + } + //- Get representative point cloud for all shapes inside // (one point per shape) pointField shapePoints() const; @@ -115,7 +173,7 @@ public: //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. - label getVolumeType + volumeType getVolumeType ( const indexedOctree<treeDataPoint>&, const point& @@ -135,50 +193,6 @@ public: const point& centre, const scalar radiusSqr ) const; - - //- Calculates nearest (to sample) point in shape. - // Returns actual point and distance (squared) - void findNearest - ( - const labelUList& indices, - const point& sample, - - scalar& nearestDistSqr, - label& nearestIndex, - point& nearestPoint - ) const; - - //- Calculates nearest (to line) point in shape. - // Returns point and distance (squared) - void findNearest - ( - const labelUList& indices, - const linePointRef& ln, - - treeBoundBox& tightest, - label& minIndex, - point& linePoint, - point& nearestPoint - ) const; - - //- Calculate intersection of shape with ray. Sets result - // accordingly - bool intersects - ( - const label index, - const point& start, - const point& end, - point& result - ) const - { - notImplemented - ( - "treeDataPoint::intersects(const label, const point&," - "const point&, point&)" - ); - return false; - } - }; diff --git a/src/meshTools/indexedOctree/treeDataPrimitivePatch.C b/src/meshTools/indexedOctree/treeDataPrimitivePatch.C index 4cd29682323df7d68cb1259cdb9836ac7325749f..47d6f57d69e1a5d05a2b721289b94c2bd6c977ed 100644 --- a/src/meshTools/indexedOctree/treeDataPrimitivePatch.C +++ b/src/meshTools/indexedOctree/treeDataPrimitivePatch.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -26,12 +26,8 @@ License #include "treeDataPrimitivePatch.H" #include "indexedOctree.H" #include "triangleFuncs.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -template<class PatchType> -Foam::scalar Foam::treeDataPrimitivePatch<PatchType>::tolSqr = sqr(1e-6); - +#include "triSurfaceTools.H" +#include "triFace.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -70,6 +66,75 @@ void Foam::treeDataPrimitivePatch<PatchType>::update() } +template<class PatchType> +bool Foam::treeDataPrimitivePatch<PatchType>::findIntersection +( + const indexedOctree<treeDataPrimitivePatch<PatchType> >& tree, + const label index, + const point& start, + const point& end, + point& intersectionPoint +) +{ + const treeDataPrimitivePatch<PatchType>& shape = tree.shapes(); + const PatchType& patch = shape.patch(); + + const pointField& points = patch.points(); + const typename PatchType::FaceType& f = patch[index]; + + // Do quick rejection test + if (shape.cacheBb_) + { + const treeBoundBox& faceBb = shape.bbs_[index]; + + if ((faceBb.posBits(start) & faceBb.posBits(end)) != 0) + { + // start and end in same block outside of faceBb. + return false; + } + } + + const vector dir(end - start); + pointHit inter; + + if (f.size() == 3) + { + inter = triPointRef + ( + points[f[0]], + points[f[1]], + points[f[2]] + ).intersection(start, dir, intersection::HALF_RAY, shape.planarTol_); + } + else + { + const pointField& faceCentres = patch.faceCentres(); + + inter = f.intersection + ( + start, + dir, + faceCentres[index], + points, + intersection::HALF_RAY + ); + } + + if (inter.hit() && inter.distance() <= 1) + { + // Note: no extra test on whether intersection is in front of us + // since using half_ray + intersectionPoint = inter.hitPoint(); + + return true; + } + else + { + return false; + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components @@ -77,16 +142,50 @@ template<class PatchType> Foam::treeDataPrimitivePatch<PatchType>::treeDataPrimitivePatch ( const bool cacheBb, - const PatchType& patch + const PatchType& patch, + const scalar planarTol ) : patch_(patch), - cacheBb_(cacheBb) + cacheBb_(cacheBb), + planarTol_(planarTol) { update(); } +template<class PatchType> +Foam::treeDataPrimitivePatch<PatchType>::findNearestOp::findNearestOp +( + const indexedOctree<treeDataPrimitivePatch<PatchType> >& tree +) +: + tree_(tree) +{} + + +template<class PatchType> +Foam::treeDataPrimitivePatch<PatchType>::findIntersectOp::findIntersectOp +( + const indexedOctree<treeDataPrimitivePatch<PatchType> >& tree +) +: + tree_(tree) +{} + + +template<class PatchType> +Foam::treeDataPrimitivePatch<PatchType>::findAllIntersectOp::findAllIntersectOp +( + const indexedOctree<treeDataPrimitivePatch<PatchType> >& tree, + DynamicList<label>& shapeMask +) +: + tree_(tree), + shapeMask_(shapeMask) +{} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class PatchType> @@ -106,7 +205,7 @@ Foam::pointField Foam::treeDataPrimitivePatch<PatchType>::shapePoints() const //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. template<class PatchType> -Foam::label Foam::treeDataPrimitivePatch<PatchType>:: getVolumeType +Foam::volumeType Foam::treeDataPrimitivePatch<PatchType>::getVolumeType ( const indexedOctree<treeDataPrimitivePatch<PatchType> >& oc, const point& sample @@ -136,7 +235,6 @@ Foam::label Foam::treeDataPrimitivePatch<PatchType>:: getVolumeType << abort(FatalError); } - // Get actual intersection point on face label faceI = info.index(); @@ -147,7 +245,7 @@ Foam::label Foam::treeDataPrimitivePatch<PatchType>:: getVolumeType } const pointField& points = patch_.localPoints(); - const face& f = patch_.localFaces()[faceI]; + const typename PatchType::FaceType& f = patch_.localFaces()[faceI]; // Retest to classify where on face info is. Note: could be improved. We // already have point. @@ -188,9 +286,10 @@ Foam::label Foam::treeDataPrimitivePatch<PatchType>:: getVolumeType const scalar typDimSqr = mag(area) + VSMALL; + forAll(f, fp) { - if ((magSqr(points[f[fp]] - curPt)/typDimSqr) < tolSqr) + if ((magSqr(points[f[fp]] - curPt)/typDimSqr) < planarTol_) { // Face intersection point equals face vertex fp @@ -207,7 +306,7 @@ Foam::label Foam::treeDataPrimitivePatch<PatchType>:: getVolumeType const point fc(f.centre(points)); - if ((magSqr(fc - curPt)/typDimSqr) < tolSqr) + if ((magSqr(fc - curPt)/typDimSqr) < planarTol_) { // Face intersection point equals face centre. Normal at face centre // is already average of face normals @@ -240,7 +339,7 @@ Foam::label Foam::treeDataPrimitivePatch<PatchType>:: getVolumeType pointHit edgeHit = e.line(points).nearestDist(sample); - if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < tolSqr) + if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < planarTol_) { // Face intersection point lies on edge e @@ -285,7 +384,7 @@ Foam::label Foam::treeDataPrimitivePatch<PatchType>:: getVolumeType fc ).nearestDist(sample); - if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < tolSqr) + if ((magSqr(edgeHit.rawPoint() - curPt)/typDimSqr) < planarTol_) { // Face intersection point lies on edge between two face triangles @@ -336,7 +435,7 @@ Foam::label Foam::treeDataPrimitivePatch<PatchType>:: getVolumeType // - tolerances are wrong. (if e.g. face has zero area) // - or (more likely) surface is not closed. - return indexedOctree<treeDataPrimitivePatch>::UNKNOWN; + return volumeType::UNKNOWN; } @@ -368,7 +467,7 @@ bool Foam::treeDataPrimitivePatch<PatchType>::overlaps // 2. Check if one or more face points inside const pointField& points = patch_.points(); - const face& f = patch_[index]; + const typename PatchType::FaceType& f = patch_[index]; if (cubeBb.containsAny(points, f)) { @@ -379,21 +478,35 @@ bool Foam::treeDataPrimitivePatch<PatchType>::overlaps // go through cube. Use triangle-bounding box intersection. const point fc = f.centre(points); - forAll(f, fp) + if (f.size() == 3) { - bool triIntersects = triangleFuncs::intersectBb + return triangleFuncs::intersectBb ( - points[f[fp]], - points[f[f.fcIndex(fp)]], - fc, + points[f[0]], + points[f[1]], + points[f[2]], cubeBb ); - - if (triIntersects) + } + else + { + forAll(f, fp) { - return true; + bool triIntersects = triangleFuncs::intersectBb + ( + points[f[fp]], + points[f[f.fcIndex(fp)]], + fc, + cubeBb + ); + + if (triIntersects) + { + return true; + } } } + return false; } @@ -439,10 +552,8 @@ bool Foam::treeDataPrimitivePatch<PatchType>::overlaps } -// Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex, -// nearestPoint. template<class PatchType> -void Foam::treeDataPrimitivePatch<PatchType>::findNearest +void Foam::treeDataPrimitivePatch<PatchType>::findNearestOp::operator() ( const labelUList& indices, const point& sample, @@ -452,13 +563,15 @@ void Foam::treeDataPrimitivePatch<PatchType>::findNearest point& nearestPoint ) const { - const pointField& points = patch_.points(); + const treeDataPrimitivePatch<PatchType>& shape = tree_.shapes(); + const PatchType& patch = shape.patch(); + + const pointField& points = patch.points(); forAll(indices, i) { const label index = indices[i]; - - const face& f = patch_[index]; + const typename PatchType::FaceType& f = patch[index]; pointHit nearHit = f.nearestPoint(sample, points); scalar distSqr = sqr(nearHit.distance()); @@ -474,7 +587,34 @@ void Foam::treeDataPrimitivePatch<PatchType>::findNearest template<class PatchType> -bool Foam::treeDataPrimitivePatch<PatchType>::intersects +void Foam::treeDataPrimitivePatch<PatchType>::findNearestOp::operator() +( + const labelUList& indices, + const linePointRef& ln, + + treeBoundBox& tightest, + label& minIndex, + point& linePoint, + point& nearestPoint +) const +{ + notImplemented + ( + "treeDataPrimitivePatch<PatchType>::findNearestOp::operator()" + "(" + " const labelUList&," + " const linePointRef&," + " treeBoundBox&," + " label&," + " point&," + " point&" + ") const" + ); +} + + +template<class PatchType> +bool Foam::treeDataPrimitivePatch<PatchType>::findIntersectOp::operator() ( const label index, const point& start, @@ -482,43 +622,25 @@ bool Foam::treeDataPrimitivePatch<PatchType>::intersects point& intersectionPoint ) const { - // Do quick rejection test - if (cacheBb_) - { - const treeBoundBox& faceBb = bbs_[index]; - - if ((faceBb.posBits(start) & faceBb.posBits(end)) != 0) - { - // start and end in same block outside of faceBb. - return false; - } - } - - const pointField& points = patch_.points(); - const face& f = patch_[index]; - const point fc = f.centre(points); - const vector dir(end - start); + return findIntersection(tree_, index, start, end, intersectionPoint); +} - pointHit inter = patch_[index].intersection - ( - start, - dir, - fc, - points, - intersection::HALF_RAY - ); - if (inter.hit() && inter.distance() <= 1) - { - // Note: no extra test on whether intersection is in front of us - // since using half_ray - intersectionPoint = inter.hitPoint(); - return true; - } - else +template<class PatchType> +bool Foam::treeDataPrimitivePatch<PatchType>::findAllIntersectOp::operator() +( + const label index, + const point& start, + const point& end, + point& intersectionPoint +) const +{ + if (!shapeMask_.empty() && findIndex(shapeMask_, index) != -1) { return false; } + + return findIntersection(tree_, index, start, end, intersectionPoint); } diff --git a/src/meshTools/indexedOctree/treeDataPrimitivePatch.H b/src/meshTools/indexedOctree/treeDataPrimitivePatch.H index bbb3c749562c49d99ce168a8e76cbc0fc2988a01..9d43d2ba85154dcec67dbab742a7d7a7bc89b19c 100644 --- a/src/meshTools/indexedOctree/treeDataPrimitivePatch.H +++ b/src/meshTools/indexedOctree/treeDataPrimitivePatch.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -35,9 +35,8 @@ SourceFiles #ifndef treeDataPrimitivePatch_H #define treeDataPrimitivePatch_H -#include "PrimitivePatch.H" -//#include "indexedOctree.H" #include "treeBoundBoxList.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -64,11 +63,6 @@ class treeDataPrimitivePatch : public treeDataPrimitivePatchName { - // Static data - - //- tolerance on linear dimensions - static scalar tolSqr; - // Private data //- Underlying geometry @@ -77,6 +71,9 @@ class treeDataPrimitivePatch //- Whether to precalculate and store face bounding box const bool cacheBb_; + //- Tolerance to use for intersection tests + const scalar planarTol_; + //- face bounding boxes (valid only if cacheBb_) treeBoundBoxList bbs_; @@ -89,15 +86,107 @@ class treeDataPrimitivePatch //- Initialise all member data void update(); + //- Find intersection of line with shapes + static bool findIntersection + ( + const indexedOctree<treeDataPrimitivePatch<PatchType> >& tree, + const label index, + const point& start, + const point& end, + point& intersectionPoint + ); + + public: + + class findNearestOp + { + const indexedOctree<treeDataPrimitivePatch>& tree_; + + public: + + findNearestOp(const indexedOctree<treeDataPrimitivePatch>& tree); + + void operator() + ( + const labelUList& indices, + const point& sample, + + scalar& nearestDistSqr, + label& minIndex, + point& nearestPoint + ) const; + + //- Calculates nearest (to line) point in shape. + // Returns point and distance (squared) + void operator() + ( + const labelUList& indices, + const linePointRef& ln, + + treeBoundBox& tightest, + label& minIndex, + point& linePoint, + point& nearestPoint + ) const; + }; + + + class findIntersectOp + { + const indexedOctree<treeDataPrimitivePatch>& tree_; + + public: + + findIntersectOp(const indexedOctree<treeDataPrimitivePatch>& tree); + + //- Calculate intersection of triangle with ray. Sets result + // accordingly + bool operator() + ( + const label index, + const point& start, + const point& end, + point& intersectionPoint + ) const; + }; + + + class findAllIntersectOp + { + const indexedOctree<treeDataPrimitivePatch>& tree_; + + DynamicList<label>& shapeMask_; + + public: + + findAllIntersectOp + ( + const indexedOctree<treeDataPrimitivePatch>& tree, + DynamicList<label>& shapeMask + ); + + //- Calculate intersection of triangle with ray. Sets result + // accordingly + bool operator() + ( + const label index, + const point& start, + const point& end, + point& intersectionPoint + ) const; + }; + + // Constructors //- Construct from patch. treeDataPrimitivePatch ( const bool cacheBb, - const PatchType& + const PatchType&, + const scalar planarTol ); @@ -125,7 +214,7 @@ public: //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. // Only makes sense for closed surfaces. - label getVolumeType + volumeType getVolumeType ( const indexedOctree<treeDataPrimitivePatch<PatchType> >&, const point& @@ -145,49 +234,6 @@ public: const point& centre, const scalar radiusSqr ) const; - - //- Calculates nearest (to sample) point in shape. - // Returns actual point and distance (squared) - void findNearest - ( - const labelUList& indices, - const point& sample, - - scalar& nearestDistSqr, - label& nearestIndex, - point& nearestPoint - ) const; - - //- Calculates nearest (to line) point in shape. - // Returns point and distance (squared) - void findNearest - ( - const labelUList& indices, - const linePointRef& ln, - - treeBoundBox& tightest, - label& minIndex, - point& linePoint, - point& nearestPoint - ) const - { - notImplemented - ( - "treeDataPrimitivePatch::findNearest" - "(const labelUList&, const linePointRef&, ..)" - ); - } - - //- Calculate intersection of shape with ray. Sets result - // accordingly - bool intersects - ( - const label index, - const point& start, - const point& end, - point& result - ) const; - }; diff --git a/src/meshTools/indexedOctree/treeDataTriSurface.C b/src/meshTools/indexedOctree/treeDataTriSurface.C index 0aa567f68b0ce38a80b6bf4576dc25f25accaa6d..ef00434eb28b28116232681c4d37d1eb152e43e5 100644 --- a/src/meshTools/indexedOctree/treeDataTriSurface.C +++ b/src/meshTools/indexedOctree/treeDataTriSurface.C @@ -25,491 +25,58 @@ License #include "treeDataTriSurface.H" #include "triSurfaceTools.H" -#include "triangleFuncs.H" -#include "indexedOctree.H" -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -namespace Foam -{ -defineTypeNameAndDebug(treeDataTriSurface, 0); -} - - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -// // Fast distance to triangle calculation. From -// // "Distance Between Point and Triangle in 3D" -// // David Eberly, Magic Software Inc. Aug. 2003. -// // Works on function Q giving distance to point and tries to minimize this. -// Foam::scalar Foam::treeDataTriSurface::nearestCoords -// ( -// const point& base, -// const point& E0, -// const point& E1, -// const scalar a, -// const scalar b, -// const scalar c, -// const point& P, -// scalar& s, -// scalar& t -// ) -// { -// // distance vector -// const vector D(base - P); - -// // Precalculate distance factors. -// const scalar d = E0 & D; -// const scalar e = E1 & D; - -// // Do classification -// const scalar det = a*c - b*b; - -// s = b*e - c*d; -// t = b*d - a*e; - -// if (s+t < det) -// { -// if (s < 0) -// { -// if (t < 0) -// { -// //region 4 -// if (e > 0) -// { -// //min on edge t = 0 -// t = 0; -// s = (d >= 0 ? 0 : (-d >= a ? 1 : -d/a)); -// } -// else -// { -// //min on edge s=0 -// s = 0; -// t = (e >= 0 ? 0 : (-e >= c ? 1 : -e/c)); -// } -// } -// else -// { -// //region 3. Min on edge s = 0 -// s = 0; -// t = (e >= 0 ? 0 : (-e >= c ? 1 : -e/c)); -// } -// } -// else if (t < 0) -// { -// //region 5 -// t = 0; -// s = (d >= 0 ? 0 : (-d >= a ? 1 : -d/a)); -// } -// else -// { -// //region 0 -// const scalar invDet = 1/det; -// s *= invDet; -// t *= invDet; -// } -// } -// else -// { -// if (s < 0) -// { -// //region 2 -// const scalar tmp0 = b + d; -// const scalar tmp1 = c + e; -// if (tmp1 > tmp0) -// { -// //min on edge s+t=1 -// const scalar numer = tmp1 - tmp0; -// const scalar denom = a-2*b+c; -// s = (numer >= denom ? 1 : numer/denom); -// t = 1 - s; -// } -// else -// { -// //min on edge s=0 -// s = 0; -// t = (tmp1 <= 0 ? 1 : (e >= 0 ? 0 : - e/c)); -// } -// } -// else if (t < 0) -// { -// //region 6 -// const scalar tmp0 = b + d; -// const scalar tmp1 = c + e; -// if (tmp1 > tmp0) -// { -// //min on edge s+t=1 -// const scalar numer = tmp1 - tmp0; -// const scalar denom = a-2*b+c; -// s = (numer >= denom ? 1 : numer/denom); -// t = 1 - s; -// } -// else -// { -// //min on edge t=0 -// t = 0; -// s = (tmp1 <= 0 ? 1 : (d >= 0 ? 0 : - d/a)); -// } -// } -// else -// { -// //region 1 -// const scalar numer = c+e-(b+d); -// if (numer <= 0) -// { -// s = 0; -// } -// else -// { -// const scalar denom = a-2*b+c; -// s = (numer >= denom ? 1 : numer/denom); -// } -// } -// t = 1 - s; -// } - - -// // Calculate distance. -// // Note: abs should not be needed but truncation error causes problems -// // with points very close to one of the triangle vertices. -// // (seen up to -9e-15). Alternatively add some small value. - -// const scalar f = D & D; -// return Foam::mag(a*s*s + 2*b*s*t + c*t*t + 2*d*s + 2*e*t + f); -// } - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -// Construct from components -Foam::treeDataTriSurface::treeDataTriSurface +template<> +Foam::volumeType Foam::treeDataPrimitivePatch<Foam::triSurface>::getVolumeType ( - const triSurface& surface, - const scalar planarTol -) -: - surface_(surface), - planarTol_(planarTol) -{} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -Foam::pointField Foam::treeDataTriSurface::shapePoints() const -{ - const pointField& points = surface_.points(); - - pointField centres(surface_.size()); - - forAll(surface_, triI) - { - centres[triI] = surface_[triI].centre(points); - } - return centres; -} - - -//- Get type of sample (inside/outside/mixed) w.r.t. surface. -Foam::label Foam::treeDataTriSurface::getVolumeType -( - const indexedOctree<treeDataTriSurface>& tree, + const indexedOctree<treeDataPrimitivePatch<triSurface> >& oc, const point& sample ) const { - // Find nearest point - const treeBoundBox& treeBb = tree.bb(); + // Find nearest face to sample + pointIndexHit info = oc.findNearest(sample, sqr(GREAT)); - pointIndexHit pHit = tree.findNearest - ( - sample, - max - ( - Foam::sqr(GREAT), - Foam::magSqr(treeBb.span()) - ) - ); - - if (!pHit.hit()) + if (info.index() == -1) { - FatalErrorIn("treeDataTriSurface::getVolumeType(..)") - << "treeBb:" << treeBb - << " sample:" << sample - << " pHit:" << pHit + FatalErrorIn + ( + "treeDataPrimitivePatch::getSampleType" + "(indexedOctree<treeDataPrimitivePatch>&, const point&)" + ) << "Could not find " << sample << " in octree." << abort(FatalError); } + // Get actual intersection point on face + label faceI = info.index(); + triSurfaceTools::sideType t = triSurfaceTools::surfaceSide ( - surface_, + patch_, sample, - pHit.index() + faceI ); if (t == triSurfaceTools::UNKNOWN) { - return indexedOctree<treeDataTriSurface>::UNKNOWN; + return volumeType::UNKNOWN; } else if (t == triSurfaceTools::INSIDE) { - return indexedOctree<treeDataTriSurface>::INSIDE; + return volumeType::INSIDE; } else if (t == triSurfaceTools::OUTSIDE) { - return indexedOctree<treeDataTriSurface>::OUTSIDE; + return volumeType::OUTSIDE; } else { - FatalErrorIn("treeDataTriSurface::getVolumeType(..)") + FatalErrorIn("treeDataPrimitivePatch<PatchType>::getVolumeType(..)") << "problem" << abort(FatalError); - return indexedOctree<treeDataTriSurface>::UNKNOWN; - } -} - - -// Check if any point on triangle is inside cubeBb. -bool Foam::treeDataTriSurface::overlaps -( - const label index, - const treeBoundBox& cubeBb -) const -{ - const pointField& points = surface_.points(); - const labelledTri& f = surface_[index]; - - treeBoundBox triBb(points, surface_[index]); - - //- For testing: robust one - //return cubeBb.overlaps(triBb); - - //- Exact test of triangle intersecting bb - - // Quick rejection. If whole bounding box of tri is outside cubeBb then - // there will be no intersection. - if (!cubeBb.overlaps(triBb)) - { - return false; - } - - // Check if one or more triangle point inside - if (cubeBb.containsAny(points, f)) - { - return true; - } - - // Triangle points - const point& p0 = points[f[0]]; - const point& p1 = points[f[1]]; - const point& p2 = points[f[2]]; - - - // Now we have the difficult case: all points are outside but connecting - // edges might go through cube. Use fast intersection of bounding box. - - //return triangleFuncs::intersectBbExact(p0, p1, p2, cubeBb); - return triangleFuncs::intersectBb(p0, p1, p2, cubeBb); -} - - -// Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex, -// nearestPoint. -void Foam::treeDataTriSurface::findNearest -( - const labelUList& indices, - const point& sample, - - scalar& nearestDistSqr, - label& minIndex, - point& nearestPoint -) const -{ - const pointField& points = surface_.points(); - - forAll(indices, i) - { - label index = indices[i]; - const triSurface::FaceType& f = surface_[index]; - - ////- Possible optimization: do quick rejection of triangle if bounding - //// sphere does not intersect triangle bounding box. From simplistic - //// test was not found to speed up things. - // - //// Triangle bounding box. - //point triBbMin = min(p0, min(p1, p2)); - //point triBbMax = max(p0, max(p1, p2)); - // - //if - //( - // indexedOctree<treeDataTriSurface>::intersects - // ( - // triBbMin, - // triBbMax, - // nearestDistSqr, - // sample - // ) - //) - { - // // Get spanning vectors of triangle - // vector base(p1); - // vector E0(p0 - p1); - // vector E1(p2 - p1); - - // scalar a(E0& E0); - // scalar b(E0& E1); - // scalar c(E1& E1); - - // // Get nearest point in s,t coordinates (s is along E0, t - // // is along E1) - // scalar s; - // scalar t; - - // scalar distSqr = nearestCoords - // ( - // base, - // E0, - // E1, - // a, - // b, - // c, - // sample, - - // s, - // t - // ); - - pointHit pHit = f.nearestPoint(sample, points); - - scalar distSqr = sqr(pHit.distance()); - - if (distSqr < nearestDistSqr) - { - nearestDistSqr = distSqr; - minIndex = index; - nearestPoint = pHit.rawPoint(); - } - } + return volumeType::UNKNOWN; } } -// Calculate nearest point to line. Updates (if any) nearestDistSqr, minIndex, -// nearestPoint. -void Foam::treeDataTriSurface::findNearest -( - const labelUList& indices, - const linePointRef& ln, - - treeBoundBox& tightest, - label& minIndex, - point& linePoint, - point& nearestPoint -) const -{ - // Best so far - scalar nearestDistSqr = VGREAT; - if (minIndex >= 0) - { - nearestDistSqr = magSqr(linePoint - nearestPoint); - } - - const pointField& points = surface_.points(); - - forAll(indices, i) - { - label index = indices[i]; - const triSurface::FaceType& f = surface_[index]; - - triPointRef tri(f.tri(points)); - - pointHit lineInfo(point::max); - pointHit pHit = tri.nearestPoint(ln, lineInfo); - - scalar distSqr = sqr(pHit.distance()); - - if (distSqr < nearestDistSqr) - { - nearestDistSqr = distSqr; - minIndex = index; - linePoint = lineInfo.rawPoint(); - nearestPoint = pHit.rawPoint(); - - { - point& minPt = tightest.min(); - minPt = min(ln.start(), ln.end()); - minPt.x() -= pHit.distance(); - minPt.y() -= pHit.distance(); - minPt.z() -= pHit.distance(); - } - { - point& maxPt = tightest.max(); - maxPt = max(ln.start(), ln.end()); - maxPt.x() += pHit.distance(); - maxPt.y() += pHit.distance(); - maxPt.z() += pHit.distance(); - } - } - } -} - - -bool Foam::treeDataTriSurface::intersects -( - const label index, - const point& start, - const point& end, - point& intersectionPoint -) const -{ - const pointField& points = surface_.points(); - - const triSurface::FaceType& f = surface_[index]; - - // Do quick rejection test - treeBoundBox triBb(points, f); - - const direction startBits(triBb.posBits(start)); - const direction endBits(triBb.posBits(end)); - - if ((startBits & endBits) != 0) - { - // start and end in same block outside of triBb. - return false; - } - - const vector dir(end - start); - - // Use relative tolerance (from octree) to determine intersection. - pointHit inter = f.intersection - ( - start, - dir, - points, - intersection::HALF_RAY, - planarTol_ - ); - - if (inter.hit() && inter.distance() <= 1) - { - // Note: no extra test on whether intersection is in front of us - // since using half_ray. - intersectionPoint = inter.hitPoint(); - - return true; - } - else - { - return false; - } - - - //- Using exact intersections - //pointHit info = f.tri(points).intersectionExact(start, end); - // - //if (info.hit()) - //{ - // intersectionPoint = info.hitPoint(); - //} - //return info.hit(); -} - - // ************************************************************************* // diff --git a/src/meshTools/indexedOctree/treeDataTriSurface.H b/src/meshTools/indexedOctree/treeDataTriSurface.H index 9184294c0be0e211f5f5cd799727848ebaa959c9..fbc3d00b129311f4d390daea58204ec605fe219e 100644 --- a/src/meshTools/indexedOctree/treeDataTriSurface.H +++ b/src/meshTools/indexedOctree/treeDataTriSurface.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,7 +25,7 @@ Class Foam::treeDataTriSurface Description - Encapsulates data for (indexedOc)tree searches on triSurface. + Encapsulates data for (indexedOc)tree searches on a triSurface. SourceFiles treeDataTriSurface.C @@ -35,139 +35,27 @@ SourceFiles #ifndef treeDataTriSurface_H #define treeDataTriSurface_H +#include "treeDataPrimitivePatch.H" #include "triSurface.H" +#include "point.H" +#include "indexedOctree.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { + typedef treeDataPrimitivePatch<triSurface> treeDataTriSurface; -// Forward declaration of classes -class treeBoundBox; -class treeDataTriSurface; -template<class Type> class indexedOctree; + //- Template specialisation of getVolumeType for treeDataTriSurface + template<> + volumeType treeDataPrimitivePatch<triSurface>::getVolumeType + ( + const indexedOctree<treeDataPrimitivePatch<triSurface> >& oc, + const point& sample + ) const; +} -/*---------------------------------------------------------------------------*\ - Class treeDataTriSurface Declaration -\*---------------------------------------------------------------------------*/ - -class treeDataTriSurface -{ - // Private data - - //- Reference to triSurface - const triSurface& surface_; - - //- Tolerance to use for intersection tests - const scalar planarTol_; - - // Private Member Functions - - // //- fast triangle nearest point calculation. Returns point in E0, E1 - // // coordinate system: base + s*E0 + t*E1 - // static scalar nearestCoords - // ( - // const point& base, - // const point& E0, - // const point& E1, - // const scalar a, - // const scalar b, - // const scalar c, - // const point& P, - // scalar& s, - // scalar& t - // ); - -public: - - // Declare name of the class and its debug switch - ClassName("treeDataTriSurface"); - - - // Constructors - - //- Construct from triSurface and tolerance for intersection - // tests. Holds reference. - treeDataTriSurface(const triSurface&, const scalar planarTol); - - - // Member Functions - - // Access - - inline const triSurface& surface() const - { - return surface_; - } - - inline label size() const - { - return surface_.size(); - } - - //- Get representative point cloud for all shapes inside - // (one point per shape) - pointField shapePoints() const; - - - // Search - - //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface. - // Only makes sense for closed surfaces. - label getVolumeType - ( - const indexedOctree<treeDataTriSurface>&, - const point& - ) const; - - //- Does (bb of) shape at index overlap bb - bool overlaps - ( - const label index, - const treeBoundBox& sampleBb - ) const; - - //- Calculates nearest (to sample) point in shape. - // Returns actual point and distance (squared) - void findNearest - ( - const labelUList& indices, - const point& sample, - - scalar& nearestDistSqr, - label& nearestIndex, - point& nearestPoint - ) const; - - //- Calculates nearest (to line) point in shape. - // Returns point and distance (squared) - void findNearest - ( - const labelUList& indices, - const linePointRef& ln, - - treeBoundBox& tightest, - label& minIndex, - point& linePoint, - point& nearestPoint - ) const; - - //- Calculate intersection of triangle with ray. Sets result - // accordingly - bool intersects - ( - const label index, - const point& start, - const point& end, - point& result - ) const; - -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/meshTools/meshSearch/meshSearch.C b/src/meshTools/meshSearch/meshSearch.C index f05d31710435f424066c378c20d0ef5f0c605744..a28b88b625cbe627ac6b47f118d01452b4608110 100644 --- a/src/meshTools/meshSearch/meshSearch.C +++ b/src/meshTools/meshSearch/meshSearch.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -947,9 +947,7 @@ Foam::List<Foam::pointIndexHit> Foam::meshSearch::intersections bool Foam::meshSearch::isInside(const point& p) const { - return - boundaryTree().getVolumeType(p) - == indexedOctree<treeDataFace>::INSIDE; + return (boundaryTree().getVolumeType(p) == volumeType::INSIDE); } diff --git a/src/meshTools/searchableSurface/searchableBox.C b/src/meshTools/searchableSurface/searchableBox.C index 3503308e422347620127daecb09212fa12e32175..7d639b99f8697205b13c4d6159a395b6630c65a9 100644 --- a/src/meshTools/searchableSurface/searchableBox.C +++ b/src/meshTools/searchableSurface/searchableBox.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -583,7 +583,7 @@ void Foam::searchableBox::getVolumeType ) const { volType.setSize(points.size()); - volType = INSIDE; + volType = volumeType::INSIDE; forAll(points, pointI) { @@ -593,7 +593,7 @@ void Foam::searchableBox::getVolumeType { if (pt[dir] < min()[dir] || pt[dir] > max()[dir]) { - volType[pointI] = OUTSIDE; + volType[pointI] = volumeType::OUTSIDE; break; } } diff --git a/src/meshTools/searchableSurface/searchableCylinder.C b/src/meshTools/searchableSurface/searchableCylinder.C index 3231dd95cd36104c06616ad0fa831a457c1f3baf..70d674d521b580acae0845f51890be762d07ce73 100644 --- a/src/meshTools/searchableSurface/searchableCylinder.C +++ b/src/meshTools/searchableSurface/searchableCylinder.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -673,7 +673,7 @@ void Foam::searchableCylinder::getVolumeType ) const { volType.setSize(points.size()); - volType = INSIDE; + volType = volumeType::INSIDE; forAll(points, pointI) { @@ -687,12 +687,12 @@ void Foam::searchableCylinder::getVolumeType if (parallel < 0) { // left of point1 endcap - volType[pointI] = OUTSIDE; + volType[pointI] = volumeType::OUTSIDE; } else if (parallel > magDir_) { // right of point2 endcap - volType[pointI] = OUTSIDE; + volType[pointI] = volumeType::OUTSIDE; } else { @@ -701,11 +701,11 @@ void Foam::searchableCylinder::getVolumeType if (mag(v) > radius_) { - volType[pointI] = OUTSIDE; + volType[pointI] = volumeType::OUTSIDE; } else { - volType[pointI] = INSIDE; + volType[pointI] = volumeType::INSIDE; } } } diff --git a/src/meshTools/searchableSurface/searchableSphere.C b/src/meshTools/searchableSurface/searchableSphere.C index 5f3e98af90d52edb319a805e95b9bbd9cf4491e2..3d17b52d9fd2c6a392462b8a1c2ad73dfa46c18e 100644 --- a/src/meshTools/searchableSurface/searchableSphere.C +++ b/src/meshTools/searchableSurface/searchableSphere.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -334,7 +334,7 @@ void Foam::searchableSphere::getVolumeType ) const { volType.setSize(points.size()); - volType = INSIDE; + volType = volumeType::INSIDE; forAll(points, pointI) { @@ -342,11 +342,11 @@ void Foam::searchableSphere::getVolumeType if (magSqr(pt - centre_) <= sqr(radius_)) { - volType[pointI] = INSIDE; + volType[pointI] = volumeType::INSIDE; } else { - volType[pointI] = OUTSIDE; + volType[pointI] = volumeType::OUTSIDE; } } } diff --git a/src/meshTools/searchableSurface/searchableSurface.C b/src/meshTools/searchableSurface/searchableSurface.C index decd4c7259ab41d187d438985f5517c2a40527e6..102b8cc8ef9d1b9eac3fe2336812ef39229944be 100644 --- a/src/meshTools/searchableSurface/searchableSurface.C +++ b/src/meshTools/searchableSurface/searchableSurface.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -30,25 +30,11 @@ License namespace Foam { - defineTypeNameAndDebug(searchableSurface, 0); - defineRunTimeSelectionTable(searchableSurface, dict); - - template<> - const char* Foam::NamedEnum - < - Foam::searchableSurface::volumeType, - 4 - >::names[] = - { - "unknown", - "mixed", - "inside", - "outside" - }; -} -const Foam::NamedEnum<Foam::searchableSurface::volumeType, 4> - Foam::searchableSurface::volumeTypeNames; +defineTypeNameAndDebug(searchableSurface, 0); +defineRunTimeSelectionTable(searchableSurface, dict); + +} // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/meshTools/searchableSurface/searchableSurface.H b/src/meshTools/searchableSurface/searchableSurface.H index baeb970844dfe8e7757afa4c0f3679866a23d17a..90224ae9ce54c517b3cdf589467b3533607d930e 100644 --- a/src/meshTools/searchableSurface/searchableSurface.H +++ b/src/meshTools/searchableSurface/searchableSurface.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -48,6 +48,7 @@ SourceFiles #include "pointIndexHit.H" #include "linePointRef.H" #include "objectRegistry.H" +#include "volumeType.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -67,25 +68,6 @@ class searchableSurface : public regIOobject { -public: - - // Data types - - //- Volume types - enum volumeType - { - UNKNOWN = 0, - MIXED = 1, // not used. only here to maintain consistency with - // indexedOctree volumeType. - INSIDE = 2, - OUTSIDE = 3 - }; - - static const NamedEnum<volumeType, 4> volumeTypeNames; - - -private: - // Private data const word name_; @@ -278,6 +260,19 @@ public: List<pointIndexHit>& ) const = 0; + //- Find the nearest locations for the supplied points to a + // particular region in the searchable surface. + virtual void findNearest + ( + const pointField& samples, + const scalarField& nearestDistSqr, + const labelList& regionIndices, + List<pointIndexHit>& info + ) const + { + findNearest(samples, nearestDistSqr, info); + } + //- Find first intersection on segment from start to end. // Note: searchableSurfacesQueries expects no // intersection to be found if start==end. Is problem? diff --git a/src/meshTools/searchableSurface/searchableSurfaces.C b/src/meshTools/searchableSurface/searchableSurfaces.C index 0612e20d80744494d533b0896240b8b79bed12b6..08569aba78c155437d42bbf086470fd11dedc419 100644 --- a/src/meshTools/searchableSurface/searchableSurfaces.C +++ b/src/meshTools/searchableSurface/searchableSurfaces.C @@ -293,6 +293,18 @@ Foam::label Foam::searchableSurfaces::findSurfaceID } +Foam::label Foam::searchableSurfaces::findSurfaceRegionID +( + const word& surfaceName, + const word& regionName +) const +{ + label surfaceIndex = findSurfaceID(surfaceName); + + return findIndex(regionNames()[surfaceIndex], regionName); +} + + // Find any intersection void Foam::searchableSurfaces::findAnyIntersection ( @@ -382,6 +394,28 @@ void Foam::searchableSurfaces::findNearest } +// Find nearest. Return -1 or nearest point +void Foam::searchableSurfaces::findNearest +( + const pointField& samples, + const scalarField& nearestDistSqr, + const labelList& regionIndices, + labelList& nearestSurfaces, + List<pointIndexHit>& nearestInfo +) const +{ + searchableSurfacesQueries::findNearest + ( + *this, + allSurfaces_, + samples, + nearestDistSqr, + regionIndices, + nearestSurfaces, + nearestInfo + ); +} + //- Calculate bounding box Foam::boundBox Foam::searchableSurfaces::bounds() const { diff --git a/src/meshTools/searchableSurface/searchableSurfaces.H b/src/meshTools/searchableSurface/searchableSurfaces.H index 107e343ef3d262f077a105dfce0441f757b435a5..22ba450e9d2db6aae1d08710d7849a650319fd11 100644 --- a/src/meshTools/searchableSurface/searchableSurfaces.H +++ b/src/meshTools/searchableSurface/searchableSurfaces.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -140,6 +140,11 @@ public: //- Find index of surface. Return -1 if not found. label findSurfaceID(const word& name) const; + label findSurfaceRegionID + ( + const word& surfaceName, + const word& regionName + ) const; // Multiple point queries. @@ -185,6 +190,15 @@ public: List<pointIndexHit>& ) const; + void findNearest + ( + const pointField& samples, + const scalarField& nearestDistSqr, + const labelList& regionIndices, + labelList& nearestSurfaces, + List<pointIndexHit>& nearestInfo + ) const; + //- Calculate bounding box boundBox bounds() const; diff --git a/src/meshTools/searchableSurface/searchableSurfacesQueries.C b/src/meshTools/searchableSurface/searchableSurfacesQueries.C index b2144cf24aa38c06393e9bc4ec561d4aa2c67e5f..2073de3d767d44972d07174948fafb552e286405 100644 --- a/src/meshTools/searchableSurface/searchableSurfacesQueries.C +++ b/src/meshTools/searchableSurface/searchableSurfacesQueries.C @@ -324,9 +324,8 @@ bool Foam::searchableSurfacesQueries::morphTet void Foam::searchableSurfacesQueries::mergeHits ( const point& start, - const scalar mergeDist, - const label testI, // index of surface + const label testI, // index of surface const List<pointIndexHit>& surfHits, // hits on surface labelList& allSurfaces, @@ -338,7 +337,7 @@ void Foam::searchableSurfacesQueries::mergeHits scalarList surfDistSqr(surfHits.size()); forAll(surfHits, i) { - surfDistSqr[i] = magSqr(surfHits[i].hitPoint()-start); + surfDistSqr[i] = magSqr(surfHits[i].hitPoint() - start); } forAll(surfDistSqr, i) @@ -346,11 +345,7 @@ void Foam::searchableSurfacesQueries::mergeHits label index = findLower(allDistSqr, surfDistSqr[i]); // Check if equal to lower. - if - ( - index >= 0 - && (mag(allDistSqr[index]-surfDistSqr[i]) < mergeDist) - ) + if (index >= 0) { // Same. Do not count. //Pout<< "point:" << surfHits[i].hitPoint() @@ -361,12 +356,9 @@ void Foam::searchableSurfacesQueries::mergeHits else { // Check if equal to higher - label next = index+1; - if - ( - next < allDistSqr.size() - && (mag(allDistSqr[next]-surfDistSqr[i]) < mergeDist) - ) + label next = index + 1; + + if (next < allDistSqr.size()) { //Pout<< "point:" << surfHits[i].hitPoint() // << " considered same as:" << allInfo[next].hitPoint() @@ -510,21 +502,6 @@ void Foam::searchableSurfacesQueries::findAllIntersections if (surfacesToTest.size() > 1) { - // Small vector to increment start vector by to find next intersection - // along line. Constant factor added to make sure that start==end still - // ends iteration in findAllIntersections. Also SMALL is just slightly - // too small. - const vectorField smallVec - ( - 1E2*SMALL*(end-start) - + vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL) - ); - - // Tolerance used to check whether points are equal. Note: used to - // compare distance^2. Note that we use the maximum possible tolerance - // (reached at intersections close to the end point) - const scalarField mergeDist(2*mag(smallVec)*mag(end-start)); - // Test the other surfaces and merge (according to distance from start). for (label testI = 1; testI < surfacesToTest.size(); testI++) { @@ -541,7 +518,6 @@ void Foam::searchableSurfacesQueries::findAllIntersections mergeHits ( start[pointI], // Current segment - mergeDist[pointI], testI, // Surface and its hits surfHits[pointI], @@ -691,13 +667,75 @@ void Foam::searchableSurfacesQueries::findNearest } +// Find nearest. Return -1 or nearest point +void Foam::searchableSurfacesQueries::findNearest +( + const PtrList<searchableSurface>& allSurfaces, + const labelList& surfacesToTest, + const pointField& samples, + const scalarField& nearestDistSqr, + const labelList& regionIndices, + labelList& nearestSurfaces, + List<pointIndexHit>& nearestInfo +) +{ + if (regionIndices.empty()) + { + findNearest + ( + allSurfaces, + surfacesToTest, + samples, + nearestDistSqr, + nearestSurfaces, + nearestInfo + ); + } + + // Initialise + nearestSurfaces.setSize(samples.size()); + nearestSurfaces = -1; + nearestInfo.setSize(samples.size()); + + // Work arrays + scalarField minDistSqr(nearestDistSqr); + List<pointIndexHit> hitInfo(samples.size()); + + forAll(surfacesToTest, testI) + { + allSurfaces[surfacesToTest[testI]].findNearest + ( + samples, + minDistSqr, + regionIndices, + hitInfo + ); + + // Update minDistSqr and arguments + forAll(hitInfo, pointI) + { + if (hitInfo[pointI].hit()) + { + minDistSqr[pointI] = magSqr + ( + hitInfo[pointI].hitPoint() + - samples[pointI] + ); + nearestInfo[pointI] = hitInfo[pointI]; + nearestSurfaces[pointI] = testI; + } + } + } +} + + void Foam::searchableSurfacesQueries::signedDistance ( const PtrList<searchableSurface>& allSurfaces, const labelList& surfacesToTest, const pointField& samples, const scalarField& nearestDistSqr, - const searchableSurface::volumeType illegalHandling, + const volumeType illegalHandling, labelList& nearestSurfaces, scalarField& distance ) @@ -737,7 +775,7 @@ void Foam::searchableSurfacesQueries::signedDistance } // Calculate sideness of these surface points - List<searchableSurface::volumeType> volType; + List<volumeType> volType; allSurfaces[surfacesToTest[testI]].getVolumeType(surfPoints, volType); // Push back to original @@ -746,13 +784,13 @@ void Foam::searchableSurfacesQueries::signedDistance label pointI = surfIndices[i]; scalar dist = mag(samples[pointI] - nearestInfo[pointI].hitPoint()); - searchableSurface::volumeType vT = volType[i]; + volumeType vT = volType[i]; - if (vT == searchableSurface::OUTSIDE) + if (vT == volumeType::OUTSIDE) { distance[pointI] = dist; } - else if (vT == searchableSurface::INSIDE) + else if (vT == volumeType::INSIDE) { distance[i] = -dist; } @@ -760,12 +798,12 @@ void Foam::searchableSurfacesQueries::signedDistance { switch (illegalHandling) { - case searchableSurface::OUTSIDE: + case volumeType::OUTSIDE: { distance[pointI] = dist; break; } - case searchableSurface::INSIDE: + case volumeType::INSIDE: { distance[pointI] = -dist; break; @@ -779,7 +817,7 @@ void Foam::searchableSurfacesQueries::signedDistance << " surface:" << allSurfaces[surfacesToTest[testI]].name() << " volType:" - << searchableSurface::volumeTypeNames[vT] + << volumeType::names[vT] << exit(FatalError); break; } diff --git a/src/meshTools/searchableSurface/searchableSurfacesQueries.H b/src/meshTools/searchableSurface/searchableSurfacesQueries.H index 9f2ebfbadb6c575aaf0c5fb9a431acf6079df455..529d4b94fabb44b8d08695573fd5f0f60d204226 100644 --- a/src/meshTools/searchableSurface/searchableSurfacesQueries.H +++ b/src/meshTools/searchableSurface/searchableSurfacesQueries.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -116,7 +116,6 @@ class searchableSurfacesQueries static void mergeHits ( const point& start, - const scalar mergeDist, const label surfI, const List<pointIndexHit>& surfHits, @@ -184,6 +183,18 @@ public: List<pointIndexHit>& ); + //- Find nearest points to a specific region of the surface + static void findNearest + ( + const PtrList<searchableSurface>& allSurfaces, + const labelList& surfacesToTest, + const pointField& samples, + const scalarField& nearestDistSqr, + const labelList& regionIndices, + labelList& nearestSurfaces, + List<pointIndexHit>& nearestInfo + ); + //- Find signed distance to nearest surface. Outside is positive. // illegalHandling: how to handle non-inside or outside // OUTSIDE : treat as outside @@ -195,7 +206,7 @@ public: const labelList& surfacesToTest, const pointField& samples, const scalarField& nearestDistSqr, - const searchableSurface::volumeType illegalHandling, + const volumeType illegalHandling, labelList& nearestSurfaces, scalarField& distance ); diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.C b/src/meshTools/searchableSurface/triSurfaceMesh.C index 4e42f5d3adce4ae3cbdf8486c76430f910a2574d..22229817932e31a1704fbc6608975d6e8b65ec48 100644 --- a/src/meshTools/searchableSurface/triSurfaceMesh.C +++ b/src/meshTools/searchableSurface/triSurfaceMesh.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -29,7 +29,7 @@ License #include "EdgeMap.H" #include "triSurfaceFields.H" #include "Time.H" -#include "PackedBoolList.H" +#include "PatchTools.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -218,99 +218,6 @@ bool Foam::triSurfaceMesh::isSurfaceClosed() const } -// Gets all intersections after initial one. Adds smallVec and starts tracking -// from there. -void Foam::triSurfaceMesh::getNextIntersections -( - const indexedOctree<treeDataTriSurface>& octree, - const point& start, - const point& end, - const vector& smallVec, - DynamicList<pointIndexHit, 1, 1>& hits -) -{ - const vector dirVec(end-start); - const scalar magSqrDirVec(magSqr(dirVec)); - - // Initial perturbation amount - vector perturbVec(smallVec); - - while (true) - { - // Start tracking from last hit. - point pt = hits.last().hitPoint() + perturbVec; - - if (((pt-start)&dirVec) > magSqrDirVec) - { - return; - } - - // See if any intersection between pt and end - pointIndexHit inter = octree.findLine(pt, end); - - if (!inter.hit()) - { - return; - } - - // Check if already found this intersection - bool duplicateHit = false; - forAllReverse(hits, i) - { - if (hits[i].index() == inter.index()) - { - duplicateHit = true; - break; - } - } - - - if (duplicateHit) - { - // Hit same triangle again. Increase perturbVec and try again. - perturbVec *= 2; - } - else - { - // Proper hit - hits.append(inter); - // Restore perturbVec - perturbVec = smallVec; - } - } -} - - -void Foam::triSurfaceMesh::calcBounds(boundBox& bb, label& nPoints) const -{ - // Unfortunately nPoints constructs meshPoints() so do compact version - // ourselves - - const triSurface& s = static_cast<const triSurface&>(*this); - - PackedBoolList pointIsUsed(points()().size()); - - nPoints = 0; - bb = boundBox::invertedBox; - - forAll(s, faceI) - { - const triSurface::FaceType& f = s[faceI]; - - forAll(f, fp) - { - label pointI = f[fp]; - if (pointIsUsed.set(pointI, 1u)) - { - bb.min() = ::Foam::min(bb.min(), points()()[pointI]); - bb.max() = ::Foam::max(bb.max(), points()()[pointI]); - nPoints++; - } - } - } -} - - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s) @@ -330,9 +237,8 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s) ) ), triSurface(s), - tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()), + triSurfaceRegionSearch(s), minQuality_(-1), - maxTreeDepth_(10), surfaceClosed_(-1) { bounds() = boundBox(points()); @@ -377,9 +283,8 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io) searchableSurface::objectPath() ) ), - tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()), + triSurfaceRegionSearch(static_cast<const triSurface&>(*this)), minQuality_(-1), - maxTreeDepth_(10), surfaceClosed_(-1) { bounds() = boundBox(points()); @@ -427,9 +332,8 @@ Foam::triSurfaceMesh::triSurfaceMesh searchableSurface::objectPath() ) ), - tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()), + triSurfaceRegionSearch(static_cast<const triSurface&>(*this), dict), minQuality_(-1), - maxTreeDepth_(10), surfaceClosed_(-1) { scalar scaleFactor = 0; @@ -445,13 +349,6 @@ Foam::triSurfaceMesh::triSurfaceMesh bounds() = boundBox(points()); - // Have optional non-standard search tolerance for gappy surfaces. - if (dict.readIfPresent("tolerance", tolerance_) && tolerance_ > 0) - { - Info<< searchableSurface::name() << " : using intersection tolerance " - << tolerance_ << endl; - } - // Have optional minimum quality for normal calculation if (dict.readIfPresent("minQuality", minQuality_) && minQuality_ > 0) { @@ -459,13 +356,6 @@ Foam::triSurfaceMesh::triSurfaceMesh << " : ignoring triangles with quality < " << minQuality_ << " for normals calculation." << endl; } - - // Have optional non-standard tree-depth to limit storage. - if (dict.readIfPresent("maxTreeDepth", maxTreeDepth_) && maxTreeDepth_ > 0) - { - Info<< searchableSurface::name() << " : using maximum tree depth " - << maxTreeDepth_ << endl; - } } @@ -479,7 +369,7 @@ Foam::triSurfaceMesh::~triSurfaceMesh() void Foam::triSurfaceMesh::clearOut() { - tree_.clear(); + triSurfaceRegionSearch::clearOut(); edgeTree_.clear(); triSurface::clearOut(); } @@ -521,64 +411,12 @@ bool Foam::triSurfaceMesh::overlaps(const boundBox& bb) const void Foam::triSurfaceMesh::movePoints(const pointField& newPoints) { - tree_.clear(); + triSurfaceRegionSearch::clearOut(); edgeTree_.clear(); triSurface::movePoints(newPoints); } -const Foam::indexedOctree<Foam::treeDataTriSurface>& -Foam::triSurfaceMesh::tree() const -{ - if (tree_.empty()) - { - // Calculate bb without constructing local point numbering. - treeBoundBox bb; - label nPoints; - calcBounds(bb, nPoints); - - if (nPoints != points()().size()) - { - WarningIn("triSurfaceMesh::tree() const") - << "Surface " << searchableSurface::name() - << " does not have compact point numbering." - << " Of " << points()().size() << " only " << nPoints - << " are used. This might give problems in some routines." - << endl; - } - - - // Random number generator. Bit dodgy since not exactly random ;-) - Random rndGen(65431); - - // Slightly extended bb. Slightly off-centred just so on symmetric - // geometry there are less face/edge aligned items. - bb = bb.extend(rndGen, 1e-4); - bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); - bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); - - scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); - indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; - - tree_.reset - ( - new indexedOctree<treeDataTriSurface> - ( - treeDataTriSurface(*this, tolerance_), - bb, - maxTreeDepth_, // maxLevel - 10, // leafsize - 3.0 // duplicity - ) - ); - - indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; - } - - return tree_(); -} - - const Foam::indexedOctree<Foam::treeDataEdge>& Foam::triSurfaceMesh::edgeTree() const { @@ -597,7 +435,12 @@ Foam::triSurfaceMesh::edgeTree() const treeBoundBox bb; label nPoints; - calcBounds(bb, nPoints); + PatchTools::calcBounds + ( + static_cast<const triSurface&>(*this), + bb, + nPoints + ); // Random number generator. Bit dodgy since not exactly random ;-) Random rndGen(65431); @@ -609,8 +452,8 @@ Foam::triSurfaceMesh::edgeTree() const bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); - scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); - indexedOctree<treeDataEdge>::perturbTol() = tolerance_; + scalar oldTol = indexedOctree<treeDataEdge>::perturbTol(); + indexedOctree<treeDataEdge>::perturbTol() = tolerance(); edgeTree_.reset ( @@ -624,7 +467,7 @@ Foam::triSurfaceMesh::edgeTree() const bEdges // selected edges ), bb, // bb - maxTreeDepth_, // maxLevel + maxTreeDepth(), // maxLevel 10, // leafsize 3.0 // duplicity ) @@ -636,12 +479,6 @@ Foam::triSurfaceMesh::edgeTree() const } -Foam::scalar Foam::triSurfaceMesh::tolerance() const -{ - return tolerance_; -} - - const Foam::wordList& Foam::triSurfaceMesh::regions() const { if (regions_.empty()) @@ -682,23 +519,25 @@ void Foam::triSurfaceMesh::findNearest List<pointIndexHit>& info ) const { - const indexedOctree<treeDataTriSurface>& octree = tree(); - - info.setSize(samples.size()); - - scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); - indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; + triSurfaceSearch::findNearest(samples, nearestDistSqr, info); +} - forAll(samples, i) - { - static_cast<pointIndexHit&>(info[i]) = octree.findNearest - ( - samples[i], - nearestDistSqr[i] - ); - } - indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; +void Foam::triSurfaceMesh::findNearest +( + const pointField& samples, + const scalarField& nearestDistSqr, + const labelList& regionIndices, + List<pointIndexHit>& info +) const +{ + triSurfaceRegionSearch::findNearest + ( + samples, + nearestDistSqr, + regionIndices, + info + ); } @@ -709,23 +548,7 @@ void Foam::triSurfaceMesh::findLine List<pointIndexHit>& info ) const { - const indexedOctree<treeDataTriSurface>& octree = tree(); - - info.setSize(start.size()); - - scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); - indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; - - forAll(start, i) - { - static_cast<pointIndexHit&>(info[i]) = octree.findLine - ( - start[i], - end[i] - ); - } - - indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; + triSurfaceSearch::findLine(start, end, info); } @@ -736,23 +559,7 @@ void Foam::triSurfaceMesh::findLineAny List<pointIndexHit>& info ) const { - const indexedOctree<treeDataTriSurface>& octree = tree(); - - info.setSize(start.size()); - - scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); - indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; - - forAll(start, i) - { - static_cast<pointIndexHit&>(info[i]) = octree.findLineAny - ( - start[i], - end[i] - ); - } - - indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; + triSurfaceSearch::findLineAny(start, end, info); } @@ -763,57 +570,7 @@ void Foam::triSurfaceMesh::findLineAll List<List<pointIndexHit> >& info ) const { - const indexedOctree<treeDataTriSurface>& octree = tree(); - - info.setSize(start.size()); - - scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); - indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; - - // Work array - DynamicList<pointIndexHit, 1, 1> hits; - - // Tolerances: - // To find all intersections we add a small vector to the last intersection - // This is chosen such that - // - it is significant (SMALL is smallest representative relative tolerance; - // we need something bigger since we're doing calculations) - // - if the start-end vector is zero we still progress - const vectorField dirVec(end-start); - const vectorField smallVec - ( - indexedOctree<treeDataTriSurface>::perturbTol()*dirVec - + vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL) - ); - - forAll(start, pointI) - { - // See if any intersection between pt and end - pointIndexHit inter = octree.findLine(start[pointI], end[pointI]); - - if (inter.hit()) - { - hits.clear(); - hits.append(inter); - - getNextIntersections - ( - octree, - start[pointI], - end[pointI], - smallVec[pointI], - hits - ); - - info[pointI].transfer(hits); - } - else - { - info[pointI].clear(); - } - } - - indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; + triSurfaceSearch::findLineAll(start, end, info); } @@ -975,7 +732,7 @@ void Foam::triSurfaceMesh::getVolumeType volType.setSize(points.size()); scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); - indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance(); forAll(points, pointI) { @@ -983,7 +740,7 @@ void Foam::triSurfaceMesh::getVolumeType // - use cached volume type per each tree node // - cheat conversion since same values - volType[pointI] = static_cast<volumeType>(tree().getVolumeType(pt)); + volType[pointI] = tree().getVolumeType(pt); } indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.H b/src/meshTools/searchableSurface/triSurfaceMesh.H index f27df49d7c85d89d876a63287277a344c8284f06..fa7e9e511c769a0d37b7eb6d9b9a885ecaa367cd 100644 --- a/src/meshTools/searchableSurface/triSurfaceMesh.H +++ b/src/meshTools/searchableSurface/triSurfaceMesh.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -46,8 +46,11 @@ SourceFiles #include "objectRegistry.H" #include "indexedOctree.H" #include "treeDataTriSurface.H" +#include "treeDataPrimitivePatch.H" #include "treeDataEdge.H" #include "EdgeMap.H" +#include "triSurface.H" +#include "triSurfaceRegionSearch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -62,25 +65,17 @@ class triSurfaceMesh : public searchableSurface, public objectRegistry, // so we can store fields - public triSurface + public triSurface, + public triSurfaceRegionSearch { private: // Private member data - //- Optional tolerance to use in searches - scalar tolerance_; - //- Optional min triangle quality. Triangles below this get // ignored for normal calculation scalar minQuality_; - //- Optional max tree depth of octree - label maxTreeDepth_; - - //- Search tree (triangles) - mutable autoPtr<indexedOctree<treeDataTriSurface> > tree_; - //- Search tree for boundary edges. mutable autoPtr<indexedOctree<treeDataEdge> > edgeTree_; @@ -136,11 +131,6 @@ private: void operator=(const triSurfaceMesh&); -protected: - - //- Calculate (number of)used points and their bounding box - void calcBounds(boundBox& bb, label& nPoints) const; - public: //- Runtime type information @@ -176,13 +166,9 @@ public: //- Move points virtual void movePoints(const pointField&); - //- Demand driven contruction of octree - const indexedOctree<treeDataTriSurface>& tree() const; - //- Demand driven contruction of octree for boundary edges const indexedOctree<treeDataEdge>& edgeTree() const; - scalar tolerance() const; // searchableSurface implementation @@ -214,6 +200,14 @@ public: List<pointIndexHit>& ) const; + virtual void findNearest + ( + const pointField& sample, + const scalarField& nearestDistSqr, + const labelList& regionIndices, + List<pointIndexHit>& + ) const; + virtual void findLine ( const pointField& start, diff --git a/src/meshTools/sets/pointSources/surfaceToPoint/surfaceToPoint.C b/src/meshTools/sets/pointSources/surfaceToPoint/surfaceToPoint.C index 4aaf9eee17664ef0ea78003a83f29ab9666ca9fa..34381e4a027f78c847581301a5fb7ceceedc1d41 100644 --- a/src/meshTools/sets/pointSources/surfaceToPoint/surfaceToPoint.C +++ b/src/meshTools/sets/pointSources/surfaceToPoint/surfaceToPoint.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -26,6 +26,7 @@ License #include "surfaceToPoint.H" #include "polyMesh.H" #include "triSurfaceSearch.H" +#include "triSurface.H" #include "cpuTime.H" #include "addToRunTimeSelectionTable.H" diff --git a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C index 9af93cf0b7be7b5b6962ded550c1f707903dcc06..b54ad7143d7adce09b0f47a6e392d347b3d054e4 100644 --- a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C +++ b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -694,6 +694,7 @@ void Foam::surfaceIntersection::doCutEdges } while (doTrack); } + intersection::setPlanarTol(oldTol); } diff --git a/src/meshTools/triSurface/orientedSurface/orientedSurface.C b/src/meshTools/triSurface/orientedSurface/orientedSurface.C index 95acfa125c60ad32dbb8b5bc4ffc43f0d51939b3..0466343eb5307c5690dbdd76fe75ec6c90f372e7 100644 --- a/src/meshTools/triSurface/orientedSurface/orientedSurface.C +++ b/src/meshTools/triSurface/orientedSurface/orientedSurface.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -258,7 +258,8 @@ void Foam::orientedSurface::findZoneSide zoneFaceI = -1; isOutside = false; - List<pointIndexHit> hits; + pointField start(1, outsidePoint); + List<List<pointIndexHit> > hits(1, List<pointIndexHit>()); forAll(faceZone, faceI) { @@ -273,7 +274,7 @@ void Foam::orientedSurface::findZoneSide // Check if normal different enough to decide upon if (magD > SMALL && (mag(n & d/magD) > 1e-6)) { - point end = fc + d; + pointField end(1, fc + d); //Info<< "Zone " << zoneI << " : Shooting ray" // << " from " << outsidePoint @@ -281,12 +282,13 @@ void Foam::orientedSurface::findZoneSide // << " to pierce triangle " << faceI // << " with centre " << fc << endl; - surfSearches.findLineAll(outsidePoint, end, hits); + + surfSearches.findLineAll(start, end, hits); label zoneIndex = -1; - forAll(hits, i) + forAll(hits[0], i) { - if (hits[i].index() == faceI) + if (hits[0][i].index() == faceI) { zoneIndex = i; break; diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C new file mode 100644 index 0000000000000000000000000000000000000000..738cb8dcdd183a5a4e9ecdc0f603bae68b73d855 --- /dev/null +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C @@ -0,0 +1,246 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "triSurfaceRegionSearch.H" +#include "indexedOctree.H" +#include "triSurface.H" +#include "PatchTools.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::triSurfaceRegionSearch::triSurfaceRegionSearch(const triSurface& surface) +: + triSurfaceSearch(surface), + indirectRegionPatches_(), + treeByRegion_() +{} + + +Foam::triSurfaceRegionSearch::triSurfaceRegionSearch +( + const triSurface& surface, + const dictionary& dict +) +: + triSurfaceSearch(surface, dict), + indirectRegionPatches_(), + treeByRegion_() +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::triSurfaceRegionSearch::~triSurfaceRegionSearch() +{ + clearOut(); +} + + +void Foam::triSurfaceRegionSearch::clearOut() +{ + triSurfaceSearch::clearOut(); + treeByRegion_.clear(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +const Foam::PtrList<Foam::triSurfaceRegionSearch::treeType>& +Foam::triSurfaceRegionSearch::treeByRegion() const +{ + if (treeByRegion_.empty()) + { + Map<label> regionSizes; + forAll(surface(), fI) + { + const label regionI = surface()[fI].region(); + + regionSizes(regionI)++; + } + + label nRegions = regionSizes.size(); + + indirectRegionPatches_.setSize(nRegions); + treeByRegion_.setSize(nRegions); + + labelListList regionsAddressing(nRegions); + + forAll(regionsAddressing, regionI) + { + regionsAddressing[regionI] = labelList(regionSizes[regionI], -1); + } + + labelList nFacesInRegions(nRegions, 0); + + forAll(surface(), fI) + { + const label regionI = surface()[fI].region(); + + regionsAddressing[regionI][nFacesInRegions[regionI]++] = fI; + } + + forAll(regionsAddressing, regionI) + { + scalar oldTol = treeType::perturbTol(); + treeType::perturbTol() = tolerance(); + + indirectRegionPatches_.set + ( + regionI, + new indirectTriSurface + ( + IndirectList<labelledTri> + ( + surface(), + regionsAddressing[regionI] + ), + surface().points() + ) + ); + + // Calculate bb without constructing local point numbering. + treeBoundBox bb; + label nPoints; + PatchTools::calcBounds + ( + indirectRegionPatches_[regionI], + bb, + nPoints + ); + +// if (nPoints != surface().points().size()) +// { +// WarningIn("triSurfaceRegionSearch::treeByRegion() const") +// << "Surface does not have compact point numbering. " +// << "Of " << surface().points().size() +// << " only " << nPoints +// << " are used. This might give problems in some routines." +// << endl; +// } + + // Random number generator. Bit dodgy since not exactly random ;-) + Random rndGen(65431); + + // Slightly extended bb. Slightly off-centred just so on symmetric + // geometry there are fewer face/edge aligned items. + bb = bb.extend(rndGen, 1e-4); + bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + treeByRegion_.set + ( + regionI, + new treeType + ( + treeDataIndirectTriSurface + ( + true, + indirectRegionPatches_[regionI], + tolerance() + ), + bb, + maxTreeDepth(), // maxLevel + 10, // leafsize + 3.0 // duplicity + ) + ); + + treeType::perturbTol() = oldTol; + } + } + + return treeByRegion_; +} + + +void Foam::triSurfaceRegionSearch::findNearest +( + const pointField& samples, + const scalarField& nearestDistSqr, + const labelList& regionIndices, + List<pointIndexHit>& info +) const +{ + if (regionIndices.empty()) + { + triSurfaceSearch::findNearest(samples, nearestDistSqr, info); + } + else + { + scalar oldTol = treeType::perturbTol(); + treeType::perturbTol() = tolerance(); + + const PtrList<treeType>& octrees = treeByRegion(); + + info.setSize(samples.size()); + + forAll(octrees, treeI) + { + if (findIndex(regionIndices, treeI) == -1) + { + continue; + } + + const treeType& octree = octrees[treeI]; + + forAll(samples, i) + { +// if (!octree.bb().contains(samples[i])) +// { +// continue; +// } + + pointIndexHit currentRegionHit = octree.findNearest + ( + samples[i], + nearestDistSqr[i], + treeDataIndirectTriSurface::findNearestOp(octree) + ); + + if + ( + currentRegionHit.hit() + && + ( + !info[i].hit() + || + ( + magSqr(currentRegionHit.hitPoint() - samples[i]) + < magSqr(info[i].hitPoint() - samples[i]) + ) + ) + ) + { + info[i] = currentRegionHit; + } + } + } + + treeType::perturbTol() = oldTol; + } +} + + +// ************************************************************************* // diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.H b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.H new file mode 100644 index 0000000000000000000000000000000000000000..c8c421b900200e1c72d3ae62e23432e69b4254d8 --- /dev/null +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.H @@ -0,0 +1,144 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-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 <http://www.gnu.org/licenses/>. + +Class + Foam::triSurfaceRegionSearch + +Description + Helper class to search on triSurface. Creates an octree for each region of + the surface and only searches on the specified regions. + +SourceFiles + triSurfaceRegionSearch.C + +\*---------------------------------------------------------------------------*/ + +#ifndef triSurfaceRegionSearch_H +#define triSurfaceRegionSearch_H + +#include "pointField.H" +#include "pointIndexHit.H" +#include "triSurfaceSearch.H" +#include "labelledTri.H" +#include "IndirectList.H" +#include "PtrList.H" +#include "indexedOctree.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class triSurfaceRegionSearch Declaration +\*---------------------------------------------------------------------------*/ + +class triSurfaceRegionSearch +: + public triSurfaceSearch +{ + // Private typedefs + + typedef PrimitivePatch + < + labelledTri, + IndirectList, + const pointField& + > indirectTriSurface; + + typedef treeDataPrimitivePatch<indirectTriSurface> + treeDataIndirectTriSurface; + + typedef indexedOctree<treeDataIndirectTriSurface> treeType; + + + // Private data + + //- Surface is split into patches by region + mutable PtrList<indirectTriSurface> indirectRegionPatches_; + + //- Search tree for each region + mutable PtrList<treeType> treeByRegion_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + triSurfaceRegionSearch(const triSurfaceRegionSearch&); + + //- Disallow default bitwise assignment + void operator=(const triSurfaceRegionSearch&); + + +public: + + // Constructors + + //- Construct from surface. Holds reference to surface! + explicit triSurfaceRegionSearch(const triSurface&); + + //- Construct from surface and dictionary. Holds reference to surface! + triSurfaceRegionSearch(const triSurface&, const dictionary& dict); + + + //- Destructor + ~triSurfaceRegionSearch(); + + //- Clear storage + void clearOut(); + + + // Member Functions + + // Access + + //- Demand driven construction of octree for each region. + // @todo Currently creates a tree for each region; could optimise + // by only constructing trees when they are in regionIndices + const PtrList<treeType>& treeByRegion() const; + + + // Query + + //- Find the nearest point on the surface out of the regions + // supplied in the list regionIndices. Ignores regions that are + // not specified + void findNearest + ( + const pointField& samples, + const scalarField& nearestDistSqr, + const labelList& regionIndices, + List<pointIndexHit>& info + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C index 28f6393b2c28b84d209dc10b1c3d0ce7ccb7b468..aad1a824eb8985a9b0c7cddf94a2f1f74db51a9c 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -24,62 +24,203 @@ License \*---------------------------------------------------------------------------*/ #include "triSurfaceSearch.H" -#include "indexedOctree.H" -#include "boolList.H" -#include "treeDataTriSurface.H" #include "triSurface.H" -#include "line.H" -#include "cpuTime.H" +#include "PatchTools.H" +#include "volumeType.H" -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -const Foam::point Foam::triSurfaceSearch::greatPoint(GREAT, GREAT, GREAT); +bool Foam::triSurfaceSearch::checkUniqueHit +( + const pointIndexHit& currHit, + const DynamicList<pointIndexHit, 1, 1>& hits, + const vector& lineVec +) const +{ + // Classify the hit + label nearType = -1; + label nearLabel = -1; + + const labelledTri& f = surface()[currHit.index()]; + + f.nearestPointClassify + ( + currHit.hitPoint(), + surface().points(), + nearType, + nearLabel + ); + + if (nearType == 1) + { + // near point + } + else if (nearType == 2) + { + // near edge + // check if the other face of the edge is already hit + + const labelList& fEdges = surface().faceEdges()[currHit.index()]; + + const label edgeI = fEdges[nearLabel]; + + const labelList& edgeFaces = surface().edgeFaces()[edgeI]; + + forAll(edgeFaces, fI) + { + const label edgeFaceI = edgeFaces[fI]; + + if (edgeFaceI != currHit.index()) + { + forAll(hits, hI) + { + const pointIndexHit& hit = hits[hI]; + + if (hit.index() == edgeFaceI) + { + // Check normals + const vector currHitNormal = + surface().faceNormals()[currHit.index()]; + + const vector existingHitNormal = + surface().faceNormals()[edgeFaceI]; + + const label signCurrHit = + pos(currHitNormal & lineVec); + + const label signExistingHit = + pos(existingHitNormal & lineVec); + + if (signCurrHit == signExistingHit) + { + return false; + } + } + } + } + } + } + + return true; +} // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -// Construct from surface. Holds reference! Foam::triSurfaceSearch::triSurfaceSearch(const triSurface& surface) : surface_(surface), + tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()), + maxTreeDepth_(10), + treePtr_(NULL) +{} + + +Foam::triSurfaceSearch::triSurfaceSearch +( + const triSurface& surface, + const dictionary& dict +) +: + surface_(surface), + tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()), + maxTreeDepth_(10), treePtr_(NULL) { - // Random number generator. Bit dodgy since not exactly random ;-) - Random rndGen(65431); + // Have optional non-standard search tolerance for gappy surfaces. + if (dict.readIfPresent("tolerance", tolerance_) && tolerance_ > 0) + { + Info<< " using intersection tolerance " << tolerance_ << endl; + } - // Slightly extended bb. Slightly off-centred just so on symmetric - // geometry there are less face/edge aligned items. - treeBoundBox treeBb - ( - treeBoundBox(surface_.points(), surface_.meshPoints()).extend - ( - rndGen, - 1e-4 - ) - ); - treeBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); - treeBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + // Have optional non-standard tree-depth to limit storage. + if (dict.readIfPresent("maxTreeDepth", maxTreeDepth_) && maxTreeDepth_ > 0) + { + Info<< " using maximum tree depth " << maxTreeDepth_ << endl; + } +} - treePtr_.reset - ( - new indexedOctree<treeDataTriSurface> - ( - treeDataTriSurface - ( - surface_, - indexedOctree<treeDataTriSurface>::perturbTol() - ), - treeBb, - 8, // maxLevel - 10, // leafsize - 3.0 // duplicity - ) - ); + +Foam::triSurfaceSearch::triSurfaceSearch +( + const triSurface& surface, + const scalar tolerance, + const label maxTreeDepth +) +: + surface_(surface), + tolerance_(tolerance), + maxTreeDepth_(maxTreeDepth), + treePtr_(NULL) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::triSurfaceSearch::~triSurfaceSearch() +{ + clearOut(); +} + + +void Foam::triSurfaceSearch::clearOut() +{ + treePtr_.clear(); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +const Foam::indexedOctree<Foam::treeDataTriSurface>& +Foam::triSurfaceSearch::tree() const +{ + if (treePtr_.empty()) + { + // Calculate bb without constructing local point numbering. + treeBoundBox bb; + label nPoints; + PatchTools::calcBounds(surface(), bb, nPoints); + + if (nPoints != surface().points().size()) + { + WarningIn("triSurfaceSearch::tree() const") + << "Surface does not have compact point numbering." + << " Of " << surface().points().size() << " only " << nPoints + << " are used. This might give problems in some routines." + << endl; + } + + // Random number generator. Bit dodgy since not exactly random ;-) + Random rndGen(65431); + + // Slightly extended bb. Slightly off-centred just so on symmetric + // geometry there are less face/edge aligned items. + bb = bb.extend(rndGen, 1e-4); + bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_; + + treePtr_.reset + ( + new indexedOctree<treeDataTriSurface> + ( + treeDataTriSurface(true, surface_, tolerance_), + bb, + maxTreeDepth_, // maxLevel + 10, // leafsize + 3.0 // duplicity + ) + ); + + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; + } + + return treePtr_(); +} + + // Determine inside/outside for samples Foam::boolList Foam::triSurfaceSearch::calcInside ( @@ -96,11 +237,7 @@ Foam::boolList Foam::triSurfaceSearch::calcInside { inside[sampleI] = false; } - else if - ( - tree().getVolumeType(sample) - == indexedOctree<treeDataTriSurface>::INSIDE - ) + else if (tree().getVolumeType(sample) == volumeType::INSIDE) { inside[sampleI] = true; } @@ -113,159 +250,167 @@ Foam::boolList Foam::triSurfaceSearch::calcInside } -Foam::labelList Foam::triSurfaceSearch::calcNearestTri +void Foam::triSurfaceSearch::findNearest ( const pointField& samples, - const vector& span + const scalarField& nearestDistSqr, + List<pointIndexHit>& info ) const { - labelList nearest(samples.size()); + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance(); - const scalar nearestDistSqr = 0.25*magSqr(span); + const indexedOctree<treeDataTriSurface>& octree = tree(); - pointIndexHit hitInfo; + info.setSize(samples.size()); - forAll(samples, sampleI) + forAll(samples, i) { - hitInfo = tree().findNearest(samples[sampleI], nearestDistSqr); - - if (hitInfo.hit()) - { - nearest[sampleI] = hitInfo.index(); - } - else - { - nearest[sampleI] = -1; - } + static_cast<pointIndexHit&>(info[i]) = octree.findNearest + ( + samples[i], + nearestDistSqr[i], + treeDataTriSurface::findNearestOp(octree) + ); } - return nearest; + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } -// Nearest point on surface -Foam::tmp<Foam::pointField> Foam::triSurfaceSearch::calcNearest +Foam::pointIndexHit Foam::triSurfaceSearch::nearest ( - const pointField& samples, + const point& pt, const vector& span -) const +) +const { const scalar nearestDistSqr = 0.25*magSqr(span); - tmp<pointField> tnearest(new pointField(samples.size())); - pointField& nearest = tnearest(); + return tree().findNearest(pt, nearestDistSqr); +} - pointIndexHit hitInfo; - forAll(samples, sampleI) - { - hitInfo = tree().findNearest(samples[sampleI], nearestDistSqr); +void Foam::triSurfaceSearch::findLine +( + const pointField& start, + const pointField& end, + List<pointIndexHit>& info +) const +{ + const indexedOctree<treeDataTriSurface>& octree = tree(); - if (hitInfo.hit()) - { - nearest[sampleI] = hitInfo.hitPoint(); - } - else - { - nearest[sampleI] = greatPoint; - } + info.setSize(start.size()); + + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance(); + + forAll(start, i) + { + static_cast<pointIndexHit&>(info[i]) = octree.findLine + ( + start[i], + end[i] + ); } - return tnearest; + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } -Foam::pointIndexHit Foam::triSurfaceSearch::nearest +void Foam::triSurfaceSearch::findLineAny ( - const point& pt, - const vector& span -) -const + const pointField& start, + const pointField& end, + List<pointIndexHit>& info +) const { - const scalar nearestDistSqr = 0.25*magSqr(span); + const indexedOctree<treeDataTriSurface>& octree = tree(); - return tree().findNearest(pt, nearestDistSqr); + info.setSize(start.size()); + + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance(); + + forAll(start, i) + { + static_cast<pointIndexHit&>(info[i]) = octree.findLineAny + ( + start[i], + end[i] + ); + } + + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } void Foam::triSurfaceSearch::findLineAll ( - const point& start, - const point& end, - List<pointIndexHit>& hits -) -const + const pointField& start, + const pointField& end, + List<List<pointIndexHit> >& info +) const { - // See if any intersection between pt and end - pointIndexHit inter = tree().findLine(start, end); + const indexedOctree<treeDataTriSurface>& octree = tree(); - if (inter.hit()) - { - hits.setSize(1); - hits[0] = inter; + info.setSize(start.size()); - const vector dirVec(end-start); - const scalar magSqrDirVec(magSqr(dirVec)); - const vector smallVec - ( - indexedOctree<treeDataTriSurface>::perturbTol()*dirVec - + vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL) - ); + scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol(); + indexedOctree<treeDataTriSurface>::perturbTol() = tolerance(); + // Work array + DynamicList<pointIndexHit, 1, 1> hits; - // Initial perturbation amount - vector perturbVec(smallVec); + DynamicList<label> shapeMask; - while (true) - { - // Start tracking from last hit. - point pt = hits.last().hitPoint() + perturbVec; + treeDataTriSurface::findAllIntersectOp allIntersectOp(octree, shapeMask); - if (((pt-start)&dirVec) > magSqrDirVec) - { - return; - } + forAll(start, pointI) + { + hits.clear(); + shapeMask.clear(); + while (true) + { // See if any intersection between pt and end - pointIndexHit inter = tree().findLine(pt, end); - - if (!inter.hit()) - { - return; - } + pointIndexHit inter = octree.findLine + ( + start[pointI], + end[pointI], + allIntersectOp + ); - // Check if already found this intersection - bool duplicateHit = false; - forAllReverse(hits, i) + if (inter.hit()) { - if (hits[i].index() == inter.index()) + vector lineVec = end[pointI] - start[pointI]; + lineVec /= mag(lineVec) + VSMALL; + + if + ( + checkUniqueHit + ( + inter, + hits, + lineVec + ) + ) { - duplicateHit = true; - break; + hits.append(inter); } - } - - if (duplicateHit) - { - // Hit same triangle again. Increase perturbVec and try again. - perturbVec *= 2; + shapeMask.append(inter.index()); } else { - // Proper hit - label sz = hits.size(); - hits.setSize(sz+1); - hits[sz] = inter; - // Restore perturbVec - perturbVec = smallVec; + break; } } + + info[pointI].transfer(hits); } - else - { - hits.clear(); - } + + indexedOctree<treeDataTriSurface>::perturbTol() = oldTol; } diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H index bbf7d1c6563c18af8002991c7a5aca34261beccc..bdca1bca83592031ea3d8cde238312ca337df8b8 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -48,11 +48,9 @@ namespace Foam // Forward declaration of classes class triSurface; -class treeDataTriSurface; -template<class Type> class indexedOctree; /*---------------------------------------------------------------------------*\ - Class triSurfaceSearch Declaration + Class triSurfaceSearch Declaration \*---------------------------------------------------------------------------*/ class triSurfaceSearch @@ -62,12 +60,26 @@ class triSurfaceSearch //- Reference to surface to work on const triSurface& surface_; + //- Optional tolerance to use in searches + scalar tolerance_; + + //- Optional max tree depth of octree + label maxTreeDepth_; + //- Octree for searches - autoPtr<indexedOctree<treeDataTriSurface> > treePtr_; + mutable autoPtr<indexedOctree<treeDataTriSurface> > treePtr_; // Private Member Functions + //- Check whether the current hit on the surface which lies on lineVec + // is unique. + bool checkUniqueHit + ( + const pointIndexHit& currHit, + const DynamicList<pointIndexHit, 1, 1>& hits, + const vector& lineVec + ) const; //- Disallow default bitwise copy construct triSurfaceSearch(const triSurfaceSearch&); @@ -75,51 +87,64 @@ class triSurfaceSearch //- Disallow default bitwise assignment void operator=(const triSurfaceSearch&); + public: - // Static data members + // Constructors - //- Point far away; used for illegal finds - static const point greatPoint; + //- Construct from surface. Holds reference to surface! + explicit triSurfaceSearch(const triSurface&); + //- Construct from surface and dictionary. + triSurfaceSearch(const triSurface&, const dictionary& dict); - // Constructors + //- Construct from components + triSurfaceSearch + ( + const triSurface& surface, + const scalar tolerance, + const label maxTreeDepth + ); - //- Construct from surface. Holds reference to surface! - triSurfaceSearch(const triSurface&); + //- Destructor + ~triSurfaceSearch(); + + //- Clear storage + void clearOut(); // Member Functions - const indexedOctree<treeDataTriSurface>& tree() const - { - return treePtr_(); - } + //- Demand driven construction of the octree + const indexedOctree<treeDataTriSurface>& tree() const; + //- Return reference to the surface. const triSurface& surface() const { return surface_; } + //- Return tolerance to use in searches + scalar tolerance() const + { + return tolerance_; + } + + //- Return max tree depth of octree + label maxTreeDepth() const + { + return maxTreeDepth_; + } + //- Calculate for each searchPoint inside/outside status. boolList calcInside(const pointField& searchPoints) const; - //- Calculate index of nearest triangle (or -1) for each sample. - // Looks only in box of size 2*span around sample. - labelList calcNearestTri - ( - const pointField& samples, - const vector& span - ) const; - - //- Calculate nearest points (to searchPoints) on surface. - // Looks only in box of size 2*span around sample. Returns greatPoint - // if not found. - tmp<pointField> calcNearest + void findNearest ( const pointField& samples, - const vector& span + const scalarField& nearestDistSqr, + List<pointIndexHit>& info ) const; //- Calculate nearest point on surface for single searchPoint. Returns @@ -129,14 +154,27 @@ public: // - index() : surface triangle label pointIndexHit nearest(const point&, const vector& span) const; + void findLine + ( + const pointField& start, + const pointField& end, + List<pointIndexHit>& info + ) const; + + void findLineAny + ( + const pointField& start, + const pointField& end, + List<pointIndexHit>& info + ) const; + //- Calculate all intersections from start to end void findLineAll ( - const point& start, - const point& end, - List<pointIndexHit>& + const pointField& start, + const pointField& end, + List<List<pointIndexHit> >& info ) const; - }; diff --git a/src/meshTools/twoDPointCorrector/twoDPointCorrector.H b/src/meshTools/twoDPointCorrector/twoDPointCorrector.H index d9e184347e6858ff7de85c82b3768e794f76e7b8..ed5e8dddf27a0cbf8a699e180f8b7df917ff7925 100644 --- a/src/meshTools/twoDPointCorrector/twoDPointCorrector.H +++ b/src/meshTools/twoDPointCorrector/twoDPointCorrector.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -31,7 +31,7 @@ Description and thus introduce a third dimension into a 2-D problem. The operation is performed by looping through all edges approximately - normal to the plane and enforcing their orthoginality onto the plane by + normal to the plane and enforcing their orthogonality onto the plane by adjusting points on their ends. SourceFiles diff --git a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C index f0b13b4afb450df10063ec14c173076e5cefb02a..2dab63202beda8e0088bde24cce5127885dc0aaa 100644 --- a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C +++ b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -37,6 +37,7 @@ License #include "geomDecomp.H" #include "vectorList.H" #include "PackedBoolList.H" +#include "PatchTools.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -2356,7 +2357,7 @@ void Foam::distributedTriSurfaceMesh::writeStats(Ostream& os) const { boundBox bb; label nPoints; - calcBounds(bb, nPoints); + PatchTools::calcBounds(static_cast<const triSurface&>(*this), bb, nPoints); reduce(bb.min(), minOp<point>()); reduce(bb.max(), maxOp<point>()); diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurface.C b/src/sampling/sampledSurface/distanceSurface/distanceSurface.C index 7d9c4eace454d7cd0bab0c351267530c03ab8cf5..2dafe3e98ad268312e11ca50d68c84a2669b83ec 100644 --- a/src/sampling/sampledSurface/distanceSurface/distanceSurface.C +++ b/src/sampling/sampledSurface/distanceSurface/distanceSurface.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -29,6 +29,7 @@ License #include "volPointInterpolation.H" #include "addToRunTimeSelectionTable.H" #include "fvMesh.H" +#include "volumeType.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -94,19 +95,19 @@ void Foam::distanceSurface::createGeometry() if (signed_) { - List<searchableSurface::volumeType> volType; + List<volumeType> volType; surfPtr_().getVolumeType(cc, volType); forAll(volType, i) { - searchableSurface::volumeType vT = volType[i]; + volumeType vT = volType[i]; - if (vT == searchableSurface::OUTSIDE) + if (vT == volumeType::OUTSIDE) { fld[i] = Foam::mag(cc[i] - nearest[i].hitPoint()); } - else if (vT == searchableSurface::INSIDE) + else if (vT == volumeType::INSIDE) { fld[i] = -Foam::mag(cc[i] - nearest[i].hitPoint()); } @@ -146,19 +147,19 @@ void Foam::distanceSurface::createGeometry() if (signed_) { - List<searchableSurface::volumeType> volType; + List<volumeType> volType; surfPtr_().getVolumeType(cc, volType); forAll(volType, i) { - searchableSurface::volumeType vT = volType[i]; + volumeType vT = volType[i]; - if (vT == searchableSurface::OUTSIDE) + if (vT == volumeType::OUTSIDE) { fld[i] = Foam::mag(cc[i] - nearest[i].hitPoint()); } - else if (vT == searchableSurface::INSIDE) + else if (vT == volumeType::INSIDE) { fld[i] = -Foam::mag(cc[i] - nearest[i].hitPoint()); } @@ -203,20 +204,20 @@ void Foam::distanceSurface::createGeometry() if (signed_) { - List<searchableSurface::volumeType> volType; + List<volumeType> volType; surfPtr_().getVolumeType(pts, volType); forAll(volType, i) { - searchableSurface::volumeType vT = volType[i]; + volumeType vT = volType[i]; - if (vT == searchableSurface::OUTSIDE) + if (vT == volumeType::OUTSIDE) { pointDistance_[i] = Foam::mag(pts[i] - nearest[i].hitPoint()); } - else if (vT == searchableSurface::INSIDE) + else if (vT == volumeType::INSIDE) { pointDistance_[i] = -Foam::mag(pts[i] - nearest[i].hitPoint());