triSurfaceSTLformat.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) 2017-2020 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "STLCore.H"
29#include "STLReader.H"
30#include "Fstream.H"
31#include "triSurface.H"
32
33// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
34
35// A file-scope helper class to expose static member(s)
36// This is a temporary measure and is expected to disappear in the future
38:
40{
42};
43
44
45// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
46
47bool Foam::triSurface::readSTL(const fileName& filename, bool forceBinary)
48{
49 // Read in the values
50 fileFormats::STLReader reader
51 (
52 filename,
53 (
54 forceBinary
57 )
58 );
59
60 // Get the map for stitched surface points, with merge tolerance depending
61 // on the input format
62 labelList pointMap;
63 const label nUniquePoints = reader.mergePointsMap(pointMap);
64
65 const auto& readpts = reader.points();
66 const labelList& zoneIds = reader.zoneIds();
67
68 pointField& pointLst = storedPoints();
69 List<face_type>& faceLst = storedFaces();
70
71 // Sizing
72 pointLst.setSize(nUniquePoints);
73 faceLst.setSize(zoneIds.size());
74
75 // Assign points
76 forAll(readpts, pointi)
77 {
78 pointLst[pointMap[pointi]] = readpts[pointi];
79 }
80
81 // Assign triangles
82 label pointi = 0;
83 forAll(faceLst, facei)
84 {
85 auto& f = faceLst[facei];
86
87 f[0] = pointMap[pointi++];
88 f[1] = pointMap[pointi++];
89 f[2] = pointMap[pointi++];
90 f.region() = zoneIds[facei];
91 }
92
93 // Set patch name/index.
94 if (reader.stlFormat() == fileFormats::STLCore::ASCII)
95 {
96 const List<word>& names = reader.names();
97
98 patches_.setSize(names.size());
99 forAll(patches_, patchi)
100 {
101 patches_[patchi] = geometricSurfacePatch(names[patchi], patchi);
102 }
103 }
104
105 return true;
106}
107
108
109void Foam::triSurface::writeSTLASCII
110(
111 const fileName& filename,
112 const bool sort
113) const
114{
115 OFstream os(filename);
116 if (!os.good())
117 {
119 << "Cannot write file " << filename << nl
120 << exit(FatalError);
121 }
122
124 surfacePatchList patches(calcPatches(faceMap));
125
126 if (sort)
127 {
128 label faceIndex = 0;
129 forAll(patches, patchi)
130 {
131 // Print all faces belonging to this region
132 const surfacePatch& patch = patches[patchi];
133
134 os << "solid " << patch.name() << endl;
135
136 for
137 (
138 label patchFacei = 0;
139 patchFacei < patch.size();
140 ++patchFacei
141 )
142 {
143 const label facei = faceMap[faceIndex++];
144 const labelledTri& f = (*this)[facei];
145
146 // Write ASCII
148 (
149 os,
150 faceNormals()[facei],
151 points()[f[0]],
152 points()[f[1]],
153 points()[f[2]]
154 );
155 }
156
157 os << "endsolid " << patch.name() << endl;
158 }
159
160 return;
161 }
162
163 // Get patch (=compact region) per face
164 labelList patchIDs(size());
165 forAll(patches, patchi)
166 {
167 label facei = patches[patchi].start();
168
169 forAll(patches[patchi], i)
170 {
171 patchIDs[faceMap[facei++]] = patchi;
172 }
173 }
174
175 label currentPatchi = -1;
176 forAll(*this, facei)
177 {
178 if (currentPatchi != patchIDs[facei])
179 {
180 if (currentPatchi != -1)
181 {
182 // Close previous solid
183 os << "endsolid " << patches[currentPatchi].name() << nl;
184 }
185 currentPatchi = patchIDs[facei];
186 os << "solid " << patches[currentPatchi].name() << nl;
187 }
188
189 const labelledTri& f = (*this)[facei];
190
191 // Write ASCII
193 (
194 os,
195 faceNormals()[facei],
196 points()[f[0]],
197 points()[f[1]],
198 points()[f[2]]
199 );
200 }
201
202 if (currentPatchi != -1)
203 {
204 os << "endsolid " << patches[currentPatchi].name() << nl;
205 }
206}
207
208
209void Foam::triSurface::writeSTLBINARY(const fileName& filename) const
210{
211 std::ofstream os(filename, std::ios::binary);
212
213 // Write the STL header
215
216 forAll(*this, facei)
217 {
218 const labelledTri& f = (*this)[facei];
219
220 // Write BINARY
221 STLtriangle
222 (
223 faceNormals()[facei],
224 points()[f[0]],
225 points()[f[1]],
226 points()[f[2]],
227 f.region()
228 ).write(os);
229 }
230}
231
232
233// ************************************************************************* //
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:65
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
void setSize(const label n)
Alias for resize()
Definition: List.H:218
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Ostream & writeBinaryHeader()
Write "C Binary" string for binary files (eg, geometry/measured)
Definition: ensightFile.C:339
Core routines used when reading/writing STL files.
Definition: STLCore.H:55
@ UNKNOWN
Detect based on (input) content or (output) extension.
Definition: STLCore.H:65
virtual bool write()
Write the output fields.
label start() const noexcept
The start label of boundary faces in the polyMesh face list.
pointField & storedPoints()
Non-const access to global points.
Definition: triSurface.H:189
List< labelledTri > & storedFaces()
Non-const access to the faces.
Definition: triSurface.H:195
const polyBoundaryMesh & patches
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
surfaceVectorField faceNormals(mesh.Sf()/mesh.magSf())
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
const std::string patch
OpenFOAM patch number as a std::string.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
List< label > labelList
A List of labels.
Definition: List.H:66
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:342
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
List< surfacePatch > surfacePatchList
A List of surfacePatch.
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