/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2016-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . Class Foam::triSurface Description Triangulated surface description with patch information. SourceFiles triSurface.C triSurfaceAddressing.C triSurfaceIO.C triSurfaceStitch.C \*---------------------------------------------------------------------------*/ #ifndef Foam_triSurface_H #define Foam_triSurface_H #include "primitivePatch.H" #include "PatchTools.H" #include "labelledTri.H" #include "boolList.H" #include "bitSet.H" #include "HashSet.H" #include "geometricSurfacePatchList.H" #include "surfacePatchList.H" #include "triFaceList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // Forward Declarations class Time; class IOobject; class IFstream; class surfZone; class triSurface; template class MeshedSurface; Istream& operator>>(Istream&, triSurface&); Ostream& operator<<(Ostream&, const triSurface&); /*---------------------------------------------------------------------------*\ Class triSurface Declaration \*---------------------------------------------------------------------------*/ class triSurface : public PrimitivePatch<::Foam::List, pointField> { // Private Typedefs //- Internal mesh storage type typedef PrimitivePatch<::Foam::List, pointField> MeshReference; // Private Data //- Patch information // (face ordering nFaces/startFace only used during reading, writing) geometricSurfacePatchList patches_; // Demand Driven //- Edge-face addressing (sorted) mutable std::unique_ptr sortedEdgeFacesPtr_; //- Label of face that 'owns' edge //- i.e. e.vec() is righthanded walk along face mutable std::unique_ptr edgeOwnerPtr_; // Private Member Functions //- Calculate sorted edgeFaces void calcSortedEdgeFaces() const; //- Calculate owner void calcEdgeOwner() const; //- Sort faces according to region. // Returns patch list and sets faceMap to index of labelledTri // inside *this. surfacePatchList calcPatches(labelList& faceMap) const; //- Sets default values for patches void setDefaultPatches(); //- Function to stitch the triangles by removing duplicate points. // Returns true if any points merged bool stitchTriangles ( const scalar tol = SMALL, const bool verbose = false ); //- Read in OpenFOAM format bool readNative(Istream& is); //- Write in OpenFOAM format void writeNative(Ostream& os) const; //- Read in STL format bool readSTL(const fileName& filename, bool forceBinary=false); //- Generic read routine for given format type. // If the format type is "", uses the file extension. bool read ( const fileName& filename, const word& fileType, const bool check = true ); //- Write STL ASCII format. // Each region becomes a 'solid' 'endsolid' block. void writeSTLASCII(const fileName& filename, const bool sort) const; //- Write STL BINARY format void writeSTLBINARY(const fileName& filename) const; //- Write GTS (Gnu Tri Surface library) format. void writeGTS(const fileName& filename, const bool sort) const; // Static Private Functions //- Convert faces to labelledTri. All get same region. static List convertToTri ( const faceList& faces, const label defaultRegion = 0 ); //- Convert triFaces to labelledTri. All get same region. static List convertToTri ( const triFaceList& faces, const label defaultRegion = 0 ); //- Return a new surface using specified pointMap and faceMap // // \param[in] pointMap from subsetMeshMap // \param[in] faceMap from subsetMeshMap triSurface subsetMeshImpl ( const labelList& pointMap, const labelList& faceMap ) const; protected: // Protected Member Functions //- Non-const access to global points pointField& storedPoints() { return const_cast(MeshReference::points()); } //- Non-const access to the faces List& storedFaces() { return static_cast&>(*this); } public: // Public Typedefs //- Placeholder only, but do not remove - it is needed for GeoMesh typedef bool BoundaryMesh; //- The face type (same as the underlying PrimitivePatch) typedef labelledTri face_type; //- The point type (same as the underlying PrimitivePatch) typedef point point_type; //- Runtime type information ClassName("triSurface"); // Static //- Name of triSurface directory to use. static fileName triSurfInstance(const Time&); //- Known readable file-types, including via friends or proxies static wordHashSet readTypes(); //- Known writable file-types, including via friends or proxies static wordHashSet writeTypes(); //- Can we read this file format? static bool canReadType(const word& fileType, bool verbose=false); //- Can we write this file format? static bool canWriteType(const word& fileType, bool verbose=false); //- Can we read this file format? static bool canRead(const fileName& name, bool verbose=false); // IO helpers //- Return fileName. // If fileName is relative gets treated as local to IOobject. static fileName relativeFilePath ( const IOobject& io, const fileName& f, const bool isGlobal = true //!< resolve as a global file ); //- Return fileName to load IOobject from. // Fatal if the file does not exist static fileName checkFile ( const IOobject& io, const bool isGlobal = true //!< resolve as a global file ); //- Return fileName to load IOobject from. // Supports optional override of fileName with "file" entry // Fatal if the file does not exist static fileName checkFile ( const IOobject& io, const dictionary& dict, const bool isGlobal = true //!< resolve as a global file ); //- Use IOobject information to resolve file to load from, //- or empty if the file does not exist. static fileName findFile ( const IOobject& io, const bool isGlobal = true //!< resolve as a global file ); //- Use IOobject information to resolve file to load from, //- or empty if the file does not exist. // Supports optional override of fileName with "file" entry static fileName findFile ( const IOobject& io, const dictionary& dict, const bool isGlobal = true //!< resolve as a global file ); // Constructors //- Default construct triSurface(); //- Copy construct triSurface(const triSurface& surf); //- Move construct triSurface(triSurface&& surf); //- Construct from triangles, patches, points. triSurface ( const List& triangles, const geometricSurfacePatchList& patches, const pointField& pts ); //- Construct from triangles, patches, points. Reuse storage. triSurface ( List& triangles, const geometricSurfacePatchList& patches, pointField& pts, const bool reuse ); //- Construct from triangles, points. //- Set patch names to default. triSurface ( const List& triangles, const pointField& pts ); //- Construct from triangles, points. //- Set region to 0 and default patchName. triSurface ( const triFaceList& triangles, const pointField& pts ); //- Construct from file name (uses extension to determine type). // Optional (positive, non-zero) point scaling is possible. explicit triSurface ( const fileName& name, const scalar scaleFactor = -1 ); //- Construct from file name with given format type. // If the format type is "", uses the file extension. triSurface ( const fileName& name, const word& fileType, const scalar scaleFactor = -1 ); //- Construct from Istream explicit triSurface(Istream& is); //- Construct from objectRegistry by reading an ".ftr" file explicit triSurface(const Time& d); //- Read construct using IO to find the file location. // Dictionary may contain the following entries: // - \c file = alternative file name (default is dictionary name) // - \c fileType = file format (default is from file extension) // - \c scale (eg, 0.001: mm to m) // . triSurface ( const IOobject& io, const dictionary& dict, const bool isGlobal = true //!< resolve as a global file ); // Selectors //- Read construct from filename with given file type static autoPtr New ( const fileName& name, const word& fileType ); //- Read construct from filename (file type implicit from extension) static autoPtr New(const fileName& name); //- Destructor virtual ~triSurface(); // Member Functions void clearOut(); void clearTopology(); void clearPatchMeshAddr(); void swap(triSurface& surf); // Access const geometricSurfacePatchList& patches() const noexcept { return patches_; } geometricSurfacePatchList& patches() noexcept { return patches_; } //- Return const access to the faces const List& surfFaces() const noexcept { return static_cast&>(*this); } //- Return edge-face addressing sorted (for edges with more than // 2 faces) according to the angle around the edge. // Orientation is anticlockwise looking from // edge.vec(localPoints()) const labelListList& sortedEdgeFaces() const; //- If 2 face neighbours: label of face where ordering of edge // is consistent with righthand walk. // If 1 neighbour: label of only face. // If >2 neighbours: undetermined. const labelList& edgeOwner() const; //- Face area vectors (normals) const vectorField& Sf() const { return MeshReference::faceAreas(); } //- Face area magnitudes const scalarField& magSf() const { return MeshReference::magFaceAreas(); } //- Face centres const vectorField& Cf() const { return MeshReference::faceCentres(); } // Interoperability with other surface mesh classes //- Sort faces according to zoneIds // Returns a surfZoneList and sets faceMap to index within faces() // (i.e. map from original,unsorted to sorted) List sortedZones(labelList& faceMap) const; //- Create a list of faces from the triFaces void triFaceFaces(List& plainFaceList) const; // Edit //- Move points virtual void movePoints(const pointField& pts); //- Swap points. Similar to movePoints, but returns the old points virtual void swapPoints(pointField& pts); //- Scale points. A non-positive factor is ignored. virtual void scalePoints(const scalar scaleFactor); //- Check/remove duplicate/degenerate triangles void checkTriangles(const bool verbose); //- Check triply (or more) connected edges. void checkEdges(const bool verbose); //- Remove non-valid triangles void cleanup(const bool verbose); //- Remove unused points and renumber faces in local visit order // // \param[out] pointMap from new to old points (optional) void compactPoints ( labelList& pointMap = const_cast(labelList::null()) ); //- Fill faceZone with currentZone for every face reachable // from facei without crossing edge marked in borderEdge. // Note: faceZone has to be sized nFaces before calling this fun. void markZone ( const boolList& borderEdge, const label facei, const label currentZone, labelList& faceZone ) const; //- (size and) fills faceZone with zone of face. Zone is area // reachable by edge crossing without crossing borderEdge // (bool for every edge in surface). Returns number of zones. label markZones ( const boolList& borderEdge, labelList& faceZone ) const; //- Create mappings for a sub-surface // // \param[in] include the faces to select // \param[out] pointMap from new to old localPoints // \param[out] faceMap from new to old localFaces template void subsetMeshMap ( const BoolListType& include, labelList& pointMap, labelList& faceMap ) const { PatchTools::subsetMap(*this, include, pointMap, faceMap); } //- Return a new surface subsetted on the selected faces. // // \param[in] include the faces to select // \param[out] pointMap from new to old localPoints // \param[out] faceMap from new to old localFaces triSurface subsetMesh ( const UList& include, labelList& pointMap, labelList& faceMap ) const; //- Return a new surface subsetted on the selected faces. // // \param[in] include the faces to select // \param[out] pointMap from subsetMeshMap // \param[out] faceMap from subsetMeshMap triSurface subsetMesh ( const bitSet& include, labelList& pointMap, labelList& faceMap ) const; //- Return a new surface subsetted on the selected faces. // // \param[in] include the faces to select triSurface subsetMesh(const UList& include) const; //- Return a new surface subsetted on the selected faces. // // \param[in] include the faces to select triSurface subsetMesh(const bitSet& include) const; //- Return a new surface subsetted on the selected patch names // // \param[in] includeNames surface patch names to include // \param[in] excludeNames surface patch names to exclude // // \see Foam::stringListOps::findMatching for details about matching triSurface subsetMesh ( const wordRes& includeNames, const wordRes& excludeNames = wordRes() ) const; //- Swap the list of faces being addressed void swapFaces(List& faceLst); //- Alter contents by transferring (triangles, points) components. // Patch information is small and therefore just copied. void transfer(triSurface& surf); //- Alter contents by transferring (triangles, points) components. // Patch information is small and therefore just copied. void transfer(MeshedSurface& surf); // Write //- Write to Ostream in simple OpenFOAM format void write(Ostream& os) const; //- Generic write routine (uses extension to determine type). // The sort option may not have an effect. void write(const fileName&, const bool sortByRegion = false) const; //- Generic write routine for given format type. // If the format type is "", uses the file extension. // The sort option may not have an effect. void write ( const fileName& filename, const word& fileType, const bool sortByRegion = false ) const; //- Write to database void write(const Time& d) const; //- Write some statistics void writeStats(Ostream& os) const; // Member Operators //- Copy assignment void operator=(const triSurface& surf); //- Move assignment void operator=(triSurface&& surf); //- Move assignment void operator=(MeshedSurface&& surf); // IOstream Operators friend Istream& operator>>(Istream& is, triSurface& s); friend Ostream& operator<<(Ostream& os, const triSurface& s); }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* //