OFFsurfaceFormat.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2019 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  << "Cannot read file " << filename
61  << exit(FatalError);
62  }
63 
64  // Read header
65  string hdr = this->getLineNoComment(is);
66  if (hdr != "OFF")
67  {
69  << "OFF file " << filename << " does not start with 'OFF'"
70  << exit(FatalError);
71  }
72 
73 
74  // get dimensions
75  label nPoints, nElems, nEdges;
76 
77  string line = this->getLineNoComment(is);
78  {
79  IStringStream lineStream(line);
80  lineStream >> nPoints >> nElems >> nEdges;
81  }
82 
83  // Read points
84  pointField pointLst(nPoints);
85  forAll(pointLst, pointi)
86  {
87  scalar x, y, z;
88  line = this->getLineNoComment(is);
89  {
90  IStringStream lineStream(line);
91  lineStream >> x >> y >> z;
92  }
93  pointLst[pointi] = point(x, y, z);
94  }
95 
96  // Read faces - ignore optional zone information
97  // use a DynamicList for possible on-the-fly triangulation
98  DynamicList<Face> dynFaces(nElems);
99 
100  for (label facei = 0; facei < nElems; ++facei)
101  {
102  line = this->getLineNoComment(is);
103 
104  {
105  IStringStream lineStream(line);
106 
107  label nVerts;
108  lineStream >> nVerts;
109 
110  List<label> verts(nVerts);
111 
112  forAll(verts, vertI)
113  {
114  lineStream >> verts[vertI];
115  }
116 
117  labelUList& f = static_cast<labelUList&>(verts);
118 
119  if (mustTriangulate && f.size() > 3)
120  {
121  // simple face triangulation about f[0]
122  // cannot use face::triangulation (points may be incomplete)
123  for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
124  {
125  label fp2 = f.fcIndex(fp1);
126 
127  dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
128  }
129  }
130  else
131  {
132  dynFaces.append(Face(f));
133  }
134  }
135  }
136 
137  // transfer to normal lists, no zone information
138  this->reset(move(pointLst), move(dynFaces), NullObjectMove<surfZoneList>());
139 
140  return true;
141 }
142 
143 
144 template<class Face>
146 (
147  const fileName& filename,
148  const MeshedSurfaceProxy<Face>& surf
149 )
150 {
151  const pointField& pointLst = surf.points();
152  const List<Face>& faceLst = surf.faces();
153  const List<label>& faceMap = surf.faceMap();
154  const List<surfZone>& zoneLst = surf.surfZones();
155 
156  OFstream os(filename);
157  if (!os.good())
158  {
160  << "Cannot open file for writing " << filename
161  << exit(FatalError);
162  }
163 
164  // Write header
165  os << "OFF" << endl
166  << "# Geomview OFF file written " << clock::dateTime().c_str() << nl
167  << nl
168  << "# points : " << pointLst.size() << nl
169  << "# faces : " << faceLst.size() << nl
170  << "# zones : " << zoneLst.size() << nl;
171 
172  // Print zone names as comment
173  forAll(zoneLst, zoneI)
174  {
175  os << "# " << zoneI << " " << zoneLst[zoneI].name()
176  << " (nFaces: " << zoneLst[zoneI].size() << ")" << nl;
177  }
178 
179  os << nl
180  << "# nPoints nFaces nEdges" << nl
181  << pointLst.size() << ' ' << faceLst.size() << ' ' << 0 << nl
182  << nl
183  << "# <points count=\"" << pointLst.size() << "\">" << endl;
184 
185  // Write vertex coords
186  forAll(pointLst, ptI)
187  {
188  os << pointLst[ptI].x() << ' '
189  << pointLst[ptI].y() << ' '
190  << pointLst[ptI].z() << " #" << ptI << endl;
191  }
192 
193  os << "# </points>" << nl
194  << nl
195  << "# <faces count=\"" << faceLst.size() << "\">" << endl;
196 
197  label faceIndex = 0;
198  forAll(zoneLst, zoneI)
199  {
200  os << "# <zone name=\"" << zoneLst[zoneI].name() << "\">" << endl;
201 
202  if (surf.useFaceMap())
203  {
204  forAll(zoneLst[zoneI], localFacei)
205  {
206  const Face& f = faceLst[faceMap[faceIndex++]];
207 
208  os << f.size();
209  forAll(f, fp)
210  {
211  os << ' ' << f[fp];
212  }
213 
214  // add optional zone information
215  os << ' ' << zoneI << endl;
216  }
217  }
218  else
219  {
220  forAll(zoneLst[zoneI], localFacei)
221  {
222  const Face& f = faceLst[faceIndex++];
223 
224  os << f.size();
225  forAll(f, fp)
226  {
227  os << ' ' << f[fp];
228  }
229 
230  // add optional zone information
231  os << ' ' << zoneI << endl;
232  }
233  }
234  os << "# </zone>" << endl;
235  }
236  os << "# </faces>" << endl;
237 }
238 
239 
240 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
tUEqn clear()
A line primitive.
Definition: line.H:56
A class for handling file names.
Definition: fileName.H:79
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
Output to file stream.
Definition: OFstream.H:82
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Definition: UListI.H:58
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
static void write(const fileName &, const MeshedSurfaceProxy< Face > &)
Write surface mesh components by proxy.
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:330
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
scalar y
bool useFaceMap() const
Use faceMap?
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
const List< Face > & faces() const
Return const access to the faces.
label nPoints
face triFace(3)
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
const List< surfZone > & surfZones() const
Const access to the surface zones.
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
virtual bool read(const fileName &)
Read from file.
static const char nl
Definition: Ostream.H:260
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats...
Definition: MeshedSurface.H:73
Input from file stream.
Definition: IFstream.H:81
labelList f(nPoints)
vector point
Point is a vector.
Definition: point.H:41
OFFsurfaceFormat(const fileName &)
Construct from file name.
const pointField & points() const
Return const access to the points.
const List< label > & faceMap() const
Const access to the faceMap, zero-sized when unused.
Input from memory buffer stream.
Definition: IStringStream.H:49
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311