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 | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2016-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "OFFsurfaceFormat.H"
30#include "clock.H"
31#include "Fstream.H"
32#include "StringStream.H"
33#include "faceTraits.H"
34
35// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
36
37template<class Face>
39(
40 const fileName& filename
41)
42{
43 read(filename);
44}
45
46
47// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
48
49template<class Face>
51(
52 const fileName& filename
53)
54{
55 // Clear everything
56 this->clear();
57
58 IFstream is(filename);
59 if (!is.good())
60 {
62 << "Cannot read file " << filename << nl
63 << exit(FatalError);
64 }
65
66 // Read header
67 string hdr = this->getLineNoComment(is);
68 if (hdr != "OFF")
69 {
71 << "OFF file " << filename << " does not start with 'OFF'"
72 << exit(FatalError);
73 }
74
75
76 // get dimensions
77 label nPoints, nElems, nEdges;
78
79 string line = this->getLineNoComment(is);
80 {
81 IStringStream lineStream(line);
82 lineStream >> nPoints >> nElems >> nEdges;
83 }
84
85 // Read points
86 pointField pointLst(nPoints);
87 for (point& pt : pointLst)
88 {
89 scalar x, y, z;
90
91 line = this->getLineNoComment(is);
92 {
93 IStringStream lineStream(line);
94 lineStream >> x >> y >> z;
95 }
96
97 pt = point(x, y, z);
98 }
99
100 // Read faces - ignore optional zone information
101 // use a DynamicList for possible on-the-fly triangulation
102 DynamicList<Face> dynFaces(nElems);
103
104 for (label facei = 0; facei < nElems; ++facei)
105 {
106 line = this->getLineNoComment(is);
107
108 {
109 IStringStream lineStream(line);
110
111 label nVerts;
112 lineStream >> nVerts;
113
114 List<label> verts(nVerts);
115
116 forAll(verts, vertI)
117 {
118 lineStream >> verts[vertI];
119 }
120
121 const labelUList& f = static_cast<const labelUList&>(verts);
122
123 if (faceTraits<Face>::isTri() && f.size() > 3)
124 {
125 // simple face triangulation about f[0]
126 // cannot use face::triangulation (points may be incomplete)
127 for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
128 {
129 label fp2 = f.fcIndex(fp1);
130
131 dynFaces.append(Face{f[0], f[fp1], f[fp2]});
132 }
133 }
134 else
135 {
136 dynFaces.append(Face(f));
137 }
138 }
139 }
140
141 // Transfer to normal lists, no zone information
142 MeshedSurface<Face> surf(std::move(pointLst), std::move(dynFaces));
143
144 this->swap(surf);
145
146 return true;
147}
148
149
150template<class Face>
152(
153 const fileName& filename,
154 const MeshedSurfaceProxy<Face>& surf,
155 IOstreamOption streamOpt,
156 const dictionary&
157)
158{
159 // ASCII only, allow output compression
160 streamOpt.format(IOstream::ASCII);
161
162 const UList<point>& pointLst = surf.points();
163 const UList<Face>& faceLst = surf.surfFaces();
164 const UList<label>& faceMap = surf.faceMap();
165 const UList<surfZone>& zoneLst = surf.surfZones();
166
167 const bool useFaceMap = surf.useFaceMap();
168
169 OFstream os(filename, streamOpt);
170 if (!os.good())
171 {
173 << "Cannot write file " << filename << nl
174 << exit(FatalError);
175 }
176
177 // Write header
178 os << "OFF" << nl
179 << "# Geomview OFF file written " << clock::dateTime().c_str() << nl
180 << nl
181 << "# points : " << pointLst.size() << nl
182 << "# faces : " << faceLst.size() << nl
183 << "# zones : " << zoneLst.size() << nl;
184
185 // Print zone names as comment
186 forAll(zoneLst, zoneI)
187 {
188 os << "# " << zoneI << " " << zoneLst[zoneI].name()
189 << " (nFaces: " << zoneLst[zoneI].size() << ")" << nl;
190 }
191
192 os << nl
193 << "# nPoints nFaces nEdges" << nl
194 << pointLst.size() << ' ' << faceLst.size() << ' ' << 0 << nl
195 << nl
196 << "# <points count=\"" << pointLst.size() << "\">" << nl;
197
198 // Write vertex coords
199 forAll(pointLst, ptI)
200 {
201 os << pointLst[ptI].x() << ' '
202 << pointLst[ptI].y() << ' '
203 << pointLst[ptI].z() << " #" << ptI << nl;
204 }
205
206 os << "# </points>" << nl
207 << nl
208 << "# <faces count=\"" << faceLst.size() << "\">" << nl;
209
210 label faceIndex = 0;
211 label zoneIndex = 0;
212
213 for (const surfZone& zone : zoneLst)
214 {
215 os << "# <zone name=\"" << zone.name() << "\">" << nl;
216
217 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
218 {
219 const label facei =
220 (useFaceMap ? faceMap[faceIndex] : faceIndex);
221
222 const Face& f = faceLst[facei];
223
224 os << f.size();
225 for (const label verti : f)
226 {
227 os << ' ' << verti;
228 }
229
230 // Add optional zone information
231 os << ' ' << zoneIndex << nl;
232 }
233
234 os << "# </zone>" << nl;
235 ++zoneIndex;
236 }
237
238 os << "# </faces>" << nl;
239}
240
241
242// ************************************************************************* //
scalar y
Input/output from string buffers.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:503
Input from file stream, using an ISstream.
Definition: IFstream.H:57
The IOstreamOption is a simple container for options an IOstream can normally have.
streamFormat format() const noexcept
Get the current stream format.
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
Definition: StringStream.H:112
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
const UList< surfZone > & surfZones() const
Const access to the surface zones.
const UList< Face > & surfFaces() const
Return const access to the faces.
bool useFaceMap() const
Can/should use faceMap?
const pointField & points() const
Return const access to the points.
const labelUList & faceMap() const
Const access to the faceMap, zero-sized when unused.
A surface geometry mesh with zone information, not to be confused with the similarly named surfaceMes...
Definition: MeshedSurface.H:99
Output to file stream, using an OSstream.
Definition: OFstream.H:57
virtual bool read()
Re-read model coefficients if they have changed.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Traits class for faces.
Definition: faceTraits.H:51
Read/write Geomview OFF polyList format.
A class for handling file names.
Definition: fileName.H:76
virtual bool write()
Write the output fields.
A line primitive.
Definition: line.H:68
A surface zone on a MeshedSurface.
Definition: surfZone.H:59
const word & name() const noexcept
The zone name.
Base class for mesh zones.
Definition: zone.H:67
patchWriters clear()
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
const labelList nEdges(UPstream::listGatherValues< label >(aMesh.nEdges()))
label nPoints
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333