Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / applications / utilities / mesh / manipulation / objToVTK / objToVTK.C
blob85d70235b83faa14d131a572239944e75473b79e
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2010 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 Description
25     Read obj line (not surface!) file and convert into vtk.
27 \*---------------------------------------------------------------------------*/
29 #include "argList.H"
30 #include "OFstream.H"
31 #include <fstream>
32 #include <sstream>
33 #include "IStringStream.H"
34 #include "point.H"
35 #include "DynamicList.H"
38 using namespace Foam;
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 string getLine(std::ifstream& is)
45     string line;
46     do
47     {
48         std::getline(is, line);
49     }
50     while (line.size() && line[0] == '#');
52     return line;
56 // Read space-separated vertices (with optional '/' arguments)
57 labelList parseVertices(const string& line)
59     DynamicList<label> verts;
61     // Assume 'l' is followed by space.
62     string::size_type endNum = 1;
64     do
65     {
66         string::size_type startNum = line.find_first_not_of(' ', endNum);
68         if (startNum == string::npos)
69         {
70             break;
71         }
73         endNum = line.find(' ', startNum);
75         string vertexSpec;
76         if (endNum != string::npos)
77         {
78             vertexSpec = line.substr(startNum, endNum-startNum);
79         }
80         else
81         {
82             vertexSpec = line.substr(startNum, line.size() - startNum);
83         }
85         string::size_type slashPos = vertexSpec.find('/');
87         label vertI = 0;
88         if (slashPos != string::npos)
89         {
90             IStringStream intStream(vertexSpec.substr(0, slashPos));
92             intStream >> vertI;
93         }
94         else
95         {
96             IStringStream intStream(vertexSpec);
98             intStream >> vertI;
99         }
100         verts.append(vertI - 1);
101     }
102     while (true);
104     return verts.shrink();
108 // Main program:
110 int main(int argc, char *argv[])
112     argList::noParallel();
113     argList::validArgs.append("OBJ file");
114     argList::validArgs.append("output VTK file");
115     argList args(argc, argv);
117     const fileName objName = args[1];
118     const fileName outName = args[2];
120     std::ifstream OBJfile(objName.c_str());
122     if (!OBJfile.good())
123     {
124         FatalErrorIn(args.executable())
125             << "Cannot read file " << objName << exit(FatalError);
126     }
128     // Points and lines
129     DynamicList<point> points;
130     DynamicList<labelList> polyLines;
131     DynamicList<labelList> polygons;
133     bool hasWarned = false;
135     label lineNo = 0;
136     while (OBJfile.good())
137     {
138         string line = getLine(OBJfile);
139         lineNo++;
141         // Read first word
142         IStringStream lineStream(line);
143         word cmd;
144         lineStream >> cmd;
146         if (cmd == "v")
147         {
148             scalar x, y, z;
150             lineStream >> x >> y >> z;
152             points.append(point(x, y, z));
153         }
154         else if (cmd == "l")
155         {
156             polyLines.append(parseVertices(line));
157         }
158         else if (cmd == "f")
159         {
160             polygons.append(parseVertices(line));
161         }
162         else if (cmd != "")
163         {
164             if (!hasWarned)
165             {
166                 hasWarned = true;
168                 WarningIn(args.executable())
169                     << "Unrecognized OBJ command " << cmd << nl
170                     << "In line " << lineStream.str()
171                     << " at linenumber " << lineNo << nl
172                     << "Only recognized commands are 'v' and 'l'.\n"
173                     << "If this is a surface command use surfaceConvert instead"
174                     << " to convert to a file format that can be read by VTK"
175                     << endl;
176             }
177         }
178     }
181     //
182     // Write as vtk 'polydata' file
183     //
186     OFstream outFile(outName);
188     outFile
189         << "# vtk DataFile Version 2.0\n"
190         << objName << nl
191         << "ASCII\n"
192         << "DATASET POLYDATA\n"
193         << "POINTS " << points.size() << " float\n";
195     forAll(points, i)
196     {
197         const point& pt = points[i];
199         outFile << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
200     }
202     label nItems = 0;
203     forAll(polyLines, polyI)
204     {
205         nItems += polyLines[polyI].size() + 1;
206     }
208     outFile
209         << "LINES " << polyLines.size() << ' ' << nItems << nl;
211     forAll(polyLines, polyI)
212     {
213         const labelList& line = polyLines[polyI];
215         outFile << line.size();
217         forAll(line, i)
218         {
219             outFile << ' ' << line[i];
220         }
221         outFile << nl;
222     }
225     nItems = 0;
226     forAll(polygons, polyI)
227     {
228         nItems += polygons[polyI].size() + 1;
229     }
231     outFile
232         << "POLYGONS " << polygons.size() << ' ' << nItems << nl;
234     forAll(polygons, polyI)
235     {
236         const labelList& line = polygons[polyI];
238         outFile << line.size();
240         forAll(line, i)
241         {
242             outFile << ' ' << line[i];
243         }
244         outFile << nl;
245     }
248     outFile
249         << "POINT_DATA " << points.size() << nl
250         << "SCALARS pointID float 1\n"
251         << "LOOKUP_TABLE default\n";
253     forAll(points, i)
254     {
255         outFile << i;
257         if ((i % 10) == 1)
258         {
259             outFile << nl;
260         }
261         else
262         {
263             outFile << ' ';
264         }
265     }
267     Info<< "End\n" << endl;
269     return 0;
273 // ************************************************************************* //