FreeFOAM The Cross-Platform CFD Toolkit
GTSsurfaceFormat.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 \*---------------------------------------------------------------------------*/
25 
26 #include "GTSsurfaceFormat.H"
28 #include <OpenFOAM/clock.H>
29 #include <OpenFOAM/IFstream.H>
30 #include <OpenFOAM/IStringStream.H>
31 #include <OpenFOAM/Ostream.H>
32 #include <OpenFOAM/OFstream.H>
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
36 template<class Face>
38 (
39  const fileName& filename
40 )
41 {
42  read(filename);
43 }
44 
45 
46 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
47 
48 template<class Face>
50 (
51  const fileName& filename
52 )
53 {
54  this->clear();
55 
56  IFstream is(filename);
57  if (!is.good())
58  {
60  (
61  "fileFormats::GTSsurfaceFormat::read(const fileName&)"
62  )
63  << "Cannot read file " << filename
64  << exit(FatalError);
65  }
66 
67  // Read header
68  string line = this->getLineNoComment(is);
69 
70  label nPoints, nEdges, nElems;
71  {
72  IStringStream lineStream(line);
73  lineStream
74  >> nPoints
75  >> nEdges
76  >> nElems;
77  }
78 
79 
80  // write directly into the lists:
81  pointField& pointLst = this->storedPoints();
82  List<Face>& faceLst = this->storedFaces();
83  List<label>& zoneIds = this->storedZoneIds();
84 
85  pointLst.setSize(nPoints);
86  faceLst.setSize(nElems);
87  zoneIds.setSize(nElems);
88 
89  // Read points
90  forAll(pointLst, pointI)
91  {
92  scalar x, y, z;
93  line = this->getLineNoComment(is);
94  {
95  IStringStream lineStream(line);
96  lineStream
97  >> x >> y >> z;
98  }
99 
100  pointLst[pointI] = point(x, y, z);
101  }
102 
103  // Read edges (Foam indexing)
104  edgeList edges(nEdges);
105  forAll(edges, edgei)
106  {
107  label beg, end;
108  line = this->getLineNoComment(is);
109  {
110  IStringStream lineStream(line);
111  lineStream
112  >> beg >> end;
113  }
114  edges[edgei] = edge(beg - 1, end - 1);
115  }
116 
117 
118  // Read triangles. Convert references to edges into pointlabels
119  label maxZone = 0;
120  forAll(faceLst, faceI)
121  {
122  label e0Label, e1Label, e2Label;
123  label zoneI = 0;
124 
125  line = this->getLineNoComment(is);
126  {
127  IStringStream lineStream(line);
128  lineStream
129  >> e0Label >> e1Label >> e2Label;
130 
131  // Optional zone number: read first, then check state on stream
132  if (lineStream)
133  {
134  label num;
135  lineStream >> num;
136  if (!lineStream.bad())
137  {
138  zoneI = num;
139  if (maxZone < zoneI)
140  {
141  maxZone = zoneI;
142  }
143  }
144  }
145  }
146 
147  // Determine ordering of edges e0, e1
148  // common: common vertex, shared by e0 and e1
149  // e0Far: vertex on e0 which is not common
150  // e1Far: vertex on e1 which is not common
151  const edge& e0 = edges[e0Label - 1];
152  const edge& e1 = edges[e1Label - 1];
153  const edge& e2 = edges[e2Label - 1];
154 
155  label common01 = e0.commonVertex(e1);
156  if (common01 == -1)
157  {
159  (
160  "fileFormats::GTSsurfaceFormat::read(const fileName&)"
161  )
162  << "Edges 0 and 1 of triangle " << faceI
163  << " do not share a point.\n"
164  << " edge0:" << e0 << nl
165  << " edge1:" << e1
166  << exit(FatalError);
167  }
168 
169  label e0Far = e0.otherVertex(common01);
170  label e1Far = e1.otherVertex(common01);
171 
172  label common12 = e1.commonVertex(e2);
173  if (common12 == -1)
174  {
176  (
177  "fileFormats::GTSsurfaceFormat::read(const fileName&)"
178  )
179  << "Edges 1 and 2 of triangle " << faceI
180  << " do not share a point.\n"
181  << " edge1:" << e1 << nl
182  << " edge2:" << e2
183  << exit(FatalError);
184  }
185  label e2Far = e2.otherVertex(common12);
186 
187  // Does edge2 sit between edge1 and 0?
188  if (common12 != e1Far || e2Far != e0Far)
189  {
191  (
192  "fileFormats::GTSsurfaceFormat::read(const fileName&)"
193  )
194  << "Edges of triangle " << faceI
195  << " reference more than three points.\n"
196  << " edge0:" << e0 << nl
197  << " edge1:" << e1 << nl
198  << " edge2:" << e2 << nl
199  << exit(FatalError);
200  }
201 
202  faceLst[faceI] = triFace(e0Far, common01, e1Far);
203  zoneIds[faceI] = zoneI;
204  }
205 
206 
207  List<surfZoneIdentifier> newZones(maxZone+1);
208  forAll(newZones, zoneI)
209  {
210  newZones[zoneI] = surfZoneIdentifier
211  (
212  "zone" + ::Foam::name(zoneI),
213  zoneI
214  );
215  }
216 
217  this->storedZoneToc().transfer(newZones);
218 
219  return true;
220 }
221 
222 
223 template<class Face>
225 (
226  const fileName& filename,
227  const MeshedSurface<Face>& surf
228 )
229 {
230  const pointField& pointLst = surf.points();
231  const List<Face>& faceLst = surf.faces();
232 
233  const List<surfZone>& zones =
234  (
235  surf.surfZones().size()
236  ? surf.surfZones()
237  : surfaceFormatsCore::oneZone(faceLst)
238  );
239 
240  // check if output triangulation would be required
241  // It is too annoying to triangulate on-the-fly
242  // just issue a warning and get out
244  {
245  label nNonTris = 0;
246  forAll(faceLst, faceI)
247  {
248  if (faceLst[faceI].size() != 3)
249  {
250  ++nNonTris;
251  }
252  }
253 
254  if (nNonTris)
255  {
257  (
258  "fileFormats::GTSsurfaceFormat::write"
259  "(const fileName&, const MeshedSurface<Face>&)"
260  )
261  << "Surface has " << nNonTris << "/" << faceLst.size()
262  << " non-triangulated faces - not writing!" << endl;
263  return;
264  }
265  }
266 
267 
268  OFstream os(filename);
269  if (!os.good())
270  {
272  (
273  "fileFormats::GTSsurfaceFormat::write"
274  "(const fileName&, const MeshedSurface<Face>&)"
275  )
276  << "Cannot open file for writing " << filename
277  << exit(FatalError);
278  }
279 
280 
281  // Write header, print zone names as comment
282  os << "# GTS file" << nl
283  << "# Zones:" << nl;
284 
285  forAll(zones, zoneI)
286  {
287  os << "# " << zoneI << " "
288  << zones[zoneI].name() << nl;
289  }
290  os << "#" << nl;
291 
292  os << "# nPoints nEdges nTriangles" << nl
293  << pointLst.size() << ' ' << surf.nEdges() << ' '
294  << surf.size() << endl;
295 
296 
297  // Write vertex coords
298  forAll(pointLst, pointI)
299  {
300  const point& pt = pointLst[pointI];
301 
302  os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
303  }
304 
305 
306  // Write edges.
307  // Note: edges are in local point labels so convert
308  const edgeList& es = surf.edges();
309  const labelList& meshPts = surf.meshPoints();
310 
311  forAll(es, edgei)
312  {
313  os << meshPts[es[edgei].start()] + 1 << ' '
314  << meshPts[es[edgei].end()] + 1 << endl;
315  }
316 
317  // Write faces in terms of edges.
318  const labelListList& faceEs = surf.faceEdges();
319 
320  label faceIndex = 0;
321  forAll(zones, zoneI)
322  {
323  const surfZone& zone = zones[zoneI];
324 
325  forAll(zone, localFaceI)
326  {
327  const labelList& fEdges = faceEs[faceIndex++];
328 
329  os << fEdges[0] + 1 << ' '
330  << fEdges[1] + 1 << ' '
331  << fEdges[2] + 1 << ' '
332  << zoneI << endl;
333  }
334  }
335 }
336 
337 
338 template<class Face>
340 (
341  const fileName& filename,
342  const UnsortedMeshedSurface<Face>& surf
343 )
344 {
345  const pointField& pointLst = surf.points();
346  const List<Face>& faceLst = surf.faces();
347  const List<label>& zoneIds = surf.zoneIds();
348  const List<surfZoneIdentifier>& zoneToc = surf.zoneToc();
349 
350  // check if output triangulation would be required
351  // It is too annoying to triangulate on-the-fly
352  // just issue a warning and get out
354  {
355  label nNonTris = 0;
356  forAll(faceLst, faceI)
357  {
358  if (faceLst[faceI].size() != 3)
359  {
360  ++nNonTris;
361  }
362  }
363 
364  if (nNonTris)
365  {
367  (
368  "fileFormats::GTSsurfaceFormat::write"
369  "(const fileName&, const UnsortedMeshedSurfaces<Face>&)"
370  )
371  << "Surface has " << nNonTris << "/" << faceLst.size()
372  << " non-triangulated faces - not writing!" << endl;
373  return;
374  }
375  }
376 
377 
378  OFstream os(filename);
379  if (!os.good())
380  {
382  (
383  "fileFormats::GTSsurfaceFormat::write"
384  "(const fileName&, const UnsortedMeshedSurface<Face>&)"
385  )
386  << "Cannot open file for writing " << filename
387  << exit(FatalError);
388  }
389 
390 
391  // Write header, print zone names as comment
392  os << "# GTS file" << nl
393  << "# Zones:" << nl;
394 
395  forAll(zoneToc, zoneI)
396  {
397  os << "# " << zoneI << " "
398  << zoneToc[zoneI].name() << nl;
399  }
400  os << "#" << endl;
401 
402 
403  os << "# nPoints nEdges nTriangles" << nl
404  << pointLst.size() << ' ' << surf.nEdges() << ' '
405  << surf.size() << endl;
406 
407 
408  // Write vertex coords
409  forAll(pointLst, pointI)
410  {
411  os << pointLst[pointI].x() << ' '
412  << pointLst[pointI].y() << ' '
413  << pointLst[pointI].z() << endl;
414  }
415 
416 
417  // Write edges.
418  // Note: edges are in local point labels so convert
419  const edgeList& es = surf.edges();
420  const labelList& meshPts = surf.meshPoints();
421 
422  forAll(es, edgeI)
423  {
424  os << meshPts[es[edgeI].start()] + 1 << ' '
425  << meshPts[es[edgeI].end()] + 1 << endl;
426  }
427 
428 
429  // Write faces in terms of edges.
430  const labelListList& faceEs = surf.faceEdges();
431 
432  forAll(faceLst, faceI)
433  {
434  const labelList& fEdges = faceEs[faceI];
435 
436  os << fEdges[0] + 1 << ' '
437  << fEdges[1] + 1 << ' '
438  << fEdges[2] + 1 << ' '
439  << zoneIds[faceI] << endl;
440  }
441 }
442 
443 
444 // ************************ vim: set sw=4 sts=4 et: ************************ //