readAC.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | foam-extend: Open Source CFD
4  \\ / O peration | Version: 3.2
5  \\ / A nd | Web: http://www.foam-extend.org
6  \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9  This file is part of foam-extend.
10 
11  foam-extend 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 3 of the License, or (at your
14  option) any later version.
15 
16  foam-extend is distributed in the hope that it will be useful, but
17  WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25 
26  Reader for .ac files generated by AC3D.
27 
28  See http://www.ac3d.org/ac3d/man/ac3dfileformat.html
29 
30 \*---------------------------------------------------------------------------*/
31 
32 #include "triSurface.H"
33 #include "IFstream.H"
34 #include "IStringStream.H"
35 #include "transform.H"
36 #include "tensor.H"
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42 
43 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 
45 static label parseInt(const string& str)
46 {
47  IStringStream intStream(str);
48 
49  label a;
50 
51  intStream >> a;
52 
53  return a;
54 }
55 
56 
57 static bool readCmd(IFstream& ACfile, string& cmd, string& args)
58 {
59  if (ACfile.good())
60  {
61  string line;
62  ACfile.getLine(line);
63 
64  string::size_type space = line.find(' ');
65 
66  if (space != string::npos)
67  {
68  cmd = line.substr(0, space);
69  args = line.substr(space+1);
70 
71  return true;
72  }
73  }
74  return false;
75 }
76 
77 
78 // Read up to line starting with cmd. Sets args to rest of line.
79 // Returns true if found, false if stream is not good anymore.
80 static bool readUpto
81 (
82  const string& cmd,
83  IFstream& ACfile,
84  string& args
85 )
86 {
87  while (ACfile.good())
88  {
89  string line;
90  ACfile.getLine(line);
91 
92  string::size_type space = line.find(' ');
93 
94  if (space != string::npos && line.substr(0, space) == cmd)
95  {
96  args = line.substr(space+1);
97  return true;
98  }
99  }
100  return false;
101 }
102 
103 
104 // Likewise but throws error if cmd not found
105 static void readUpto
106 (
107  const string& cmd,
108  IFstream& ACfile,
109  string& args,
110  const string errorMsg
111 )
112 {
113  if (!readUpto(cmd, ACfile, args))
114  {
115  FatalErrorIn("triSurface::readAC(const fileName&)")
116  << "Cannot find command " << cmd
117  << errorMsg << exit(FatalError);
118  }
119 }
120 
121 
122 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
123 
124 bool triSurface::readAC(const fileName& ACfileName)
125 {
126  IFstream ACfile(ACfileName);
127 
128  if (!ACfile.good())
129  {
130  FatalErrorIn("triSurface::readAC(const fileName&)")
131  << "Cannot read file " << ACfileName
132  << exit(FatalError);
133  }
134 
135  string line;
136  ACfile.getLine(line);
137 
138  string version = line.substr(4);
139 
140  if (version != "b")
141  {
142  WarningIn("bool triSurface::readAC(const fileName& ACfileName)")
143  << "When reading AC3D file " << ACfileName
144  << " read header " << line << " with version " << version
145  << endl << "Only tested reading with version 'b'."
146  << " This might give problems" << endl;
147  }
148 
149  string cmd;
150 
151  string args;
152 
153  if (!readUpto("OBJECT", ACfile, args) || (args != "world"))
154  {
155  FatalErrorIn("bool triSurface::readAC(const fileName& ACfileName)")
156  << "Cannot find \"OBJECT world\" in file " << ACfileName
157  << exit(FatalError);
158  }
159 
160  // Number of kids = patches
161 
162  readUpto("kids", ACfile, args, "");
163 
165 
166  // Storage for patches and unmerged points and faces
167 
171 
172 
173  // Start of vertices for object/patch
174  label patchStartVert = 0;
175 
176  for (label patchI = 0; patchI < nPatches; patchI++)
177  {
178  readUpto("OBJECT", ACfile, args, " while reading patch " + patchI);
179 
180  // Object global values
181  string patchName = string("patch") + name(patchI);
182  label nVerts = 0;
183  tensor rot(I);
184  vector loc(0, 0, 0);
185 
186  // Read all info for current patch
187  while (ACfile.good())
188  {
189  // Read line and get first word. If end of file break since
190  // patch should always end with 'kids' command ?not sure.
191  if (!readCmd(ACfile, cmd, args))
192  {
193  FatalErrorIn("triSurface::readAC(const fileName&)")
194  << "Did not read up to \"kids 0\" while reading patch "
195  << patchI << " from file " << ACfileName
196  << exit(FatalError);
197  }
198 
199  if (cmd == "name")
200  {
201  IStringStream nameStream(args);
202 
203  nameStream >> patchName;
204  }
205  else if (cmd == "rot")
206  {
207  // rot %f %f %f %f %f %f %f %f %f
208  IStringStream lineStream(args);
209 
210  lineStream
211  >> rot.xx() >> rot.xy() >> rot.xz()
212  >> rot.yx() >> rot.yy() >> rot.yz()
213  >> rot.zx() >> rot.zy() >> rot.zz();
214 
215  WarningIn("triSurface::readAC(const fileName&)")
216  << "rot (rotation tensor) command not implemented"
217  << "Line:" << cmd << ' ' << args << endl
218  << "while reading patch " << patchI << endl;
219  }
220  else if (cmd == "loc")
221  {
222  IStringStream lineStream(args);
223 
224  lineStream >> loc.x() >> loc.y() >> loc.z();
225  }
226  else if (cmd == "numvert")
227  {
228  nVerts = parseInt(args);
229 
230  for (label vertI = 0; vertI < nVerts; vertI++)
231  {
232  ACfile.getLine(line);
233 
234  IStringStream lineStream(line);
235 
236  point pt;
237 
238  lineStream >> pt.x() >> pt.y() >> pt.z();
239 
240  // Offset with current translation vector
241  points.append(pt+loc);
242  }
243  }
244  else if (cmd == "numsurf")
245  {
246  label nTris = parseInt(args);
247 
248  for (label triI = 0; triI < nTris; triI++)
249  {
250  static string errorMsg =
251  string(" while reading face ")
252  + name(triI) + " on patch " + name(patchI)
253  + " from file " + ACfileName;
254 
255  readUpto("SURF", ACfile, args, errorMsg);
256  readUpto("mat", ACfile, args, errorMsg);
257  readUpto("refs", ACfile, args, errorMsg);
258 
259  label size = parseInt(args);
260 
261  if (size != 3)
262  {
263  FatalErrorIn("triSurface::readAC(const fileName&)")
264  << "Can only read surfaces with 3 vertices."
265  << endl
266  << "Detected " << size << " when reading triangle "
267  << triI << " of patch " << patchI
268  << exit(FatalError);
269  }
270 
271  ACfile.getLine(line);
272 
273  label v0 = parseInt(line);
274 
275  ACfile.getLine(line);
276 
277  label v1 = parseInt(line);
278 
279  ACfile.getLine(line);
280 
281  label v2 = parseInt(line);
282 
283  faces.append
284  (
286  (
287  v0 + patchStartVert,
288  v1 + patchStartVert,
289  v2 + patchStartVert,
290  patchI
291  )
292  );
293  }
294 
295  // Done the current patch. Increment the offset vertices are
296  // stored at
297  patchStartVert += nVerts;
298  }
299  else if (cmd == "kids")
300  {
301  // 'kids' denotes the end of the current patch.
302 
303  label nKids = parseInt(args);
304 
305  if (nKids != 0)
306  {
307  FatalErrorIn("triSurface::readAC(const fileName&)")
308  << "Can only read objects without kids."
309  << " Encountered " << nKids << " kids when"
310  << " reading patch " << patchI
311  << exit(FatalError);
312  }
313 
314  patches[patchI] =
316  (
317  "empty",
318  word(patchName),
319  patchI
320  );
321 
322  // Stop reading current patch
323  break;
324  }
325  }
326  }
327 
328  faces.shrink();
329 
330  // Transfer DynamicLists to straight ones.
331  pointField allPoints(points.xfer());
332 
333  *this = triSurface(faces, patches, allPoints, true);
334 
336 
337  return true;
338 }
339 
340 
341 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
342 
343 } // End namespace Foam
344 
345 // ************************************************************************* //
Foam::Tensor
Templated 3D tensor derived from VectorSpace adding construction from 9 components,...
Definition: complexI.H:224
Foam::PrimitivePatch< labelledTri, List, pointField, point >::points
const Field< point > & points() const
Return reference to global points.
Definition: PrimitivePatchTemplate.H:282
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
nPatches
label nPatches
Definition: readKivaGrid.H:402
Foam::IFstream
Input from file stream.
Definition: IFstream.H:81
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:56
Foam::geometricSurfacePatch
The geometricSurfacePatch is like patchIdentifier but for surfaces. Holds type, name and index.
Definition: geometricSurfacePatch.H:53
Foam::readCmd
static bool readCmd(IFstream &ACfile, string &cmd, string &args)
Definition: readAC.C:57
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::string
A class for handling character strings derived from std::string.
Definition: string.H:74
Foam::triSurface::patches
const geometricSurfacePatchList & patches() const
Definition: triSurface.H:301
tensor.H
IStringStream.H
Foam::parseInt
static label parseInt(const string &str)
Definition: readAC.C:45
Foam::label
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
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::ISstream::getLine
ISstream & getLine(string &)
Raw, low-level getline into a string function.
Definition: ISstreamI.H:77
Foam::readUpto
static bool readUpto(const string &cmd, IFstream &ACfile, string &args)
Definition: readAC.C:81
Foam::triSurface::triSurface
triSurface()
Construct null.
Definition: triSurface.C:608
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
Foam::DynamicList::shrink
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:258
IFstream.H
Foam::I
static const sphericalTensor I(1)
Foam::Vector::x
const Cmpt & x() const
Definition: VectorI.H:65
Foam::FatalError
error FatalError
Foam::IStringStream
Input from memory buffer stream.
Definition: IStringStream.H:49
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::Vector::z
const Cmpt & z() const
Definition: VectorI.H:77
Foam::triSurface::readAC
bool readAC(const fileName &)
Definition: readAC.C:124
Foam::DynamicList::append
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::List< labelledTri >::size
label size() const
Return the number of elements in the UList.
rot
#define rot(x, k)
Definition: Test-HashingSpeed.C:81
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::triSurface::stitchTriangles
bool stitchTriangles(const pointField &rawPoints, const scalar tol=SMALL, const bool verbose=false)
Function to stitch the triangles by removing duplicate points.
Definition: stitchTriangles.C:38
Foam::line
A line primitive.
Definition: line.H:56
Foam::labelledTri
Triangle with additional region number.
Definition: labelledTri.H:49
Foam::Vector::y
const Cmpt & y() const
Definition: VectorI.H:71
FatalErrorIn
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:313
Foam::DelaunayMeshTools::allPoints
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
WarningIn
#define WarningIn(functionName)
Report a warning using Foam::Warning.
Definition: messageStream.H:254
transform.H
3D tensor transformation operations.
Foam::IOstream::good
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
args
Foam::argList args(argc, argv)
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47