initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / applications / utilities / mesh / manipulation / objToVTK / objToVTK.C
blob07190e49f9842dbfbae3f00ec5d7544934ff9df6
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Description
26     Read obj line (not surface!) file and convert into vtk.
28 \*---------------------------------------------------------------------------*/
30 #include "argList.H"
31 #include "OFstream.H"
32 #include <fstream>
33 #include <sstream>
34 #include "IStringStream.H"
35 #include "point.H"
36 #include "DynamicList.H"
39 using namespace Foam;
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 string getLine(std::ifstream& is)
46     string line;
47     do
48     {
49         std::getline(is, line);
50     }
51     while (line.size() && line[0] == '#');
53     return line;
57 // Read space-separated vertices (with optional '/' arguments)
58 labelList parseVertices(const string& line)
60     DynamicList<label> verts;
62     // Assume 'l' is followed by space.
63     string::size_type endNum = 1;
65     do
66     {
67         string::size_type startNum = line.find_first_not_of(' ', endNum);
69         if (startNum == string::npos)
70         {
71             break;
72         }
74         endNum = line.find(' ', startNum);
76         string vertexSpec;
77         if (endNum != string::npos)
78         {
79             vertexSpec = line.substr(startNum, endNum-startNum);
80         }
81         else
82         {
83             vertexSpec = line.substr(startNum, line.size() - startNum);
84         }
86         string::size_type slashPos = vertexSpec.find('/');
88         label vertI = 0;
89         if (slashPos != string::npos)
90         {
91             IStringStream intStream(vertexSpec.substr(0, slashPos));
93             intStream >> vertI;
94         }
95         else
96         {
97             IStringStream intStream(vertexSpec);
99             intStream >> vertI;
100         }
101         verts.append(vertI - 1);
102     }
103     while (true);
105     return verts.shrink();
109 // Main program:
111 int main(int argc, char *argv[])
113     argList::noParallel();
114     argList::validArgs.clear();
115     argList::validArgs.append("OBJ file");
116     argList::validArgs.append("output VTK file");
117     argList::argList args(argc, argv);
119     fileName objName(args.additionalArgs()[0]);
120     fileName outName(args.additionalArgs()[1]);
122     std::ifstream OBJfile(objName.c_str());
124     if (!OBJfile.good())
125     {
126         FatalErrorIn(args.executable())
127             << "Cannot read file " << objName << exit(FatalError);
128     }
130     // Points and lines
131     DynamicList<point> points;
132     DynamicList<labelList> polyLines;
133     DynamicList<labelList> polygons;
135     bool hasWarned = false;
137     label lineNo = 0;
138     while (OBJfile.good())
139     {
140         string line = getLine(OBJfile);
141         lineNo++;
143         // Read first word
144         IStringStream lineStream(line);
145         word cmd;
146         lineStream >> cmd;
148         if (cmd == "v")
149         {
150             scalar x, y, z;
152             lineStream >> x >> y >> z;
154             points.append(point(x, y, z));
155         }
156         else if (cmd == "l")
157         {
158             polyLines.append(parseVertices(line));
159         }
160         else if (cmd == "f")
161         {
162             polygons.append(parseVertices(line));
163         }
164         else if (cmd != "")
165         {
166             if (!hasWarned)
167             {
168                 hasWarned = true;
170                 WarningIn(args.executable())
171                     << "Unrecognized OBJ command " << cmd << nl
172                     << "In line " << lineStream.str()
173                     << " at linenumber " << lineNo << nl
174                     << "Only recognized commands are 'v' and 'l'.\n"
175                     << "If this is a surface command use surfaceConvert instead"
176                     << " to convert to a file format that can be read by VTK"
177                     << endl;
178             }
179         }
180     }
183     //
184     // Write as vtk 'polydata' file
185     //
188     OFstream outFile(outName);
190     outFile
191         << "# vtk DataFile Version 2.0\n"
192         << objName << nl
193         << "ASCII\n"
194         << "DATASET POLYDATA\n"
195         << "POINTS " << points.size() << " float\n";
197     forAll(points, i)
198     {
199         const point& pt = points[i];
201         outFile << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
202     }
204     label nItems = 0;
205     forAll(polyLines, polyI)
206     {
207         nItems += polyLines[polyI].size() + 1;
208     }
210     outFile
211         << "LINES " << polyLines.size() << ' ' << nItems << nl;
213     forAll(polyLines, polyI)
214     {
215         const labelList& line = polyLines[polyI];
217         outFile << line.size();
219         forAll(line, i)
220         {
221             outFile << ' ' << line[i];
222         }
223         outFile << nl;
224     }
227     nItems = 0;
228     forAll(polygons, polyI)
229     {
230         nItems += polygons[polyI].size() + 1;
231     }
233     outFile
234         << "POLYGONS " << polygons.size() << ' ' << nItems << nl;
236     forAll(polygons, polyI)
237     {
238         const labelList& line = polygons[polyI];
240         outFile << line.size();
242         forAll(line, i)
243         {
244             outFile << ' ' << line[i];
245         }
246         outFile << nl;
247     }
250     outFile
251         << "POINT_DATA " << points.size() << nl
252         << "SCALARS pointID float 1\n"
253         << "LOOKUP_TABLE default\n";
255     forAll(points, i)
256     {
257         outFile << i;
259         if ((i % 10) == 1)
260         {
261             outFile << nl;
262         }
263         else
264         {
265             outFile << ' ';
266         }
267     }
269     Info << "End\n" << endl;
271     return 0;
275 // ************************************************************************* //