diff --git a/src/edgeMesh/Make/files b/src/edgeMesh/Make/files index 70c5178cbe..ed4cec5d95 100644 --- a/src/edgeMesh/Make/files +++ b/src/edgeMesh/Make/files @@ -1,13 +1,20 @@ -edgeMesh.C -edgeMeshIO.C -edgeMeshNew.C +em = . -edgeMeshFormats = edgeMeshFormats +$(em)/edgeMesh.C +$(em)/edgeMeshIO.C +$(em)/edgeMeshNew.C + + +edgeMeshFormats = $(em)/edgeMeshFormats $(edgeMeshFormats)/edgeMeshFormatsCore.C $(edgeMeshFormats)/edgeMesh/edgeMeshFormat.C $(edgeMeshFormats)/edgeMesh/edgeMeshFormatRunTime.C +$(edgeMeshFormats)/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormat.C +$(edgeMeshFormats)/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormatRunTime.C + + $(edgeMeshFormats)/nas/NASedgeFormat.C $(edgeMeshFormats)/nas/NASedgeFormatRunTime.C @@ -20,9 +27,22 @@ $(edgeMeshFormats)/starcd/STARCDedgeFormatRunTime.C $(edgeMeshFormats)/vtk/VTKedgeFormat.C $(edgeMeshFormats)/vtk/VTKedgeFormatRunTime.C -extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.C -featureEdgeMesh/featureEdgeMesh.C +$(em)/featureEdgeMesh/featureEdgeMesh.C + +eem = $(em)/extendedEdgeMesh + +$(eem)/extendedEdgeMesh.C +$(eem)/extendedEdgeMeshNew.C + +$(eem)/extendedEdgeMeshFormats/obj/OBJextendedEdgeFormat.C +$(eem)/extendedEdgeMeshFormats/obj/OBJextendedEdgeFormatRunTime.C +$(eem)/extendedEdgeMeshFormats/extendedEdgeMeshFormat/extendedEdgeMeshFormat.C +$(eem)/extendedEdgeMeshFormats/extendedEdgeMeshFormat/extendedEdgeMeshFormatRunTime.C + +efm = $(eem)/extendedFeatureEdgeMesh + +$(efm)/extendedFeatureEdgeMesh.C diff --git a/src/edgeMesh/Make/options b/src/edgeMesh/Make/options index 3c1b5258d3..61439e40e2 100644 --- a/src/edgeMesh/Make/options +++ b/src/edgeMesh/Make/options @@ -1,9 +1,11 @@ EXE_INC = \ -I$(LIB_SRC)/fileFormats/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ -I$(LIB_SRC)/triSurface/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude LIB_LIBS = \ -ltriSurface \ -lmeshTools \ - -lfileFormats + -lfileFormats \ + -lsurfMesh diff --git a/src/edgeMesh/edgeMesh.H b/src/edgeMesh/edgeMesh.H index c8abb55169..d3397a290b 100644 --- a/src/edgeMesh/edgeMesh.H +++ b/src/edgeMesh/edgeMesh.H @@ -27,6 +27,9 @@ Class Description Points connected by edges. + Can be read from fileName based on extension. Uses ::New factory method + to select the reader and transfer the result. + SourceFiles edgeMeshI.H edgeMesh.C @@ -253,7 +256,7 @@ public: // Write - void writeStats(Ostream&) const; + virtual void writeStats(Ostream&) const; //- Generic write routine. Chooses writer based on extension. virtual void write(const fileName& name) const diff --git a/src/edgeMesh/edgeMeshFormats/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormat.C b/src/edgeMesh/edgeMeshFormats/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormat.C new file mode 100644 index 0000000000..5f20b3016b --- /dev/null +++ b/src/edgeMesh/edgeMeshFormats/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormat.C @@ -0,0 +1,70 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "extendedFeatureEdgeMeshFormat.H" +#include "edgeMeshFormat.H" +#include "IFstream.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::fileFormats::extendedFeatureEdgeMeshFormat::extendedFeatureEdgeMeshFormat +( + const fileName& filename +) +{ + read(filename); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::fileFormats::extendedFeatureEdgeMeshFormat::read +( + const fileName& filename +) +{ + clear(); + + IFstream is(filename); + if (!is.good()) + { + FatalErrorIn + ( + "fileFormats::extendedFeatureEdgeMeshFormat::read(const fileName&)" + ) + << "Cannot read file " << filename + << exit(FatalError); + } + + return fileFormats::edgeMeshFormat::read + ( + is, + this->storedPoints(), + this->storedEdges() + ); +} + + +// ************************************************************************* // diff --git a/src/edgeMesh/edgeMeshFormats/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormat.H b/src/edgeMesh/edgeMeshFormats/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormat.H new file mode 100644 index 0000000000..cabc9beec0 --- /dev/null +++ b/src/edgeMesh/edgeMeshFormats/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormat.H @@ -0,0 +1,106 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::fileFormats::extendedFeatureEdgeMeshFormat + +Description + Provide a means of reading extendedFeatureEdgeMesh as featureEdgeMesh + +SourceFiles + extendedFeatureEdgeMeshFormat.C + +\*---------------------------------------------------------------------------*/ + +#ifndef extendedFeatureEdgeMeshFormat_H +#define extendedFeatureEdgeMeshFormat_H + +#include "edgeMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace fileFormats +{ + +/*---------------------------------------------------------------------------*\ + Class extendedFeatureEdgeMeshFormat Declaration +\*---------------------------------------------------------------------------*/ + +class extendedFeatureEdgeMeshFormat +: + public edgeMesh +{ + // Private Member Functions + + //- Disallow default bitwise copy construct + extendedFeatureEdgeMeshFormat(const extendedFeatureEdgeMeshFormat&); + + //- Disallow default bitwise assignment + void operator=(const extendedFeatureEdgeMeshFormat&); + + +public: + + // Constructors + + //- Construct from file name + extendedFeatureEdgeMeshFormat(const fileName&); + + + // Selectors + + //- Read file and return surface + static autoPtr New(const fileName& name) + { + return autoPtr + ( + new extendedFeatureEdgeMeshFormat(name) + ); + } + + + //- Destructor + virtual ~extendedFeatureEdgeMeshFormat() + {} + + + // Member Functions + + //- Read from file + virtual bool read(const fileName&); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace fileFormats +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/edgeMesh/edgeMeshFormats/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormatRunTime.C b/src/edgeMesh/edgeMeshFormats/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormatRunTime.C new file mode 100644 index 0000000000..958f99facb --- /dev/null +++ b/src/edgeMesh/edgeMeshFormats/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshFormatRunTime.C @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "extendedFeatureEdgeMeshFormat.H" + +#include "addToRunTimeSelectionTable.H" +#include "addToMemberFunctionSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace fileFormats +{ + +// read extendedEdgeMesh +addNamedToRunTimeSelectionTable +( + edgeMesh, + extendedFeatureEdgeMeshFormat, + fileExtension, + featureEdgeMesh +); + +} +} + +// ************************************************************************* // diff --git a/src/edgeMesh/edgeMeshIO.C b/src/edgeMesh/edgeMeshIO.C index 08e1398a36..3887f9d679 100644 --- a/src/edgeMesh/edgeMeshIO.C +++ b/src/edgeMesh/edgeMeshIO.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 @@ -122,9 +122,9 @@ void Foam::edgeMesh::write void Foam::edgeMesh::writeStats(Ostream& os) const { - os << "points : " << points().size() << nl; - os << "edges : " << edges().size() << nl; - os << "boundingBox : " << boundBox(this->points()) << endl; + os << indent << "points : " << points().size() << nl; + os << indent << "edges : " << edges().size() << nl; + os << indent << "boundingBox : " << boundBox(this->points()) << endl; } diff --git a/src/edgeMesh/edgeMeshNew.C b/src/edgeMesh/edgeMeshNew.C index da7091c73a..df52d7cf63 100644 --- a/src/edgeMesh/edgeMeshNew.C +++ b/src/edgeMesh/edgeMeshNew.C @@ -42,8 +42,9 @@ Foam::autoPtr Foam::edgeMesh::New ( "edgeMesh::New(const fileName&, const word&) : " "constructing edgeMesh" - ) << "Unknown file extension " << ext << nl << nl - << "Valid types are :" << nl + ) << "Unknown file extension " << ext + << " for file " << name << nl << nl + << "Valid extensions are :" << nl << fileExtensionConstructorTablePtr_->sortedToc() << exit(FatalError); } diff --git a/src/edgeMesh/extendedEdgeMesh/extendedEdgeMesh.C b/src/edgeMesh/extendedEdgeMesh/extendedEdgeMesh.C new file mode 100644 index 0000000000..999d2f0651 --- /dev/null +++ b/src/edgeMesh/extendedEdgeMesh/extendedEdgeMesh.C @@ -0,0 +1,1518 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "extendedEdgeMesh.H" +#include "surfaceFeatures.H" +#include "triSurface.H" +#include "Random.H" +#include "Time.H" +#include "OBJstream.H" +#include "DynamicField.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(extendedEdgeMesh, 0); + + template<> + const char* Foam::NamedEnum + < + Foam::extendedEdgeMesh::pointStatus, + 4 + >::names[] = + { + "convex", + "concave", + "mixed", + "nonFeature" + }; + + template<> + const char* Foam::NamedEnum + < + Foam::extendedEdgeMesh::edgeStatus, + 6 + >::names[] = + { + "external", + "internal", + "flat", + "open", + "multiple", + "none" + }; + + template<> + const char* Foam::NamedEnum + < + Foam::extendedEdgeMesh::sideVolumeType, + 4 + >::names[] = + { + "inside", + "outside", + "both", + "neither" + }; +} + +const Foam::NamedEnum + Foam::extendedEdgeMesh::pointStatusNames_; + +const Foam::NamedEnum + Foam::extendedEdgeMesh::edgeStatusNames_; + +const Foam::NamedEnum + Foam::extendedEdgeMesh::sideVolumeTypeNames_; + +Foam::scalar Foam::extendedEdgeMesh::cosNormalAngleTol_ = + Foam::cos(degToRad(0.1)); + + +Foam::label Foam::extendedEdgeMesh::convexStart_ = 0; + + +Foam::label Foam::extendedEdgeMesh::externalStart_ = 0; + + +Foam::label Foam::extendedEdgeMesh::nPointTypes = 4; + + +Foam::label Foam::extendedEdgeMesh::nEdgeTypes = 5; + + +// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // + +Foam::extendedEdgeMesh::pointStatus +Foam::extendedEdgeMesh::classifyFeaturePoint +( + label ptI +) const +{ + labelList ptEds(pointEdges()[ptI]); + + label nPtEds = ptEds.size(); + label nExternal = 0; + label nInternal = 0; + + if (nPtEds == 0) + { + // There are no edges attached to the point, this is a problem + return NONFEATURE; + } + + forAll(ptEds, i) + { + edgeStatus edStat = getEdgeStatus(ptEds[i]); + + if (edStat == EXTERNAL) + { + nExternal++; + } + else if (edStat == INTERNAL) + { + nInternal++; + } + } + + if (nExternal == nPtEds) + { + return CONVEX; + } + else if (nInternal == nPtEds) + { + return CONCAVE; + } + else + { + return MIXED; + } +} + + +Foam::extendedEdgeMesh::edgeStatus +Foam::extendedEdgeMesh::classifyEdge +( + const List& norms, + const labelList& edNorms, + const vector& fC0tofC1 +) +{ + label nEdNorms = edNorms.size(); + + if (nEdNorms == 1) + { + return OPEN; + } + else if (nEdNorms == 2) + { + const vector& n0(norms[edNorms[0]]); + const vector& n1(norms[edNorms[1]]); + + if ((n0 & n1) > cosNormalAngleTol_) + { + return FLAT; + } + else if ((fC0tofC1 & n0) > 0.0) + { + return INTERNAL; + } + else + { + return EXTERNAL; + } + } + else if (nEdNorms > 2) + { + return MULTIPLE; + } + else + { + // There is a problem - the edge has no normals + return NONE; + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::extendedEdgeMesh::extendedEdgeMesh() +: + edgeMesh(pointField(0), edgeList(0)), + concaveStart_(0), + mixedStart_(0), + nonFeatureStart_(0), + internalStart_(0), + flatStart_(0), + openStart_(0), + multipleStart_(0), + normals_(0), + normalVolumeTypes_(0), + edgeDirections_(0), + normalDirections_(0), + edgeNormals_(0), + featurePointNormals_(0), + featurePointEdges_(0), + regionEdges_(0), + pointTree_(), + edgeTree_(), + edgeTreesByType_() +{} + + +Foam::extendedEdgeMesh::extendedEdgeMesh +( + const extendedEdgeMesh& fem +) +: + edgeMesh(fem), + concaveStart_(fem.concaveStart()), + mixedStart_(fem.mixedStart()), + nonFeatureStart_(fem.nonFeatureStart()), + internalStart_(fem.internalStart()), + flatStart_(fem.flatStart()), + openStart_(fem.openStart()), + multipleStart_(fem.multipleStart()), + normals_(fem.normals()), + normalVolumeTypes_(fem.normalVolumeTypes()), + edgeDirections_(fem.edgeDirections()), + normalDirections_(fem.normalDirections()), + edgeNormals_(fem.edgeNormals()), + featurePointNormals_(fem.featurePointNormals()), + featurePointEdges_(fem.featurePointEdges()), + regionEdges_(fem.regionEdges()), + pointTree_(), + edgeTree_(), + edgeTreesByType_() +{} + + +Foam::extendedEdgeMesh::extendedEdgeMesh(Istream& is) +{ + is >> *this; +} + + +Foam::extendedEdgeMesh::extendedEdgeMesh +( + const Xfer& pointLst, + const Xfer& edgeLst +) +: + edgeMesh(pointLst, edgeLst), + concaveStart_(0), + mixedStart_(0), + nonFeatureStart_(0), + internalStart_(0), + flatStart_(0), + openStart_(0), + multipleStart_(0), + normals_(0), + normalVolumeTypes_(0), + edgeDirections_(0), + normalDirections_(0), + edgeNormals_(0), + featurePointNormals_(0), + featurePointEdges_(0), + regionEdges_(0), + pointTree_(), + edgeTree_(), + edgeTreesByType_() +{} + + +Foam::extendedEdgeMesh::extendedEdgeMesh +( + const surfaceFeatures& sFeat, + const boolList& surfBaffleRegions +) +: + edgeMesh(pointField(0), edgeList(0)), + concaveStart_(-1), + mixedStart_(-1), + nonFeatureStart_(-1), + internalStart_(-1), + flatStart_(-1), + openStart_(-1), + multipleStart_(-1), + normals_(0), + normalVolumeTypes_(0), + edgeDirections_(0), + normalDirections_(0), + edgeNormals_(0), + featurePointNormals_(0), + featurePointEdges_(0), + regionEdges_(0), + pointTree_(), + edgeTree_(), + edgeTreesByType_() +{ + // Extract and reorder the data from surfaceFeatures + const triSurface& surf = sFeat.surface(); + const labelList& featureEdges = sFeat.featureEdges(); + const labelList& featurePoints = sFeat.featurePoints(); + + // Get a labelList of all the featureEdges that are region edges + const labelList regionFeatureEdges(identity(sFeat.nRegionEdges())); + + sortPointsAndEdges + ( + surf, + featureEdges, + regionFeatureEdges, + featurePoints + ); + + const labelListList& edgeFaces = surf.edgeFaces(); + + normalVolumeTypes_.setSize(normals_.size()); + + // Noting when the normal of a face has been used so not to duplicate + labelList faceMap(surf.size(), -1); + + label nAdded = 0; + + forAll(featureEdges, i) + { + label sFEI = featureEdges[i]; + + // Pick up the faces adjacent to the feature edge + const labelList& eFaces = edgeFaces[sFEI]; + + forAll(eFaces, j) + { + label eFI = eFaces[j]; + + // Check to see if the points have been already used + if (faceMap[eFI] == -1) + { + normalVolumeTypes_[nAdded++] = + ( + surfBaffleRegions[surf[eFI].region()] + ? BOTH + : INSIDE + ); + + faceMap[eFI] = nAdded - 1; + } + } + } +} + + +Foam::extendedEdgeMesh::extendedEdgeMesh +( + const PrimitivePatch& surf, + const labelList& featureEdges, + const labelList& regionFeatureEdges, + const labelList& featurePoints +) +: + edgeMesh(pointField(0), edgeList(0)), + concaveStart_(-1), + mixedStart_(-1), + nonFeatureStart_(-1), + internalStart_(-1), + flatStart_(-1), + openStart_(-1), + multipleStart_(-1), + normals_(0), + normalVolumeTypes_(0), + edgeDirections_(0), + normalDirections_(0), + edgeNormals_(0), + featurePointNormals_(0), + featurePointEdges_(0), + regionEdges_(0), + pointTree_(), + edgeTree_(), + edgeTreesByType_() +{ + sortPointsAndEdges + ( + surf, + featureEdges, + regionFeatureEdges, + featurePoints + ); +} + + +Foam::extendedEdgeMesh::extendedEdgeMesh +( + const pointField& pts, + const edgeList& eds, + label concaveStart, + label mixedStart, + label nonFeatureStart, + label internalStart, + label flatStart, + label openStart, + label multipleStart, + const vectorField& normals, + const List& normalVolumeTypes, + const vectorField& edgeDirections, + const labelListList& normalDirections, + const labelListList& edgeNormals, + const labelListList& featurePointNormals, + const labelListList& featurePointEdges, + const labelList& regionEdges +) +: + edgeMesh(pts, eds), + concaveStart_(concaveStart), + mixedStart_(mixedStart), + nonFeatureStart_(nonFeatureStart), + internalStart_(internalStart), + flatStart_(flatStart), + openStart_(openStart), + multipleStart_(multipleStart), + normals_(normals), + normalVolumeTypes_(normalVolumeTypes), + edgeDirections_(edgeDirections), + normalDirections_(normalDirections), + edgeNormals_(edgeNormals), + featurePointNormals_(featurePointNormals), + featurePointEdges_(featurePointEdges), + regionEdges_(regionEdges), + pointTree_(), + edgeTree_(), + edgeTreesByType_() +{} + + +Foam::extendedEdgeMesh::extendedEdgeMesh +( + const fileName& name, + const word& ext +) +: + edgeMesh(pointField(0), edgeList(0)), + concaveStart_(0), + mixedStart_(0), + nonFeatureStart_(0), + internalStart_(0), + flatStart_(0), + openStart_(0), + multipleStart_(0), + normals_(0), + normalVolumeTypes_(0), + edgeDirections_(0), + normalDirections_(0), + edgeNormals_(0), + featurePointNormals_(0), + featurePointEdges_(0), + regionEdges_(0), + pointTree_(), + edgeTree_(), + edgeTreesByType_() +{ + read(name, ext); +} + + +Foam::extendedEdgeMesh::extendedEdgeMesh(const fileName& name) +: + edgeMesh(pointField(0), edgeList(0)), + concaveStart_(0), + mixedStart_(0), + nonFeatureStart_(0), + internalStart_(0), + flatStart_(0), + openStart_(0), + multipleStart_(0), + normals_(0), + normalVolumeTypes_(0), + edgeDirections_(0), + normalDirections_(0), + edgeNormals_(0), + featurePointNormals_(0), + featurePointEdges_(0), + regionEdges_(0), + pointTree_(), + edgeTree_(), + edgeTreesByType_() +{ + read(name); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::extendedEdgeMesh::~extendedEdgeMesh() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +bool Foam::extendedEdgeMesh::read(const fileName& name) +{ + word ext = name.ext(); + if (ext == "gz") + { + fileName unzipName = name.lessExt(); + return read(unzipName, unzipName.ext()); + } + else + { + return read(name, ext); + } +} + + +// Read from file in given format +bool Foam::extendedEdgeMesh::read +( + const fileName& name, + const word& ext +) +{ + // read via selector mechanism + transfer(New(name, ext)()); + return true; +} + + +void Foam::extendedEdgeMesh::nearestFeaturePoint +( + const point& sample, + scalar searchDistSqr, + pointIndexHit& info +) const +{ + info = pointTree().findNearest + ( + sample, + searchDistSqr + ); +} + + +void Foam::extendedEdgeMesh::nearestFeatureEdge +( + const point& sample, + scalar searchDistSqr, + pointIndexHit& info +) const +{ + info = edgeTree().findNearest + ( + sample, + searchDistSqr + ); +} + + +void Foam::extendedEdgeMesh::nearestFeatureEdge +( + const pointField& samples, + const scalarField& searchDistSqr, + List& info +) const +{ + info.setSize(samples.size()); + + forAll(samples, i) + { + nearestFeatureEdge + ( + samples[i], + searchDistSqr[i], + info[i] + ); + } +} + + +void Foam::extendedEdgeMesh::nearestFeatureEdgeByType +( + const point& sample, + const scalarField& searchDistSqr, + List& info +) const +{ + const PtrList >& edgeTrees = edgeTreesByType(); + + info.setSize(edgeTrees.size()); + + labelList sliceStarts(edgeTrees.size()); + + sliceStarts[0] = externalStart_; + sliceStarts[1] = internalStart_; + sliceStarts[2] = flatStart_; + sliceStarts[3] = openStart_; + sliceStarts[4] = multipleStart_; + + forAll(edgeTrees, i) + { + info[i] = edgeTrees[i].findNearest + ( + sample, + searchDistSqr[i] + ); + + // The index returned by the indexedOctree is local to the slice of + // edges it was supplied with, return the index to the value in the + // complete edge list + + info[i].setIndex(info[i].index() + sliceStarts[i]); + } +} + + +void Foam::extendedEdgeMesh::allNearestFeaturePoints +( + const point& sample, + scalar searchRadiusSqr, + List& info +) const +{ + // Pick up all the feature points that intersect the search sphere + labelList elems = pointTree().findSphere + ( + sample, + searchRadiusSqr + ); + + DynamicList dynPointHit(elems.size()); + + forAll(elems, elemI) + { + label index = elems[elemI]; + label ptI = pointTree().shapes().pointLabels()[index]; + const point& pt = points()[ptI]; + + pointIndexHit nearHit(true, pt, index); + + dynPointHit.append(nearHit); + } + + info.transfer(dynPointHit); +} + + +void Foam::extendedEdgeMesh::allNearestFeatureEdges +( + const point& sample, + const scalar searchRadiusSqr, + List& info +) const +{ + const PtrList >& edgeTrees = edgeTreesByType(); + + info.setSize(edgeTrees.size()); + + labelList sliceStarts(edgeTrees.size()); + + sliceStarts[0] = externalStart_; + sliceStarts[1] = internalStart_; + sliceStarts[2] = flatStart_; + sliceStarts[3] = openStart_; + sliceStarts[4] = multipleStart_; + + DynamicList dynEdgeHit(edgeTrees.size()*3); + + // Loop over all the feature edge types + forAll(edgeTrees, i) + { + // Pick up all the edges that intersect the search sphere + labelList elems = edgeTrees[i].findSphere + ( + sample, + searchRadiusSqr + ); + + forAll(elems, elemI) + { + label index = elems[elemI]; + label edgeI = edgeTrees[i].shapes().edgeLabels()[index]; + const edge& e = edges()[edgeI]; + + pointHit hitPoint = e.line(points()).nearestDist(sample); + + label hitIndex = index + sliceStarts[i]; + + pointIndexHit nearHit + ( + hitPoint.hit(), + hitPoint.rawPoint(), + hitIndex + ); + + dynEdgeHit.append(nearHit); + } + } + + info.transfer(dynEdgeHit); +} + + +const Foam::indexedOctree& +Foam::extendedEdgeMesh::pointTree() const +{ + if (pointTree_.empty()) + { + Random rndGen(17301893); + + // Slightly extended bb. Slightly off-centred just so on symmetric + // geometry there are less face/edge aligned items. + treeBoundBox bb + ( + treeBoundBox(points()).extend(rndGen, 1e-4) + ); + + bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + const labelList featurePointLabels = identity(nonFeatureStart_); + + pointTree_.reset + ( + new indexedOctree + ( + treeDataPoint + ( + points(), + featurePointLabels + ), + bb, // bb + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity + ) + ); + } + + return pointTree_(); +} + + +const Foam::indexedOctree& +Foam::extendedEdgeMesh::edgeTree() const +{ + if (edgeTree_.empty()) + { + Random rndGen(17301893); + + // Slightly extended bb. Slightly off-centred just so on symmetric + // geometry there are less face/edge aligned items. + treeBoundBox bb + ( + treeBoundBox(points()).extend(rndGen, 1e-4) + ); + + bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + labelList allEdges(identity(edges().size())); + + edgeTree_.reset + ( + new indexedOctree + ( + treeDataEdge + ( + false, // cachebb + edges(), // edges + points(), // points + allEdges // selected edges + ), + bb, // bb + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity + ) + ); + } + + return edgeTree_(); +} + + +const Foam::PtrList >& +Foam::extendedEdgeMesh::edgeTreesByType() const +{ + if (edgeTreesByType_.size() == 0) + { + edgeTreesByType_.setSize(nEdgeTypes); + + Random rndGen(872141); + + // Slightly extended bb. Slightly off-centred just so on symmetric + // geometry there are less face/edge aligned items. + treeBoundBox bb + ( + treeBoundBox(points()).extend(rndGen, 1e-4) + ); + + bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); + + labelListList sliceEdges(nEdgeTypes); + + // External edges + sliceEdges[0] = + identity(internalStart_ - externalStart_) + externalStart_; + + // Internal edges + sliceEdges[1] = identity(flatStart_ - internalStart_) + internalStart_; + + // Flat edges + sliceEdges[2] = identity(openStart_ - flatStart_) + flatStart_; + + // Open edges + sliceEdges[3] = identity(multipleStart_ - openStart_) + openStart_; + + // Multiple edges + sliceEdges[4] = + identity(edges().size() - multipleStart_) + multipleStart_; + + forAll(edgeTreesByType_, i) + { + edgeTreesByType_.set + ( + i, + new indexedOctree + ( + treeDataEdge + ( + false, // cachebb + edges(), // edges + points(), // points + sliceEdges[i] // selected edges + ), + bb, // bb + 8, // maxLevel + 10, // leafsize + 3.0 // duplicity + ) + ); + } + } + + return edgeTreesByType_; +} + + +void Foam::extendedEdgeMesh::transfer(extendedEdgeMesh& mesh) +{ + edgeMesh::transfer(mesh); + + concaveStart_ = mesh.concaveStart_; + mixedStart_ = mesh.mixedStart_; + nonFeatureStart_ = mesh.nonFeatureStart_; + internalStart_ = mesh.internalStart_; + flatStart_ = mesh.flatStart_; + openStart_ = mesh.openStart_; + multipleStart_ = mesh.multipleStart_; + normals_.transfer(mesh.normals_); + normalVolumeTypes_.transfer(mesh.normalVolumeTypes_); + edgeDirections_.transfer(mesh.edgeDirections_); + normalDirections_.transfer(mesh.normalDirections_); + edgeNormals_.transfer(mesh.edgeNormals_); + featurePointNormals_.transfer(mesh.featurePointNormals_); + featurePointEdges_.transfer(mesh.featurePointEdges_); + regionEdges_.transfer(mesh.regionEdges_); + pointTree_ = mesh.pointTree_; + edgeTree_ = mesh.edgeTree_; + edgeTreesByType_.transfer(mesh.edgeTreesByType_); +} + + +Foam::Xfer Foam::extendedEdgeMesh::xfer() +{ + return xferMoveTo(*this); +} + + +void Foam::extendedEdgeMesh::clear() +{ + edgeMesh::clear(); + concaveStart_ = 0; + mixedStart_ = 0; + nonFeatureStart_ = 0; + internalStart_ = 0; + flatStart_ = 0; + openStart_ = 0; + multipleStart_ = 0; + normals_.clear(); + normalVolumeTypes_.clear(); + edgeDirections_.clear(); + normalDirections_.clear(); + edgeNormals_.clear(); + featurePointNormals_.clear(); + featurePointEdges_.clear(); + regionEdges_.clear(); + pointTree_.clear(); + edgeTree_.clear(); + edgeTreesByType_.clear(); +} + + +void Foam::extendedEdgeMesh::add(const extendedEdgeMesh& fem) +{ + // Points + // ~~~~~~ + + // From current points into combined points + labelList reversePointMap(points().size()); + labelList reverseFemPointMap(fem.points().size()); + + label newPointI = 0; + for (label i = 0; i < concaveStart(); i++) + { + reversePointMap[i] = newPointI++; + } + for (label i = 0; i < fem.concaveStart(); i++) + { + reverseFemPointMap[i] = newPointI++; + } + + // Concave + label newConcaveStart = newPointI; + for (label i = concaveStart(); i < mixedStart(); i++) + { + reversePointMap[i] = newPointI++; + } + for (label i = fem.concaveStart(); i < fem.mixedStart(); i++) + { + reverseFemPointMap[i] = newPointI++; + } + + // Mixed + label newMixedStart = newPointI; + for (label i = mixedStart(); i < nonFeatureStart(); i++) + { + reversePointMap[i] = newPointI++; + } + for (label i = fem.mixedStart(); i < fem.nonFeatureStart(); i++) + { + reverseFemPointMap[i] = newPointI++; + } + + // Non-feature + label newNonFeatureStart = newPointI; + for (label i = nonFeatureStart(); i < points().size(); i++) + { + reversePointMap[i] = newPointI++; + } + for (label i = fem.nonFeatureStart(); i < fem.points().size(); i++) + { + reverseFemPointMap[i] = newPointI++; + } + + pointField newPoints(newPointI); + newPoints.rmap(points(), reversePointMap); + newPoints.rmap(fem.points(), reverseFemPointMap); + + + // Edges + // ~~~~~ + + // From current edges into combined edges + labelList reverseEdgeMap(edges().size()); + labelList reverseFemEdgeMap(fem.edges().size()); + + // External + label newEdgeI = 0; + for (label i = 0; i < internalStart(); i++) + { + reverseEdgeMap[i] = newEdgeI++; + } + for (label i = 0; i < fem.internalStart(); i++) + { + reverseFemEdgeMap[i] = newEdgeI++; + } + + // Internal + label newInternalStart = newEdgeI; + for (label i = internalStart(); i < flatStart(); i++) + { + reverseEdgeMap[i] = newEdgeI++; + } + for (label i = fem.internalStart(); i < fem.flatStart(); i++) + { + reverseFemEdgeMap[i] = newEdgeI++; + } + + // Flat + label newFlatStart = newEdgeI; + for (label i = flatStart(); i < openStart(); i++) + { + reverseEdgeMap[i] = newEdgeI++; + } + for (label i = fem.flatStart(); i < fem.openStart(); i++) + { + reverseFemEdgeMap[i] = newEdgeI++; + } + + // Open + label newOpenStart = newEdgeI; + for (label i = openStart(); i < multipleStart(); i++) + { + reverseEdgeMap[i] = newEdgeI++; + } + for (label i = fem.openStart(); i < fem.multipleStart(); i++) + { + reverseFemEdgeMap[i] = newEdgeI++; + } + + // Multiple + label newMultipleStart = newEdgeI; + for (label i = multipleStart(); i < edges().size(); i++) + { + reverseEdgeMap[i] = newEdgeI++; + } + for (label i = fem.multipleStart(); i < fem.edges().size(); i++) + { + reverseFemEdgeMap[i] = newEdgeI++; + } + + edgeList newEdges(newEdgeI); + forAll(edges(), i) + { + const edge& e = edges()[i]; + newEdges[reverseEdgeMap[i]] = edge + ( + reversePointMap[e[0]], + reversePointMap[e[1]] + ); + } + forAll(fem.edges(), i) + { + const edge& e = fem.edges()[i]; + newEdges[reverseFemEdgeMap[i]] = edge + ( + reverseFemPointMap[e[0]], + reverseFemPointMap[e[1]] + ); + } + + pointField newEdgeDirections(newEdgeI); + newEdgeDirections.rmap(edgeDirections(), reverseEdgeMap); + newEdgeDirections.rmap(fem.edgeDirections(), reverseFemEdgeMap); + + + + + // Normals + // ~~~~~~~ + + // Combine normals + DynamicField newNormals(normals().size()+fem.normals().size()); + newNormals.append(normals()); + newNormals.append(fem.normals()); + + + // Combine and re-index into newNormals + labelListList newEdgeNormals(edgeNormals().size()+fem.edgeNormals().size()); + UIndirectList(newEdgeNormals, reverseEdgeMap) = + edgeNormals(); + UIndirectList(newEdgeNormals, reverseFemEdgeMap) = + fem.edgeNormals(); + forAll(reverseFemEdgeMap, i) + { + label mapI = reverseFemEdgeMap[i]; + labelList& en = newEdgeNormals[mapI]; + forAll(en, j) + { + en[j] += normals().size(); + } + } + + + // Combine and re-index into newFeaturePointNormals + labelListList newFeaturePointNormals + ( + featurePointNormals().size() + + fem.featurePointNormals().size() + ); + + // Note: featurePointNormals only go up to nonFeatureStart + UIndirectList + ( + newFeaturePointNormals, + SubList