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) 2011-2015 OpenFOAM Foundation
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 \*---------------------------------------------------------------------------*/
31 
32 #include "argList.H"
33 #include "OFstream.H"
34 #include <fstream>
35 #include <sstream>
36 #include "IStringStream.H"
37 #include "point.H"
38 #include "DynamicList.H"
39 
40 
41 using namespace Foam;
42 
43 
44 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 
46 string getLine(std::ifstream& is)
47 {
48  string line;
49  do
50  {
51  std::getline(is, line);
52  }
53  while (line.size() && line[0] == '#');
54 
55  return line;
56 }
57 
58 
59 // Read space-separated vertices (with optional '/' arguments)
60 labelList parseVertices(const string& line)
61 {
62  DynamicList<label> verts;
63 
64  // Assume 'l' is followed by space.
65  string::size_type endNum = 1;
66 
67  do
68  {
69  string::size_type startNum = line.find_first_not_of(' ', endNum);
70 
71  if (startNum == string::npos)
72  {
73  break;
74  }
75 
76  endNum = line.find(' ', startNum);
77 
78  string vertexSpec;
79  if (endNum != string::npos)
80  {
81  vertexSpec = line.substr(startNum, endNum-startNum);
82  }
83  else
84  {
85  vertexSpec = line.substr(startNum, line.size() - startNum);
86  }
87 
88  string::size_type slashPos = vertexSpec.find('/');
89 
90  label vertI = 0;
91  if (slashPos != string::npos)
92  {
93  IStringStream intStream(vertexSpec.substr(0, slashPos));
94 
95  intStream >> vertI;
96  }
97  else
98  {
99  IStringStream intStream(vertexSpec);
100 
101  intStream >> vertI;
102  }
103  verts.append(vertI - 1);
104  }
105  while (true);
106 
107  return verts.shrink();
108 }
109 
110 
111 
112 int main(int argc, char *argv[])
113 {
115  argList::validArgs.append("OBJ file");
116  argList::validArgs.append("output VTK file");
117  argList args(argc, argv);
118 
119  const fileName objName = args[1];
120  const fileName outName = args[2];
121 
122  std::ifstream OBJfile(objName.c_str());
123 
124  if (!OBJfile.good())
125  {
127  << "Cannot read file " << objName << exit(FatalError);
128  }
129 
130  // Points and lines
132  DynamicList<vector> pointNormals;
133  DynamicList<labelList> polyLines;
134  DynamicList<labelList> polygons;
135 
136  bool hasWarned = false;
137 
138  label lineNo = 0;
139  while (OBJfile.good())
140  {
141  string line = getLine(OBJfile);
142  lineNo++;
143 
144  // Read first word
145  IStringStream lineStream(line);
146  word cmd;
147  lineStream >> cmd;
148 
149  if (cmd == "v")
150  {
151  scalar x, y, z;
152 
153  lineStream >> x >> y >> z;
154 
155  points.append(point(x, y, z));
156  }
157  else if (cmd == "vn")
158  {
159  scalar x, y, z;
160 
161  lineStream >> x >> y >> z;
162 
163  pointNormals.append(vector(x, y, z));
164  }
165  else if (cmd == "l")
166  {
167  polyLines.append(parseVertices(line));
168  }
169  else if (cmd == "f")
170  {
171  polygons.append(parseVertices(line));
172  }
173  else if (cmd != "")
174  {
175  if (!hasWarned)
176  {
177  hasWarned = true;
178 
180  << "Unrecognized OBJ command " << cmd << nl
181  << "In line " << lineStream.str()
182  << " at linenumber " << lineNo << nl
183  << "Only recognized commands are 'v' and 'l'.\n"
184  << "If this is a surface command use surfaceConvert instead"
185  << " to convert to a file format that can be read by VTK"
186  << endl;
187  }
188  }
189  }
190 
191 
192  //
193  // Write as vtk 'polydata' file
194  //
195 
196 
197  OFstream outFile(outName);
198 
199  outFile
200  << "# vtk DataFile Version 2.0\n"
201  << objName << nl
202  << "ASCII\n"
203  << "DATASET POLYDATA\n"
204  << "POINTS " << points.size() << " float\n";
205 
206  forAll(points, i)
207  {
208  const point& pt = points[i];
209 
210  outFile << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
211  }
212 
213  outFile
214  << "VERTICES " << points.size() << ' ' << (2 * points.size()) << nl;
215 
216  forAll(points, i)
217  {
218  outFile << 1 << ' ' << i << nl;
219  }
220 
221  label nItems = 0;
222  forAll(polyLines, polyI)
223  {
224  nItems += polyLines[polyI].size() + 1;
225  }
226 
227  outFile
228  << "LINES " << polyLines.size() << ' ' << nItems << nl;
229 
230  forAll(polyLines, polyI)
231  {
232  const labelList& line = polyLines[polyI];
233 
234  outFile << line.size();
235 
236  forAll(line, i)
237  {
238  outFile << ' ' << line[i];
239  }
240  outFile << nl;
241  }
242 
243 
244  nItems = 0;
245  forAll(polygons, polyI)
246  {
247  nItems += polygons[polyI].size() + 1;
248  }
249 
250  outFile
251  << "POLYGONS " << polygons.size() << ' ' << nItems << nl;
252 
253  forAll(polygons, polyI)
254  {
255  const labelList& line = polygons[polyI];
256 
257  outFile << line.size();
258 
259  forAll(line, i)
260  {
261  outFile << ' ' << line[i];
262  }
263  outFile << nl;
264  }
265 
266 
267  outFile
268  << "POINT_DATA " << points.size() << nl
269  << "SCALARS pointID float 1\n"
270  << "LOOKUP_TABLE default\n";
271 
272  forAll(points, i)
273  {
274  outFile << i;
275 
276  if ((i % 10) == 1)
277  {
278  outFile << nl;
279  }
280  else
281  {
282  outFile << ' ';
283  }
284  }
285 
286  if (!pointNormals.empty())
287  {
288  outFile << nl << "NORMALS pointNormals float\n";
289 
290  forAll(pointNormals, i)
291  {
292  const vector& n = pointNormals[i];
293 
294  outFile << n.x() << ' ' << n.y() << ' ' << n.z() << nl;
295  }
296  }
297 
298  Info<< "End\n" << endl;
299 
300  return 0;
301 }
302 
303 
304 // ************************************************************************* //
const Cmpt & z() const
Definition: VectorI.H:87
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
A class for handling file names.
Definition: fileName.H:69
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
const Cmpt & x() const
Definition: VectorI.H:75
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
bool empty() const
Return true if the UList is empty (ie, size() is zero)
Definition: UListI.H:313
Output to file stream.
Definition: OFstream.H:81
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
static void noParallel()
Remove the parallel options.
Definition: argList.C:146
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:154
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
scalar y
const pointField & points
A class for handling words, derived from string.
Definition: word.H:59
Extract command arguments and options from the supplied argc and argv parameters. ...
Definition: argList.H:102
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:292
const Cmpt & y() const
Definition: VectorI.H:81
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:240
static const char nl
Definition: Ostream.H:262
vector point
Point is a vector.
Definition: point.H:41
#define WarningInFunction
Report a warning using Foam::Warning.
Input from memory buffer stream.
Definition: IStringStream.H:49
messageStream Info
Foam::argList args(argc, argv)
Namespace for OpenFOAM.