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

readAC.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 Description
00025 
00026     Reader for .ac files generated by AC3D.
00027 
00028     See http://www.ac3d.org/ac3d/man/ac3dfileformat.html
00029 
00030 \*---------------------------------------------------------------------------*/
00031 
00032 #include <triSurface/triSurface.H>
00033 #include <OpenFOAM/IFstream.H>
00034 #include <OpenFOAM/IStringStream.H>
00035 #include <OpenFOAM/transform.H>
00036 #include <OpenFOAM/tensor.H>
00037 
00038 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00039 
00040 namespace Foam
00041 {
00042 
00043 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00044 
00045 static label parseInt(const string& str)
00046 {
00047     IStringStream intStream(str);
00048 
00049     label a;
00050 
00051     intStream >> a;
00052 
00053     return a;
00054 }
00055 
00056 
00057 static bool readCmd(IFstream& ACfile, string& cmd, string& args)
00058 {
00059     if (ACfile.good())
00060     {
00061         string line;
00062         ACfile.getLine(line);
00063 
00064         string::size_type space = line.find(' ');
00065 
00066         if (space != string::npos)
00067         {
00068             cmd  = line.substr(0, space);
00069             args = line.substr(space+1);
00070 
00071             return true;
00072         }
00073     }
00074     return false;
00075 }
00076 
00077 
00078 // Read up to line starting with cmd. Sets args to rest of line.
00079 // Returns true if found, false if stream is not good anymore.
00080 static bool readUpto
00081 (
00082     const string& cmd,
00083     IFstream& ACfile,
00084     string& args
00085 )
00086 {
00087     while (ACfile.good())
00088     {
00089         string line;
00090         ACfile.getLine(line);
00091 
00092         string::size_type space = line.find(' ');
00093 
00094         if (space != string::npos && line.substr(0, space) == cmd)
00095         {
00096             args = line.substr(space+1);            
00097             return true;
00098         }
00099     }
00100     return false;
00101 }
00102 
00103 
00104 // Likewise but throws error if cmd not found
00105 static void readUpto
00106 (
00107     const string& cmd,
00108     IFstream& ACfile,
00109     string& args,
00110     const string errorMsg
00111 )
00112 {
00113     if (!readUpto(cmd, ACfile, args))
00114     {
00115         FatalErrorIn("triSurface::readAC(const fileName&)")
00116             << "Cannot find command " << cmd
00117             << errorMsg << exit(FatalError);
00118     }
00119 }
00120 
00121 
00122 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00123 
00124 bool triSurface::readAC(const fileName& ACfileName)
00125 {
00126     IFstream ACfile(ACfileName);
00127 
00128     if (!ACfile.good())
00129     {
00130         FatalErrorIn("triSurface::readAC(const fileName&)")
00131             << "Cannot read file " << ACfileName
00132             << exit(FatalError);
00133     }
00134 
00135     string line;
00136     ACfile.getLine(line);
00137 
00138     string version = line.substr(4);
00139 
00140     if (version != "b")
00141     {
00142         WarningIn("bool triSurface::readAC(const fileName& ACfileName)")
00143             << "When reading AC3D file " << ACfileName
00144             << " read header " << line << " with version " << version
00145             << endl << "Only tested reading with version 'b'."
00146             << " This might give problems" << endl;
00147     }
00148 
00149     string cmd;
00150 
00151     string args;
00152 
00153     if (!readUpto("OBJECT", ACfile, args) || (args != "world"))
00154     {
00155         FatalErrorIn("bool triSurface::readAC(const fileName& ACfileName)")
00156             << "Cannot find \"OBJECT world\" in file " << ACfileName
00157             << exit(FatalError);
00158     }
00159 
00160     // Number of kids = patches
00161 
00162     readUpto("kids", ACfile, args, "");
00163 
00164     label nPatches = parseInt(args);
00165 
00166     // Storage for patches and unmerged points and faces
00167 
00168     DynamicList<point> points;
00169     DynamicList<labelledTri> faces;
00170     geometricSurfacePatchList patches(nPatches);
00171 
00172 
00173     // Start of vertices for object/patch
00174     label patchStartVert = 0;
00175 
00176     for (label patchI = 0; patchI < nPatches; patchI++)
00177     {
00178         readUpto("OBJECT", ACfile, args, " while reading patch " + patchI);
00179 
00180         // Object global values
00181         string patchName = string("patch") + name(patchI);
00182         label nVerts = 0;
00183         tensor rot(I);
00184         vector loc(0, 0, 0);
00185 
00186         // Read all info for current patch
00187         while (ACfile.good())
00188         {
00189             // Read line and get first word. If end of file break since
00190             // patch should always end with 'kids' command ?not sure.
00191             if (!readCmd(ACfile, cmd, args))
00192             {
00193                 FatalErrorIn("triSurface::readAC(const fileName&)")
00194                     << "Did not read up to \"kids 0\" while reading patch "
00195                     << patchI << " from file " << ACfileName
00196                     << exit(FatalError);
00197             }
00198 
00199             if (cmd == "name")
00200             {
00201                 IStringStream nameStream(args);
00202 
00203                 nameStream >> patchName;
00204             }
00205             else if (cmd == "rot")
00206             {
00207                 // rot %f %f %f  %f %f %f  %f %f %f
00208                 IStringStream lineStream(args);
00209 
00210                 lineStream
00211                     >> rot.xx() >> rot.xy() >> rot.xz()
00212                     >> rot.yx() >> rot.yy() >> rot.yz()
00213                     >> rot.zx() >> rot.zy() >> rot.zz();
00214 
00215                 WarningIn("triSurface::readAC(const fileName&)")
00216                     << "rot (rotation tensor) command not implemented"
00217                     << "Line:" << cmd << ' ' << args << endl
00218                     << "while reading patch " << patchI << endl;
00219             }
00220             else if (cmd == "loc")
00221             {
00222                 IStringStream lineStream(args);
00223 
00224                 lineStream >> loc.x() >> loc.y() >> loc.z();
00225             }
00226             else if (cmd == "numvert")
00227             {
00228                 nVerts = parseInt(args);
00229 
00230                 for (label vertI = 0; vertI < nVerts; vertI++)
00231                 {
00232                     ACfile.getLine(line);
00233 
00234                     IStringStream lineStream(line);
00235 
00236                     point pt;
00237 
00238                     lineStream >> pt.x() >> pt.y() >> pt.z();
00239 
00240                     // Offset with current translation vector
00241                     points.append(pt+loc);
00242                 }
00243             }
00244             else if (cmd == "numsurf")
00245             {
00246                 label nTris = parseInt(args);
00247 
00248                 for (label triI = 0; triI < nTris; triI++)
00249                 {
00250                     static string errorMsg =
00251                         string(" while reading face ")
00252                       + name(triI) + " on patch " + name(patchI)
00253                       + " from file " + ACfileName;
00254 
00255                     readUpto("SURF", ACfile, args, errorMsg);
00256                     readUpto("mat", ACfile, args, errorMsg);
00257                     readUpto("refs", ACfile, args, errorMsg);
00258 
00259                     label size = parseInt(args);
00260 
00261                     if (size != 3)
00262                     {
00263                         FatalErrorIn("triSurface::readAC(const fileName&)")
00264                             << "Can only read surfaces with 3 vertices."
00265                             << endl
00266                             << "Detected " << size << " when reading triangle "
00267                             << triI << " of patch " << patchI
00268                             << exit(FatalError);
00269                     }
00270 
00271                     ACfile.getLine(line);
00272 
00273                     label v0 = parseInt(line);
00274 
00275                     ACfile.getLine(line);
00276 
00277                     label v1 = parseInt(line);
00278 
00279                     ACfile.getLine(line);
00280 
00281                     label v2 = parseInt(line);
00282 
00283                     faces.append
00284                     (
00285                         labelledTri 
00286                         (
00287                             v0 + patchStartVert,
00288                             v1 + patchStartVert,
00289                             v2 + patchStartVert,
00290                             patchI
00291                         )
00292                     );
00293                 }
00294 
00295                 // Done the current patch. Increment the offset vertices are
00296                 // stored at
00297                 patchStartVert += nVerts;
00298             }
00299             else if (cmd == "kids")
00300             {
00301                 // 'kids' denotes the end of the current patch.
00302 
00303                 label nKids = parseInt(args);
00304 
00305                 if (nKids != 0)
00306                 {
00307                     FatalErrorIn("triSurface::readAC(const fileName&)")
00308                         << "Can only read objects without kids."
00309                         << " Encountered " << nKids << " kids when"
00310                         << " reading patch " << patchI
00311                         << exit(FatalError);
00312                 }
00313 
00314                 patches[patchI] =
00315                     geometricSurfacePatch
00316                     (
00317                         "empty",
00318                         word(patchName),
00319                         patchI
00320                     );
00321 
00322                 // Stop reading current patch
00323                 break;
00324             }
00325         }
00326     }
00327 
00328     faces.shrink();
00329 
00330     // Transfer DynamicLists to straight ones.
00331     pointField allPoints(points.xfer());
00332 
00333     *this = triSurface(faces, patches, allPoints, true);
00334 
00335     stitchTriangles(allPoints);
00336 
00337     return true;
00338 }
00339 
00340 
00341 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00342 
00343 } // End namespace Foam
00344 
00345 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines