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

OFFsurfaceFormat.C

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 \*---------------------------------------------------------------------------*/
00025 
00026 #include "OFFsurfaceFormat.H"
00027 #include <OpenFOAM/clock.H>
00028 #include <OpenFOAM/IFstream.H>
00029 #include <OpenFOAM/IStringStream.H>
00030 #include <OpenFOAM/Ostream.H>
00031 #include <OpenFOAM/OFstream.H>
00032 
00033 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00034 
00035 template<class Face>
00036 Foam::fileFormats::OFFsurfaceFormat<Face>::OFFsurfaceFormat
00037 (
00038     const fileName& filename
00039 )
00040 {
00041     read(filename);
00042 }
00043 
00044 
00045 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00046 
00047 template<class Face>
00048 bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
00049 (
00050     const fileName& filename
00051 )
00052 {
00053     const bool mustTriangulate = this->isTri();
00054     this->clear();
00055 
00056     IFstream is(filename);
00057     if (!is.good())
00058     {
00059         FatalErrorIn
00060         (
00061             "fileFormats::OFFsurfaceFormat::read(const fileName&)"
00062         )
00063             << "Cannot read file " << filename
00064             << exit(FatalError);
00065     }
00066 
00067     // Read header
00068     string hdr = this->getLineNoComment(is);
00069     if (hdr != "OFF")
00070     {
00071         FatalErrorIn
00072         (
00073             "fileFormats::OFFsurfaceFormat::read(const fileName&)"
00074         )
00075             << "OFF file " << filename << " does not start with 'OFF'"
00076             << exit(FatalError);
00077     }
00078 
00079 
00080     // get dimensions
00081     label nPoints, nElems, nEdges;
00082 
00083     string line = this->getLineNoComment(is);
00084     {
00085         IStringStream lineStream(line);
00086         lineStream >> nPoints >> nElems >> nEdges;
00087     }
00088 
00089     // Read points
00090     pointField pointLst(nPoints);
00091     forAll(pointLst, pointI)
00092     {
00093         scalar x, y, z;
00094         line = this->getLineNoComment(is);
00095         {
00096             IStringStream lineStream(line);
00097             lineStream >> x >> y >> z;
00098         }
00099         pointLst[pointI] = point(x, y, z);
00100     }
00101 
00102     // Read faces - ignore optional zone information
00103     // use a DynamicList for possible on-the-fly triangulation
00104     DynamicList<Face>  dynFaces(nElems);
00105 
00106     for (label faceI = 0; faceI < nElems; ++faceI)
00107     {
00108         line = this->getLineNoComment(is);
00109 
00110         {
00111             IStringStream lineStream(line);
00112 
00113             label nVerts;
00114             lineStream >> nVerts;
00115 
00116             List<label> verts(nVerts);
00117 
00118             forAll(verts, vertI)
00119             {
00120                 lineStream >> verts[vertI];
00121             }
00122 
00123             UList<label>& f = static_cast<UList<label>&>(verts);
00124 
00125             if (mustTriangulate && f.size() > 3)
00126             {
00127                 // simple face triangulation about f[0]
00128                 // cannot use face::triangulation (points may be incomplete)
00129                 for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
00130                 {
00131                     label fp2 = f.fcIndex(fp1);
00132 
00133                     dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
00134                 }
00135             }
00136             else
00137             {
00138                 dynFaces.append(Face(f));
00139             }
00140         }
00141     }
00142 
00143     // transfer to normal lists, no zone information
00144     this->reset(pointLst.xfer(), dynFaces.xfer(), Xfer<surfZoneList>());
00145 
00146     return true;
00147 }
00148 
00149 
00150 template<class Face>
00151 void Foam::fileFormats::OFFsurfaceFormat<Face>::write
00152 (
00153     const fileName& filename,
00154     const MeshedSurfaceProxy<Face>& surf
00155 )
00156 {
00157     const pointField& pointLst = surf.points();
00158     const List<Face>&  faceLst = surf.faces();
00159     const List<label>& faceMap = surf.faceMap();
00160     const List<surfZone>& zoneLst = surf.surfZones();
00161 
00162     OFstream os(filename);
00163     if (!os.good())
00164     {
00165         FatalErrorIn
00166         (
00167             "fileFormats::OFFsurfaceFormat::write"
00168             "(const fileName&, const MeshedSurfaceProxy<Face>&)"
00169         )
00170             << "Cannot open file for writing " << filename
00171             << exit(FatalError);
00172     }
00173 
00174     // Write header
00175     os  << "OFF" << endl
00176         << "# Geomview OFF file written " << clock::dateTime().c_str() << nl
00177         << nl
00178         << "# points : " << pointLst.size() << nl
00179         << "# faces  : " << faceLst.size() << nl
00180         << "# zones  : " << zoneLst.size() << nl;
00181 
00182     // Print zone names as comment
00183     forAll(zoneLst, zoneI)
00184     {
00185         os  << "#   " << zoneI << "  " << zoneLst[zoneI].name()
00186             << "  (nFaces: " << zoneLst[zoneI].size() << ")" << nl;
00187     }
00188 
00189     os  << nl
00190         << "# nPoints  nFaces  nEdges" << nl
00191         << pointLst.size() << ' ' << faceLst.size() << ' ' << 0 << nl
00192         << nl
00193         << "# <points count=\"" << pointLst.size() << "\">" << endl;
00194 
00195     // Write vertex coords
00196     forAll(pointLst, ptI)
00197     {
00198         os  << pointLst[ptI].x() << ' '
00199             << pointLst[ptI].y() << ' '
00200             << pointLst[ptI].z() << " #" << ptI << endl;
00201     }
00202 
00203     os  << "# </points>" << nl
00204         << nl
00205         << "# <faces count=\"" << faceLst.size() << "\">" << endl;
00206 
00207     label faceIndex = 0;
00208     forAll(zoneLst, zoneI)
00209     {
00210         os << "# <zone name=\"" << zoneLst[zoneI].name() << "\">" << endl;
00211 
00212         if (surf.useFaceMap())
00213         {
00214             forAll(zoneLst[zoneI], localFaceI)
00215             {
00216                 const Face& f = faceLst[faceMap[faceIndex++]];
00217 
00218                 os << f.size();
00219                 forAll(f, fp)
00220                 {
00221                     os << ' ' << f[fp];
00222                 }
00223 
00224                 // add optional zone information
00225                 os << ' ' << zoneI << endl;
00226             }
00227         }
00228         else
00229         {
00230             forAll(zoneLst[zoneI], localFaceI)
00231             {
00232                 const Face& f = faceLst[faceIndex++];
00233 
00234                 os << f.size();
00235                 forAll(f, fp)
00236                 {
00237                     os << ' ' << f[fp];
00238                 }
00239 
00240                 // add optional zone information
00241                 os << ' ' << zoneI << endl;
00242             }
00243         }
00244         os << "# </zone>" << endl;
00245     }
00246     os << "# </faces>" << endl;
00247 }
00248 
00249 
00250 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines