FreeFOAM The Cross-Platform CFD Toolkit
objToVTK.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 Application
25  objToVTK
26 
27 Description
28  Read obj line (not surface!) file and convert into vtk.
29 
30 Usage
31 
32  - objToVTK [OPTIONS] <OBJ file> <output VTK file>
33 
34  @param <OBJ file> \n
35  @todo Detailed description of argument.
36 
37  @param <output VTK file> \n
38  @todo Detailed description of argument.
39 
40  @param -case <dir>\n
41  Case directory.
42 
43  @param -help \n
44  Display help message.
45 
46  @param -doc \n
47  Display Doxygen API documentation page for this application.
48 
49  @param -srcDoc \n
50  Display Doxygen source documentation page for this application.
51 
52 \*---------------------------------------------------------------------------*/
53 
54 #include <OpenFOAM/argList.H>
55 #include <OpenFOAM/OFstream.H>
56 #include <fstream>
57 #include <sstream>
58 #include <OpenFOAM/IStringStream.H>
59 #include <OpenFOAM/point.H>
60 #include <OpenFOAM/DynamicList.H>
61 
62 
63 using namespace Foam;
64 
65 
66 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
67 
68 string getLine(std::ifstream& is)
69 {
70  string line;
71  do
72  {
73  std::getline(is, line);
74  }
75  while (line.size() && line[0] == '#');
76 
77  return line;
78 }
79 
80 
81 // Read space-separated vertices (with optional '/' arguments)
82 labelList parseVertices(const string& line)
83 {
84  DynamicList<label> verts;
85 
86  // Assume 'l' is followed by space.
87  string::size_type endNum = 1;
88 
89  do
90  {
91  string::size_type startNum = line.find_first_not_of(' ', endNum);
92 
93  if (startNum == string::npos)
94  {
95  break;
96  }
97 
98  endNum = line.find(' ', startNum);
99 
100  string vertexSpec;
101  if (endNum != string::npos)
102  {
103  vertexSpec = line.substr(startNum, endNum-startNum);
104  }
105  else
106  {
107  vertexSpec = line.substr(startNum, line.size() - startNum);
108  }
109 
110  string::size_type slashPos = vertexSpec.find('/');
111 
112  label vertI = 0;
113  if (slashPos != string::npos)
114  {
115  IStringStream intStream(vertexSpec.substr(0, slashPos));
116 
117  intStream >> vertI;
118  }
119  else
120  {
121  IStringStream intStream(vertexSpec);
122 
123  intStream >> vertI;
124  }
125  verts.append(vertI - 1);
126  }
127  while (true);
128 
129  return verts.shrink();
130 }
131 
132 
133 // Main program:
134 
135 int main(int argc, char *argv[])
136 {
139  argList::validArgs.append("OBJ file");
140  argList::validArgs.append("output VTK file");
141  argList args(argc, argv);
142 
143  fileName objName(args.additionalArgs()[0]);
144  fileName outName(args.additionalArgs()[1]);
145 
146  std::ifstream OBJfile(objName.c_str());
147 
148  if (!OBJfile.good())
149  {
151  << "Cannot read file " << objName << exit(FatalError);
152  }
153 
154  // Points and lines
156  DynamicList<labelList> polyLines;
157  DynamicList<labelList> polygons;
158 
159  bool hasWarned = false;
160 
161  label lineNo = 0;
162  while (OBJfile.good())
163  {
164  string line = getLine(OBJfile);
165  lineNo++;
166 
167  // Read first word
168  IStringStream lineStream(line);
169  word cmd;
170  lineStream >> cmd;
171 
172  if (cmd == "v")
173  {
174  scalar x, y, z;
175 
176  lineStream >> x >> y >> z;
177 
178  points.append(point(x, y, z));
179  }
180  else if (cmd == "l")
181  {
182  polyLines.append(parseVertices(line));
183  }
184  else if (cmd == "f")
185  {
186  polygons.append(parseVertices(line));
187  }
188  else if (cmd != "")
189  {
190  if (!hasWarned)
191  {
192  hasWarned = true;
193 
195  << "Unrecognized OBJ command " << cmd << nl
196  << "In line " << lineStream.str()
197  << " at linenumber " << lineNo << nl
198  << "Only recognized commands are 'v' and 'l'.\n"
199  << "If this is a surface command use surfaceConvert instead"
200  << " to convert to a file format that can be read by VTK"
201  << endl;
202  }
203  }
204  }
205 
206 
207  //
208  // Write as vtk 'polydata' file
209  //
210 
211 
212  OFstream outFile(outName);
213 
214  outFile
215  << "# vtk DataFile Version 2.0\n"
216  << objName << nl
217  << "ASCII\n"
218  << "DATASET POLYDATA\n"
219  << "POINTS " << points.size() << " float\n";
220 
221  forAll(points, i)
222  {
223  const point& pt = points[i];
224 
225  outFile << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
226  }
227 
228  label nItems = 0;
229  forAll(polyLines, polyI)
230  {
231  nItems += polyLines[polyI].size() + 1;
232  }
233 
234  outFile
235  << "LINES " << polyLines.size() << ' ' << nItems << nl;
236 
237  forAll(polyLines, polyI)
238  {
239  const labelList& line = polyLines[polyI];
240 
241  outFile << line.size();
242 
243  forAll(line, i)
244  {
245  outFile << ' ' << line[i];
246  }
247  outFile << nl;
248  }
249 
250 
251  nItems = 0;
252  forAll(polygons, polyI)
253  {
254  nItems += polygons[polyI].size() + 1;
255  }
256 
257  outFile
258  << "POLYGONS " << polygons.size() << ' ' << nItems << nl;
259 
260  forAll(polygons, polyI)
261  {
262  const labelList& line = polygons[polyI];
263 
264  outFile << line.size();
265 
266  forAll(line, i)
267  {
268  outFile << ' ' << line[i];
269  }
270  outFile << nl;
271  }
272 
273 
274  outFile
275  << "POINT_DATA " << points.size() << nl
276  << "SCALARS pointID float 1\n"
277  << "LOOKUP_TABLE default\n";
278 
279  forAll(points, i)
280  {
281  outFile << i;
282 
283  if ((i % 10) == 1)
284  {
285  outFile << nl;
286  }
287  else
288  {
289  outFile << ' ';
290  }
291  }
292 
293  Info << "End\n" << endl;
294 
295  return 0;
296 }
297 
298 
299 // ************************ vim: set sw=4 sts=4 et: ************************ //