OFFsurfaceFormat.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 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 \*---------------------------------------------------------------------------*/
25 
26 #include "OFFsurfaceFormat.H"
27 #include "clock.H"
28 #include "IFstream.H"
29 #include "IStringStream.H"
30 #include "Ostream.H"
31 #include "OFstream.H"
32 
33 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34 
35 template<class Face>
37 (
38  const fileName& filename
39 )
40 {
41  read(filename);
42 }
43 
44 
45 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
46 
47 template<class Face>
49 (
50  const fileName& filename
51 )
52 {
53  const bool mustTriangulate = this->isTri();
54  this->clear();
55 
56  IFstream is(filename);
57  if (!is.good())
58  {
60  (
61  "fileFormats::OFFsurfaceFormat::read(const fileName&)"
62  )
63  << "Cannot read file " << filename
64  << exit(FatalError);
65  }
66 
67  // Read header
68  string hdr = this->getLineNoComment(is);
69  if (hdr != "OFF")
70  {
72  (
73  "fileFormats::OFFsurfaceFormat::read(const fileName&)"
74  )
75  << "OFF file " << filename << " does not start with 'OFF'"
76  << exit(FatalError);
77  }
78 
79 
80  // get dimensions
81  label nPoints, nElems, nEdges;
82 
83  string line = this->getLineNoComment(is);
84  {
85  IStringStream lineStream(line);
86  lineStream >> nPoints >> nElems >> nEdges;
87  }
88 
89  // Read points
90  pointField pointLst(nPoints);
91  forAll(pointLst, pointI)
92  {
93  scalar x, y, z;
94  line = this->getLineNoComment(is);
95  {
96  IStringStream lineStream(line);
97  lineStream >> x >> y >> z;
98  }
99  pointLst[pointI] = point(x, y, z);
100  }
101 
102  // Read faces - ignore optional zone information
103  // use a DynamicList for possible on-the-fly triangulation
104  DynamicList<Face> dynFaces(nElems);
105 
106  for (label faceI = 0; faceI < nElems; ++faceI)
107  {
108  line = this->getLineNoComment(is);
109 
110  {
111  IStringStream lineStream(line);
112 
113  label nVerts;
114  lineStream >> nVerts;
115 
116  List<label> verts(nVerts);
117 
118  forAll(verts, vertI)
119  {
120  lineStream >> verts[vertI];
121  }
122 
123  labelUList& f = static_cast<labelUList&>(verts);
124 
125  if (mustTriangulate && f.size() > 3)
126  {
127  // simple face triangulation about f[0]
128  // cannot use face::triangulation (points may be incomplete)
129  for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
130  {
131  label fp2 = f.fcIndex(fp1);
132 
133  dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
134  }
135  }
136  else
137  {
138  dynFaces.append(Face(f));
139  }
140  }
141  }
142 
143  // transfer to normal lists, no zone information
144  this->reset(pointLst.xfer(), dynFaces.xfer(), Xfer<surfZoneList>());
145 
146  return true;
147 }
148 
149 
150 template<class Face>
152 (
153  const fileName& filename,
154  const MeshedSurfaceProxy<Face>& surf
155 )
156 {
157  const pointField& pointLst = surf.points();
158  const List<Face>& faceLst = surf.faces();
159  const List<label>& faceMap = surf.faceMap();
160  const List<surfZone>& zoneLst = surf.surfZones();
161 
162  OFstream os(filename);
163  if (!os.good())
164  {
166  (
167  "fileFormats::OFFsurfaceFormat::write"
168  "(const fileName&, const MeshedSurfaceProxy<Face>&)"
169  )
170  << "Cannot open file for writing " << filename
171  << exit(FatalError);
172  }
173 
174  // Write header
175  os << "OFF" << endl
176  << "# Geomview OFF file written " << clock::dateTime().c_str() << nl
177  << nl
178  << "# points : " << pointLst.size() << nl
179  << "# faces : " << faceLst.size() << nl
180  << "# zones : " << zoneLst.size() << nl;
181 
182  // Print zone names as comment
183  forAll(zoneLst, zoneI)
184  {
185  os << "# " << zoneI << " " << zoneLst[zoneI].name()
186  << " (nFaces: " << zoneLst[zoneI].size() << ")" << nl;
187  }
188 
189  os << nl
190  << "# nPoints nFaces nEdges" << nl
191  << pointLst.size() << ' ' << faceLst.size() << ' ' << 0 << nl
192  << nl
193  << "# <points count=\"" << pointLst.size() << "\">" << endl;
194 
195  // Write vertex coords
196  forAll(pointLst, ptI)
197  {
198  os << pointLst[ptI].x() << ' '
199  << pointLst[ptI].y() << ' '
200  << pointLst[ptI].z() << " #" << ptI << endl;
201  }
202 
203  os << "# </points>" << nl
204  << nl
205  << "# <faces count=\"" << faceLst.size() << "\">" << endl;
206 
207  label faceIndex = 0;
208  forAll(zoneLst, zoneI)
209  {
210  os << "# <zone name=\"" << zoneLst[zoneI].name() << "\">" << endl;
211 
212  if (surf.useFaceMap())
213  {
214  forAll(zoneLst[zoneI], localFaceI)
215  {
216  const Face& f = faceLst[faceMap[faceIndex++]];
217 
218  os << f.size();
219  forAll(f, fp)
220  {
221  os << ' ' << f[fp];
222  }
223 
224  // add optional zone information
225  os << ' ' << zoneI << endl;
226  }
227  }
228  else
229  {
230  forAll(zoneLst[zoneI], localFaceI)
231  {
232  const Face& f = faceLst[faceIndex++];
233 
234  os << f.size();
235  forAll(f, fp)
236  {
237  os << ' ' << f[fp];
238  }
239 
240  // add optional zone information
241  os << ' ' << zoneI << endl;
242  }
243  }
244  os << "# </zone>" << endl;
245  }
246  os << "# </faces>" << endl;
247 }
248 
249 
250 // ************************************************************************* //
Input from memory buffer stream.
Definition: IStringStream.H:49
Output to file stream.
Definition: OFstream.H:81
vector point
Point is a vector.
Definition: point.H:41
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
bool useFaceMap() const
Use faceMap?
labelList f(nPoints)
Xfer< List< T > > xfer()
Transfer contents to the Xfer container.
Definition: ListI.H:90
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats...
Definition: MeshedSurface.H:73
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
static void write(const fileName &, const MeshedSurfaceProxy< Face > &)
Write surface mesh components by proxy.
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
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:310
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Definition: UListI.H:58
face triFace(3)
const pointField & points() const
Return const access to the points.
Input from file stream.
Definition: IFstream.H:81
A line primitive.
Definition: line.H:56
const List< Face > & faces() const
Return const access to the faces.
static const char nl
Definition: Ostream.H:260
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
const List< surfZone > & surfZones() const
Const access to the surface zones.
virtual bool read(const fileName &)
Read from file.
Xfer< List< T > > xfer()
Transfer contents to the Xfer container as a plain List.
Definition: DynamicListI.H:301
#define forAll(list, i)
Definition: UList.H:421
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
error FatalError
scalar y
A class for handling file names.
Definition: fileName.H:69
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
const List< label > & faceMap() const
Const access to the faceMap, zero-sized when unused.
bool read(const char *, int32_t &)
Definition: int32IO.C:87
label nPoints
UEqn clear()
Provide a means of reading/writing Geomview OFF polyList format.