Loading...
Searching...
No Matches
triSurfaceLoader.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-2024 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 "triSurfaceLoader.H"
29#include "fileNameList.H"
30#include "Time.H"
31#include "OSspecific.H"
32
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35const Foam::Enum
36<
38>
40({
41 { loadingOption::SINGLE_REGION, "single" },
42 { loadingOption::FILE_REGION, "file" },
44 { loadingOption::MERGE_REGION, "merge" },
45});
46
47
48// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49
50Foam::triSurfaceLoader::triSurfaceLoader(const fileName& directory)
51:
52 directory_(directory),
53 available_(),
54 selected_()
55{
56 readDir();
57}
58
59
60Foam::triSurfaceLoader::triSurfaceLoader(const Time& runTime)
61:
62 directory_(runTime.constantPath()/"triSurface"),
63 available_(),
64 selected_()
66 readDir();
67}
68
69
70// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
71
73{
74 fileNameList files = Foam::readDir(directory_, fileName::FILE);
75
76 // Will be using triSurface
77 //
78 // - filter according to what is supported
79 //
80 // Transform from fileName to word and eliminate duplicates
81 // (eg, files with/without .gz)
82 wordHashSet names(2*files.size());
83
84 for (const fileName& f : files)
85 {
87 {
88 names.insert(f.name());
89 }
90 }
91 available_ = names.sortedToc();
92
93 return available_.size();
94}
95
96
98{
99 selected_ = available_;
100 return selected_.size();
101}
102
103
104Foam::label Foam::triSurfaceLoader::select(const word& name)
105{
106 if (available_.found(name))
107 {
108 selected_.resize(1);
109 selected_.front() = name;
110 }
111 else
112 {
113 selected_.clear();
114 }
115
116 return selected_.size();
117}
118
119
120Foam::label Foam::triSurfaceLoader::select(const wordRe& mat)
121{
122 if (mat.isPattern())
123 {
124 labelList foundIds = wordRes::matching(mat, available_);
125 Foam::sort(foundIds);
126 selected_ = wordList(available_, foundIds);
127 }
128 else if (available_.found(static_cast<const word&>(mat)))
129 {
130 selected_.resize(1);
131 selected_.front() = mat;
132 }
133 else
134 {
136 << "Specified the surfaces " << mat << nl
137 << " - but could not find it"
139 }
140
141 return selected_.size();
142}
143
144
145Foam::label Foam::triSurfaceLoader::select(const UList<wordRe>& matcher)
146{
147 // Need to be more careful when select.
148 // - preserve same order as the input matcher itself
149 // - avoid duplicate selections
150 // - flag explicitly named files as missing.
151 // (Eg, foo.stl must exist, but "foo.*\.stl" is optional)
152
153 // Track which files have already been selected
154 DynamicList<label> foundIds(available_.size());
155 labelHashSet hashedFound(2*available_.size());
156
157 DynamicList<word> missing(matcher.size());
158 wordHashSet hashedMissing(2*matcher.size());
159
160 // Exact matches must exist
161 for (const wordRe& mat : matcher)
162 {
163 if (mat.isPattern())
164 {
165 labelList indices = wordRes::matching(mat, available_);
166 Foam::sort(indices);
167
168 for (const label idx : indices)
169 {
170 if (hashedFound.insert(idx))
171 {
172 foundIds.append(idx);
173 }
174 }
175 }
176 else
177 {
178 const word& plain = mat;
179 const label idx = available_.find(plain);
180
181 if (idx >= 0)
182 {
183 if (hashedFound.insert(idx))
184 {
185 foundIds.append(idx);
186 }
187 }
188 else if (hashedMissing.insert(plain))
189 {
190 missing.append(plain);
191 }
192 }
193 }
194
195 if (missing.size())
196 {
198 << "Specified the surfaces " << flatOutput(matcher) << nl
199 << " - but could not find " << flatOutput(missing)
200 << exit(FatalError);
202
203 selected_ = wordList(available_, foundIds);
204 return selected_.size();
205}
206
207
209(
210 const enum loadingOption opt,
211 const scalar scaleFactor
212) const
213{
214 autoPtr<triSurface> output;
215
216 if (selected_.empty())
217 {
218 return output;
219 }
220 else if (selected_.size() == 1)
221 {
222 // Use scaling (if any)
223 output.reset(new triSurface(directory_/selected_[0], scaleFactor));
224
225 triSurface& surf = output();
226
227 if
228 (
229 opt == loadingOption::SINGLE_REGION
230 || opt == loadingOption::FILE_REGION
231 )
232 {
233 for (labelledTri& f : surf)
234 {
235 f.region() = 0;
236 }
237
238 if (surf.patches().size())
239 {
240 surf.patches().resize(1);
241 }
242 else
243 {
244 surf.patches().append
245 (
246 geometricSurfacePatch(selected_[0].lessExt(), 0)
247 );
248 }
249 }
250
251 return output;
252 }
253
254
255 List<labelledTri> faces;
257
258 Map<label> oldToNew;
259 HashTable<label> patchNameLookup;
260 DynamicList<geometricSurfacePatch> patches(16*selected_.size());
261
262 forAll(selected_, surfi)
263 {
264 List<labelledTri> addfaces;
265 pointField addpoints;
266
267 triSurface addsurf(directory_/selected_[surfi]);
268
269 addsurf.swapFaces(addfaces);
270 addsurf.swapPoints(addpoints);
271
272 // Offset the points for all additional surfaces
273 if (surfi)
274 {
275 const label ptoff = points.size();
276
277 for (labelledTri& f : addfaces)
278 {
279 forAll(f, fi)
280 {
281 f[fi] += ptoff;
282 }
283 }
284 }
285
286 switch (opt)
287 {
288 case loadingOption::SINGLE_REGION:
289 {
290 for (labelledTri& f : addfaces)
291 {
292 f.region() = 0;
293 }
294
295 if (patches.empty() && !addsurf.patches().empty())
296 {
297 patches.append(addsurf.patches().first());
298 }
299
300 break;
301 }
302
303 case loadingOption::FILE_REGION:
304 {
305 for (labelledTri& f : addfaces)
306 {
307 f.region() = surfi;
308 }
309
310 // Use surface name for region
312 (
313 geometricSurfacePatch(selected_[surfi].lessExt(), surfi)
314 );
315
316 break;
317 }
318
319 case loadingOption::OFFSET_REGION:
320 {
321 // Collect all patches, preserving names.
322 // This will be horrible for output, but is good if we rely
323 // on the names for defining baffles.
324
325 // region offset
326 const label regoff = patches.size();
327 patches.append(addsurf.patches());
328
329 if (surfi)
330 {
331 for (labelledTri& f : addfaces)
332 {
333 f.region() += regoff;
334 }
335 }
336 break;
337 }
338
339 case loadingOption::MERGE_REGION:
340 {
341 // Merge by name
342 geometricSurfacePatchList& addpatches = addsurf.patches();
343
344 // Build lookup tables with name->id and localId -> mergedId
345 oldToNew.clear();
346 forAll(addpatches, patchi)
347 {
348 geometricSurfacePatch& p = addpatches[patchi];
349 const word& patchName = p.name();
350
351 label patchId = patches.size();
352 if (patchNameLookup.insert(patchName, patchId))
353 {
354 p.index() = patchId;
356 }
357 else
358 {
359 patchId = patchNameLookup[patchName];
360 }
361
362 oldToNew.insert(patchi, patchId);
363 }
364
365 if (surfi)
366 {
367 // Relabel regions accordingly
368 for (labelledTri& f : addfaces)
369 {
370 f.region() = oldToNew[f.region()];
371 }
372 }
373 break;
374 }
375 }
376
377 if (surfi)
378 {
379 faces.append(addfaces);
380 points.append(addpoints);
381 }
382 else
383 {
384 faces.transfer(addfaces);
385 points.transfer(addpoints);
386 }
387 }
388
389 // Apply scaling (if any)
390 if (scaleFactor > VSMALL)
391 {
392 points *= scaleFactor;
393 }
394
395 output.reset(new triSurface(faces, patches, points, true));
396
397 return output;
398}
399
400
401// ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void append(const T &val)
Copy append an element to the end of this list.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition Enum.H:57
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition HashSet.H:229
A HashTable similar to std::unordered_map.
Definition HashTable.H:124
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition HashTableI.H:152
void clear()
Remove all entries from table.
Definition HashTable.C:742
const word & name() const noexcept
Return the object name.
Definition IOobjectI.H:205
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition List.C:347
void append(const T &val)
Append an element at the end of the list.
Definition List.H:497
A HashTable to objects of type <T> with a label key.
Definition Map.H:54
void append(autoPtr< T > &ptr)
Move append an element to the end of the list.
Definition PtrList.H:364
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
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:89
T & first()
Access first element of the list, position [0].
Definition UList.H:957
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition UPtrListI.H:99
label size() const noexcept
The number of entries in the list.
Definition UPtrListI.H:106
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition autoPtrI.H:37
A class for handling file names.
Definition fileName.H:75
@ FILE
A regular file.
Definition fileName.H:84
Identifies a surface patch/zone by name and index, with geometric type.
A triFace with additional (region) index.
Definition labelledTri.H:56
static const Enum< loadingOption > loadingOptionNames
The loading enumeration names.
autoPtr< triSurface > load(const enum loadingOption opt=loadingOption::OFFSET_REGION, const scalar scaleFactor=-1) const
Load a single file, or load and combine multiple selected files.
label readDir()
Read directory and populate the 'available' files.
label selectAll()
Populates 'selected' with all available files.
label select(const word &name)
Populates 'selected' with a subset of the available files.
const fileName & directory() const noexcept
The directory being used.
loadingOption
The file loading options for triSurfaceLoader.
@ FILE_REGION
"file" = One region for each file
@ MERGE_REGION
"merge" = Merge regions by name
@ OFFSET_REGION
"offset" = Offset regions per file
@ SINGLE_REGION
"single" = One region for all files
Triangulated surface description with patch information.
Definition triSurface.H:74
const geometricSurfacePatchList & patches() const noexcept
Definition triSurface.H:509
virtual void swapPoints(pointField &pts)
Swap points. Similar to movePoints, but returns the old points.
Definition triSurface.C:619
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
void swapFaces(List< labelledTri > &faceLst)
Swap the list of faces being addressed.
Definition triSurface.C:947
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition wordRe.H:81
bool isPattern() const noexcept
The wordRe is a pattern, not a literal string.
Definition wordReI.H:104
static labelList matching(const wordRe &select, const UList< StringType > &input, const bool invert=false)
Determine the list indices for all matches.
A class for handling words, derived from Foam::string.
Definition word.H:66
volScalarField & p
const polyBoundaryMesh & patches
engineTime & runTime
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
auto & names
const pointField & points
label patchId(-1)
List< word > wordList
List of word.
Definition fileName.H:60
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
Definition HashSet.H:80
List< label > labelList
A List of labels.
Definition List.H:62
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition HashSet.H:85
List< fileName > fileNameList
List of fileName.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition FlatOutput.H:217
void sort(UList< T > &list)
Sort the list.
Definition UList.C:283
List< geometricSurfacePatch > geometricSurfacePatchList
List of geometricSurfacePatch.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
fileNameList readDir(const fileName &directory, const fileName::Type type=fileName::Type::FILE, const bool filtergz=true, const bool followLink=true)
Read a directory and return the entries as a fileName List.
Definition POSIX.C:965
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299