TRIsurfaceFormat.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 "TRIsurfaceFormat.H"
30#include "TRIReader.H"
31#include "OFstream.H"
32#include "ListOps.H"
33
34// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35
36template<class Face>
38(
39 Ostream& os,
40 const UList<point>& pts,
41 const Face& f,
42 const label zoneI
43)
44{
45 // simple triangulation about f[0].
46 // better triangulation should have been done before
47 const point& p0 = pts[f[0]];
48 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
49 {
50 const label fp2 = f.fcIndex(fp1);
51
52 const point& p1 = pts[f[fp1]];
53 const point& p2 = pts[f[fp2]];
54
55 os << p0.x() << ' ' << p0.y() << ' ' << p0.z() << ' '
56 << p1.x() << ' ' << p1.y() << ' ' << p1.z() << ' '
57 << p2.x() << ' ' << p2.y() << ' ' << p2.z() << ' '
58 // zone as colour
59 << "0x" << hex << zoneI << dec << nl;
60 }
61}
62
63
64// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
65
66template<class Face>
68(
69 const fileName& filename
70)
71{
72 read(filename);
73}
74
75
76// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
77
78template<class Face>
80(
81 const fileName& filename
82)
83{
84 // Clear everything
85 this->clear();
86
87 // Read in the values
88 TRIReader reader(filename);
89
90 // Get the map for stitched surface points
91 labelList pointMap;
92 const label nUniquePoints = reader.mergePointsMap(pointMap);
93
94 const auto& readpts = reader.points();
95
96 // Assign points
97 pointField& pointLst = this->storedPoints();
98 pointLst.setSize(nUniquePoints);
99 forAll(readpts, pointi)
100 {
101 pointLst[pointMap[pointi]] = readpts[pointi];
102 }
103
104 // Retrieve the original zone information
105 List<label> sizes(std::move(reader.sizes()));
106 List<label> zoneIds(std::move(reader.zoneIds()));
107
108 // Generate the (sorted) faces
109 List<Face> faceLst(zoneIds.size());
110
111 if (reader.sorted())
112 {
113 // Already sorted - generate directly
114 forAll(faceLst, facei)
115 {
116 const label startPt = 3*facei;
117 faceLst[facei] = Face
118 {
119 pointMap[startPt],
120 pointMap[startPt+1],
121 pointMap[startPt+2]
122 };
123 }
124 }
125 else
126 {
127 // Determine the sorted order:
128 // use sortedOrder directly (the intermediate list is discared anyhow)
129 labelList faceMap(sortedOrder(zoneIds));
130
131 // Generate sorted faces
132 forAll(faceMap, facei)
133 {
134 const label startPt = 3*faceMap[facei];
135 faceLst[facei] = Face
136 {
137 pointMap[startPt],
138 pointMap[startPt+1],
139 pointMap[startPt+2]
140 };
141 }
142 }
143 zoneIds.clear();
144
145 // Transfer
146 this->storedFaces().transfer(faceLst);
147
148 this->addZones(sizes);
149 this->addZonesToFaces(); // for labelledTri
150
151 return true;
152}
153
154
155template<class Face>
157(
158 const fileName& filename,
159 const MeshedSurfaceProxy<Face>& surf,
160 IOstreamOption streamOpt,
161 const dictionary&
162)
163{
164 // ASCII only, allow output compression
165 streamOpt.format(IOstream::ASCII);
166
167 const UList<point>& pointLst = surf.points();
168 const UList<Face>& faceLst = surf.surfFaces();
169 const UList<label>& faceMap = surf.faceMap();
170
171 const surfZoneList zones =
172 (
173 surf.surfZones().empty()
174 ? surfaceFormatsCore::oneZone(faceLst)
175 : surf.surfZones()
176 );
177
178 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
179
180 OFstream os(filename, streamOpt);
181 if (!os.good())
182 {
184 << "Cannot write file " << filename << nl
185 << exit(FatalError);
186 }
187
188 label faceIndex = 0;
189 label zoneIndex = 0;
190 for (const surfZone& zone : zones)
191 {
192 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
193 {
194 const label facei =
195 (useFaceMap ? faceMap[faceIndex] : faceIndex);
196
197 const Face& f = faceLst[facei];
198
199 writeShell(os, pointLst, f, zoneIndex);
200 }
201
202 ++zoneIndex;
203 }
204}
205
206
207template<class Face>
209(
210 const fileName& filename,
211 const UnsortedMeshedSurface<Face>& surf,
212 IOstreamOption streamOpt,
213 const dictionary&
214)
215{
216 // ASCII only, allow output compression
217 streamOpt.format(IOstream::ASCII);
218
219 const UList<point>& pointLst = surf.points();
220 const UList<Face>& faceLst = surf.surfFaces();
221
222 OFstream os(filename, streamOpt);
223 if (!os.good())
224 {
226 << "Cannot write file " << filename << nl
227 << exit(FatalError);
228 }
229
230 // A single zone needs no sorting
231 if (surf.zoneToc().size() == 1)
232 {
233 const UList<label>& zoneIds = surf.zoneIds();
234
235 forAll(faceLst, facei)
236 {
237 writeShell(os, pointLst, faceLst[facei], zoneIds[facei]);
238 }
239 }
240 else
241 {
243 List<surfZone> zoneLst = surf.sortedZones(faceMap);
244
245 label faceIndex = 0;
246 label zoneIndex = 0;
247
248 for (const surfZone& zone : zoneLst)
249 {
250 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
251 {
252 const label facei = faceMap[faceIndex];
253
254 const Face& f = faceLst[facei];
255
256 writeShell(os, pointLst, f, zoneIndex);
257 }
258
259 ++zoneIndex;
260 }
261 }
262}
263
264
265// ************************************************************************* //
Various functions to operate on Lists.
The IOstreamOption is a simple container for options an IOstream can normally have.
streamFormat format() const noexcept
Get the current stream format.
void setSize(const label n)
Alias for resize()
Definition: List.H:218
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
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.
const List< Face > & surfFaces() const
Return const access to the faces.
Output to file stream, using an OSstream.
Definition: OFstream.H:57
const Field< point_type > & points() const noexcept
Return reference to global points.
virtual bool read()
Re-read model coefficients if they have changed.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A surface geometry mesh, in which the surface zone information is conveyed by the 'zoneId' associated...
surfZoneList sortedZones(labelList &faceMap) const
Sort faces according to zoneIds.
virtual const labelList & zoneIds() const
Return const access to the zone ids.
const List< surfZoneIdentifier > & zoneToc() const
Return const access to the zone table-of-contents.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
TRI (triangle) file reader.
Definition: TRIReader.H:64
label mergePointsMap(labelList &pointMap) const
Calculate merge points mapping, return old to new pointMap.
Definition: TRIReader.C:195
bool sorted() const
File read was already sorted.
Definition: TRIReader.H:115
List< STLpoint > & points()
Return full access to the points.
Definition: TRIReader.H:121
List< label > & sizes()
The list of zone sizes in the order of their first appearance.
Definition: TRIReader.H:139
List< label > & zoneIds()
Return full access to the zones.
Definition: TRIReader.H:127
Provide a means of reading/writing .tri format.
A class for handling file names.
Definition: fileName.H:76
virtual bool write()
Write the output fields.
A surface zone on a MeshedSurface.
Definition: surfZone.H:59
Base class for mesh zones.
Definition: zone.H:67
const volScalarField & p0
Definition: EEqn.H:36
patchWriters clear()
const cellModel & hex
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
vector point
Point is a vector.
Definition: point.H:43
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
IOstream & dec(IOstream &io)
Definition: IOstream.H:440
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