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 -------------------------------------------------------------------------------
10 License
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 
47 bool 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 
109 void 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 
209 void 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 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
STLReader.H
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::surfacePatchList
List< surfacePatch > surfacePatchList
A List of surfacePatch.
Definition: surfacePatchList.H:47
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::fileFormats::STLCore::BINARY
BINARY.
Definition: STLCore.H:64
STLCore.H
triSurface.H
Foam::polyBoundaryMesh::start
label start() const
The start label of the boundary faces in the polyMesh face list.
Definition: polyBoundaryMesh.C:611
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::STLtriangle::write
void write(std::ostream &os) const
Write to ostream (binary)
Definition: STLtriangleI.H:99
faceNormals
surfaceVectorField faceNormals(mesh.Sf()/mesh.magSf())
Foam::fileFormats::STLCore::writeBinaryHeader
static void writeBinaryHeader(ostream &os, uint32_t nTris)
Write STL binary file and number of triangles to stream.
Definition: STLCore.C:227
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::sort
void sort(UList< T > &a)
Definition: UList.C:261
triSurfaceSTLCore
Definition: triSurfaceSTLformat.C:37
Foam::triSurface::storedPoints
pointField & storedPoints()
Non-const access to global points.
Definition: triSurface.H:189
Foam::FatalError
error FatalError
os
OBJstream os(runTime.globalPath()/outputName)
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::fileFormats::STLCore::ASCII
ASCII.
Definition: STLCore.H:63
Foam::IOobject::name
const word & name() const noexcept
Return name.
Definition: IOobjectI.H:65
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Fstream.H
Foam::fileFormats::STLCore
Core routines used when reading/writing STL files.
Definition: STLCore.H:54
f
labelList f(nPoints)
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::triSurface::storedFaces
List< labelledTri > & storedFaces()
Non-const access to the faces.
Definition: triSurface.H:195
points
const pointField & points
Definition: gmvOutputHeader.H:1
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:36
Foam::PtrListOps::names
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Foam::fileFormats::STLCore::UNKNOWN
Detect based on (input) content or (output) extension.
Definition: STLCore.H:65