FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

triSurfaceTools.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Class
00025     Foam::triSurfaceTools
00026 
00027 Description
00028     A collection of tools for triSurfaceMesh
00029 
00030 SourceFiles
00031     triSurfaceTools.C
00032 
00033 \*---------------------------------------------------------------------------*/
00034 
00035 #ifndef triSurfaceTools_H
00036 #define triSurfaceTools_H
00037 
00038 #include <OpenFOAM/boolList.H>
00039 #include <OpenFOAM/pointField.H>
00040 #include <OpenFOAM/DynamicList.H>
00041 #include <OpenFOAM/HashSet.H>
00042 #include <OpenFOAM/FixedList.H>
00043 #include <OpenFOAM/vector2D.H>
00044 #include <OpenFOAM/triPointRef.H>
00045 #include <meshTools/surfaceLocation.H>
00046 
00047 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00048 
00049 namespace Foam
00050 {
00051 
00052 // Forward declaration of classes
00053 class triSurface;
00054 class edge;
00055 class labelledTri;
00056 class polyBoundaryMesh;
00057 class plane;
00058 
00059 /*---------------------------------------------------------------------------*\
00060                            Class triSurfaceTools Declaration
00061 \*---------------------------------------------------------------------------*/
00062 
00063 class triSurfaceTools
00064 {
00065     // Private Member Functions
00066 
00067         // Refinement
00068 
00069             enum refineType
00070             {
00071                 NONE,
00072                 RED,
00073                 GREEN
00074             };
00075             static void calcRefineStatus
00076             (
00077                 const triSurface& surf,
00078                 const label faceI,
00079                 List<refineType>& refine
00080             );
00081             static void greenRefine
00082             (
00083                 const triSurface& surf,
00084                 const label faceI,
00085                 const label edgeI,
00086                 const label newPointI,
00087                 DynamicList<labelledTri>& newFaces
00088             );
00089             static triSurface doRefine
00090             (
00091                 const triSurface& surf,
00092                 const List<refineType>& refineStatus
00093             );
00094 
00095 
00096         // Coarsening
00097 
00098             static scalar faceCosAngle
00099             (
00100                 const point& pStart,
00101                 const point& pEnd,
00102                 const point& pLeft,
00103                 const point& pRight
00104             );
00105 
00106             static void protectNeighbours
00107             (
00108                 const triSurface& surf,
00109                 const label vertI,
00110                 labelList& faceStatus
00111             );
00112 
00113             //- faces to collapse because of edge collapse
00114             static labelHashSet getCollapsedFaces
00115             (
00116                 const triSurface& surf,
00117                 label edgeI
00118             );
00119 
00120             // Return value of faceUsed for faces using vertI (local numbering).
00121             // Used internally.
00122             static label vertexUsesFace
00123             (
00124                 const triSurface& surf,
00125                 const labelHashSet& faceUsed,
00126                 const label vertI
00127             );
00128 
00129             // Get new connections between faces (because of edge collapse)
00130             // in form of tables:
00131             //  - given edge get other edge
00132             //  - given edge get other face
00133             // A face using point v1 on edge will get connected to a face using
00134             //  point v2 if they share a common vertex
00135             //  (but not a common edge since then the triangles collapse to
00136             //  nothing)
00137             static void getMergedEdges
00138             (
00139                 const triSurface& surf,
00140                 const label edgeI,
00141                 const labelHashSet& collapsedFaces,
00142                 HashTable<label, label, Hash<label> >& edgeToEdge,
00143                 HashTable<label, label, Hash<label> >& edgeToFace
00144             );
00145 
00146             //- Calculates (cos of) angle across edgeI of faceI,
00147             //  taking into account updated addressing (resulting from edge
00148             //  collapse)
00149             static scalar edgeCosAngle
00150             (
00151                 const triSurface& surf,
00152                 const label v1,
00153                 const point& pt,
00154                 const labelHashSet& collapsedFaces,
00155                 const HashTable<label, label, Hash<label> >& edgeToEdge,
00156                 const HashTable<label, label, Hash<label> >& edgeToFace,
00157                 const label faceI,
00158                 const label edgeI
00159             );
00160 
00161             //- Calculate minimum (cos of) edge angle using addressing from
00163             //  edge to v1 at pt. Returns 1 if v1 is on edge without neighbours
00164             //  (and hence no edge angle can be defined)
00165             static scalar collapseMinCosAngle
00166             (
00167                 const triSurface& surf,
00168                 const label v1,
00169                 const point& pt,
00170                 const labelHashSet& collapsedFaces,
00171                 const HashTable<label, label, Hash<label> >& edgeToEdge,
00172                 const HashTable<label, label, Hash<label> >& edgeToFace
00173             );
00174 
00175             //- Like collapseMinCosAngle but return true for value < minCos
00176             bool collapseCreatesFold
00177             (
00178                 const triSurface& surf,
00179                 const label v1,
00180                 const point& pt,
00181                 const labelHashSet& collapsedFaces,
00182                 const HashTable<label, label, Hash<label> >& edgeToEdge,
00183                 const HashTable<label, label, Hash<label> >& edgeToFace,
00184                 const scalar minCos
00185             );
00186 
00189             //static bool collapseCreatesDuplicates
00190             //(
00191             //    const triSurface& surf,
00192             //    const label edgeI,
00193             //    const HashTable<bool, label, Hash<label> >& collapsedFaces
00194             //);
00195 
00196         // Tracking
00197 
00198             //- Finds the triangle edge/point cut by the plane between
00199             //  a point inside/on edge of a triangle and a point outside.
00200             //  Returns
00201             //  - location on edge/point and hit()
00202             //  - or miss() if no intersection found
00203             static surfaceLocation cutEdge
00204             (
00205                 const triSurface& s,
00206                 const label triI,
00207                 const label excludeEdgeI,
00208                 const label excludePointI,
00209                 const point& triPoint,
00210                 const plane& cutPlane,
00211                 const point& toPoint
00212             );
00213 
00214             //- Checks if current is on the same triangle as the endpoint
00215             //  and shifts it there. If so updates current and sets a hit.
00216             static void snapToEnd
00217             (
00218                 const triSurface& s,
00219                 const surfaceLocation& endInfo,
00220                 surfaceLocation& current
00221             );
00222 
00223             //- Visits faces eFaces around start. Does not visit triangle
00224             //  start.triangle() nor edge excludeEdgeI.
00225             //  Returns edge, triangle (if more than one choice) which gets
00226             //  us nearer endpoint.
00227             //  Returns
00228             //  - hit() if triangle contains endpoint
00229             //  - triangle()=-1 if no triangle found
00230             //  - nearest triangle/edge otherwise
00231             static surfaceLocation visitFaces
00232             (
00233                 const triSurface& s,
00234                 const labelList& eFaces,
00235                 const surfaceLocation& start,
00236                 const label excludeEdgeI,
00237                 const label excludePointI,
00238                 const surfaceLocation& end,
00239                 const plane& cutPlane
00240             );
00241 
00242 
00243 public:
00244 
00245     // OBJ writing
00246 
00247         //- Write pointField to OBJ format file
00248         static void writeOBJ
00249         (
00250             const fileName& fName,
00251             const pointField& pts
00252         );
00253 
00254         //- Write vertex subset to OBJ format file
00255         static void writeOBJ
00256         (
00257             const triSurface& surf,
00258             const fileName& fName,
00259             const boolList& markedVerts
00260         );
00261 
00262 
00263     // Additional addressing
00264 
00265         //- Get all triangles using edge endpoint
00266         static void getVertexTriangles
00267         (
00268             const triSurface& surf,
00269             const label edgeI,
00270             labelList& edgeTris
00271         );
00272 
00273         //- Get all vertices (local numbering) connected to vertices of edge
00274         static labelList getVertexVertices
00275         (
00276             const triSurface& surf,
00277             const edge& e
00278         );
00279 
00281         //static void orderVertices
00282         //(
00283         //    const labelledTri& f,
00284         //    const label v1,
00285         //    const label v2,
00286         //    label& vA,
00287         //    label& vB
00288         //);
00289 
00290         //- Get face connected to edge not faceI
00291         static label otherFace
00292         (
00293             const triSurface& surf,
00294             const label faceI,
00295             const label edgeI
00296         );
00297 
00298         //- Get the two edges on faceI counterclockwise after edgeI
00299         static void otherEdges
00300         (
00301             const triSurface& surf,
00302             const label faceI,
00303             const label edgeI,
00304             label& e1,
00305             label& e2
00306         );
00307 
00308         //- Get the two vertices (local numbering) on faceI counterclockwise
00309         //  vertI
00310         static void otherVertices
00311         (
00312             const triSurface& surf,
00313             const label faceI,
00314             const label vertI,
00315             label& vert1I,
00316             label& vert2I
00317         );
00318 
00319         //- Get edge opposite vertex (local numbering)
00320         static label oppositeEdge
00321         (
00322             const triSurface& surf,
00323             const label faceI,
00324             const label vertI
00325         );
00326 
00327         //- Get vertex (local numbering) opposite edge
00328         static label oppositeVertex
00329         (
00330             const triSurface& surf,
00331             const label faceI,
00332             const label edgeI
00333         );
00334 
00335         //- Returns edge label connecting v1, v2 (local numbering)
00336         static label getEdge
00337         (
00338             const triSurface& surf,
00339             const label vert1I,
00340             const label vert2I
00341         );
00342 
00343         //- Return index of triangle (or -1) using all three edges
00344         static label getTriangle
00345         (
00346             const triSurface& surf,
00347             const label e0I,
00348             const label e1I,
00349             const label e2I
00350         );
00351 
00352     // Coarsening
00353 
00354         //- Create new triSurface by collapsing edges to edge mids.
00355         static triSurface collapseEdges
00356         (
00357             const triSurface& surf,
00358             const labelList& collapsableEdges
00359         );
00360 
00361 
00362         //- Face collapse status.
00363         //  anyEdge: any edge can be collapsed
00364         //  noEdge: no edge can be collapsed
00365         //  collapsed: already collapsed
00366         //  >0: edge label that can be collapsed
00367         static const label ANYEDGE;
00368         static const label NOEDGE;
00369         static const label COLLAPSED;
00370 
00371         //- Create new triSurface by collapsing edges to specified
00372         //  positions. faceStatus allows
00373         //  explicit control over which faces need to be protected (see above).
00374         //  faceStatus gets updated to protect collapsing already collapsed
00375         //  faces.
00376         static triSurface collapseEdges
00377         (
00378             const triSurface& surf,
00379             const labelList& collapsableEdges,
00380             const pointField& edgeMids,
00381             labelList& faceStatus
00382         );
00383 
00384 
00385     // Refinement
00386 
00387         //- Refine edges by splitting to opposite vertex
00388         static triSurface greenRefine
00389         (
00390             const triSurface& surf,
00391             const labelList& refineEdges
00392         );
00393 
00394         //- Refine face by splitting all edges. Neighbouring face is
00395         //  greenRefine'd.
00396         static triSurface redGreenRefine
00397         (
00398             const triSurface& surf,
00399             const labelList& refineFaces
00400         );
00401 
00402 
00403     // Geometric
00404 
00405         //- Returns element in edgeIndices with minimum length
00406         static label minEdge
00407         (
00408             const triSurface& surf,
00409             const labelList& edgeIndices
00410         );
00411 
00412         //- Returns element in edgeIndices with minimum length
00413         static label maxEdge
00414         (
00415             const triSurface& surf,
00416             const labelList& edgeIndices
00417         );
00418 
00419         //- Merge points within distance
00420         static triSurface mergePoints
00421         (
00422             const triSurface& surf,
00423             const scalar mergeTol
00424         );
00425 
00426         //- Triangle (unit) normal. If nearest point to triangle on edge use
00427         //  edge normal (calculated on the fly); if on vertex use vertex normal.
00428         //  Uses planarTol.
00429         static vector surfaceNormal
00430         (
00431             const triSurface& surf,
00432             const label nearestFaceI,
00433             const point& nearestPt
00434         );
00435 
00436         //- on which side of surface
00437         enum sideType
00438         {
00439             UNKNOWN,    // cannot be determined (e.g. non-manifold)
00440             INSIDE,     // inside
00441             OUTSIDE     // outside
00442         };
00443 
00444         //- if nearest point is on edgeI, determine on which side of surface
00445         //  sample is.
00446         static sideType edgeSide
00447         (
00448             const triSurface& surf,
00449             const point& sample,
00450             const point& nearestPoint,
00451             const label edgeI
00452         );
00453 
00454         //- Given nearest point (to sample) on surface determines which side
00455         //  sample is. Uses either face normal, edge normal or point normal
00456         //  (non-trivial). Uses triangle::classify.
00457         static sideType surfaceSide
00458         (
00459             const triSurface& surf,
00460             const point& sample,
00461             const label nearestFaceI,   // nearest face
00462             const point& nearestPt,     // nearest point on nearest face
00463             const scalar tol            // tolerance for nearness test.
00464         );
00465 
00466     // Triangulation of faces
00467 
00468         //- Simple triangulation of (selected patches of) boundaryMesh. Needs
00469         //  polyMesh (or polyBoundaryMesh) since only at this level are the
00470         //  triangles on neighbouring patches connected.
00471         static triSurface triangulate
00472         (
00473             const polyBoundaryMesh& mBesh,
00474             const labelHashSet& includePatches,
00475             const bool verbose = false
00476         );
00477 
00478         //- Face-centre triangulation of (selected patches of) boundaryMesh.
00479         //  Needs
00480         //  polyMesh (or polyBoundaryMesh) since only at this level are the
00481         //  triangles on neighbouring patches connected.
00482         triSurface triangulateFaceCentre
00483         (
00484             const polyBoundaryMesh& mBesh,
00485             const labelHashSet& includePatches,
00486             const bool verbose = false
00487         );
00488 
00489 
00490     // Triangulation and interpolation
00491 
00492         //- Calculate linear interpolation weights for point (guaranteed to be
00493         //  inside triangle)
00494         static void calcInterpolationWeights
00495         (
00496             const triPointRef&,
00497             const point&,
00498             FixedList<scalar, 3>& weights
00499         );
00500 
00501         // Calculate weighting factors from samplePts to triangle it is in.
00502         // Uses linear search to find triangle.
00503         // Vertices are:
00504         //   (a b c)  : vertices of the triangle abc the point is in
00505         // or if the point is outside all triangles:
00506         //   (a b -1) : the edge ab the point is nearest to.
00507         //   (a -1 -1) : the vertex a the point is nearest to
00508         static void calcInterpolationWeights
00509         (
00510             const triSurface& s,
00511             const pointField& samplePts,
00512             List<FixedList<label, 3> >& verts,
00513             List<FixedList<scalar, 3> >& weights
00514         );
00515 
00516         //- Do unconstrained Delaunay of points. Returns triSurface with 3D
00517         //  points with z=0. All triangles in region 0.
00518         static triSurface delaunay2D(const List<vector2D>&);
00519 
00520 
00521     // Tracking
00522 
00523         //- Test point on plane of triangle to see if on edge or point
00524         //  or inside.
00525         static surfaceLocation classify
00526         (
00527             const triSurface&,
00528             const label triI,
00529             const point& trianglePoint
00530         );
00531 
00532         //- Track on surface to get closer to point. Possible situations:
00533         //  - 1. reached endpoint
00534         //  - 2. reached edge (normal situation)
00535         //  - 3. reached end of surface (edge on single face)
00536         //  Input:
00537         //  - starting position+triangle/edge/point (so has to be on surface!)
00538         //  - (optional) previous position+triangle/edge/point to prevent
00539         //    going back. Set index (of triangle/edge/point) to -1 if not
00540         //    used.
00541         //  - end position+triangle/edge/point (so has to be on surface!)
00542         //  - plane to follow. Has to go through end point!
00543         //  Returns:
00544         //  - true if end point reached (situation 1)
00545         //  - new position+triangle/edge/point
00546         //  Caller has to check for situation 3 by checking that triangle()
00547         //  is not set.
00548         static surfaceLocation trackToEdge
00549         (
00550             const triSurface&,
00551             const surfaceLocation& start,
00552             const surfaceLocation& end,
00553             const plane& cutPlane
00554         );
00555 
00556         //- Track from edge to edge across surface. Uses trackToEdge.
00557         //  Not really useful by itself, more example of how to use trackToEdge.
00558         //  endInfo should be location on surface.
00559         //  hitInfo should be initialised to starting location (on surface as
00560         //  well). Upon return is set to end location.
00561         static void track
00562         (
00563             const triSurface&,
00564             const surfaceLocation& endInfo,
00565             const plane& cutPlane,
00566             surfaceLocation& hitInfo
00567         );
00568 };
00569 
00570 
00571 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00572 
00573 } // End namespace Foam
00574 
00575 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00576 
00577 #endif
00578 
00579 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines