mergeSurfacePatches.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | cfMesh: A library for mesh generation
4  \\ / O peration |
5  \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6  \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of cfMesh.
10 
11  cfMesh is free software; you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by the
13  Free Software Foundation; either version 3 of the License, or (at your
14  option) any later version.
15 
16  cfMesh is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25  cfMesh utility to merge the supplied list of patches onto a single
26  patch.
27 
28 Author
29  Ivor Clifford <ivor.clifford@psi.ch>
30 
31 \*---------------------------------------------------------------------------*/
32 
33 #include "argList.H"
34 #include "autoPtr.H"
35 #include "triSurf.H"
36 #include "triSurfModifier.H"
37 #include "demandDrivenData.H"
38 #include "Pair.H"
39 
40 using namespace Foam;
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
44 // Find the supplied list of patch names and return a list of patch Ids
45 void getPatchIds
46 (
47  const triSurf& origSurf,
48  const wordList& patchNames,
49  DynamicList<label>& patchIds
50 )
51 {
52  const geometricSurfacePatchList& origPatches = origSurf.patches();
53 
54  // Create patch name map
55  HashSet<word> patchNameHash(patchNames);
56 
57  // Find selected patches
58  label nFound = 0;
59  forAll(origPatches, patchI)
60  {
61  if (patchNameHash.found(origPatches[patchI].name()))
62  {
63  patchIds.append(patchI);
64  nFound++;
65  }
66  }
67 
68  if (nFound != patchNames.size())
69  {
70  WarningIn("getPatchIds")
71  << "Not all supplied patch names were found on the surface mesh" << endl;
72  }
73 }
74 
75 
76 // Copy all face subsets from one triSurf to another
77 void copyFaceSubsets
78 (
79  const triSurf& origSurf,
80  triSurf& newSurf
81 )
82 {
83  DynList<label> subsetIds;
84  origSurf.facetSubsetIndices(subsetIds);
85 
86  forAll(subsetIds, subsetI)
87  {
88  label newSubsetId = newSurf.addFacetSubset
89  (
90  origSurf.facetSubsetName(subsetI)
91  );
92 
93  labelList origFaces;
94  origSurf.facetsInSubset(subsetI, origFaces);
95 
96  forAll(origFaces, faceI)
97  {
98  newSurf.addFacetToSubset
99  (
100  newSubsetId,
101  origFaces[faceI]
102  );
103  }
104  }
105 }
106 
107 
108 // Copy all edge subsets from one triSurf to another
109 void copyEdgeSubsets
110 (
111  const triSurf& origSurf,
112  triSurf& newSurf
113 )
114 {
115  DynList<label> subsetIds;
116  origSurf.edgeSubsetIndices(subsetIds);
117 
118  forAll(subsetIds, subsetI)
119  {
120  label newSubsetId = newSurf.addEdgeSubset
121  (
122  origSurf.edgeSubsetName(subsetI)
123  );
124 
125  labelList origEdges;
126  origSurf.edgesInSubset(subsetI, origEdges);
127 
128  forAll(origEdges, faceI)
129  {
130  newSurf.addEdgeToSubset
131  (
132  newSubsetId,
133  origEdges[faceI]
134  );
135  }
136  }
137 }
138 
139 
140 // Copy all point subsets from one triSurf to another
141 void copyPointSubsets
142 (
143  const triSurf& origSurf,
144  triSurf& newSurf
145 )
146 {
147  DynList<label> subsetIds;
148  origSurf.pointSubsetIndices(subsetIds);
149 
150  forAll(subsetIds, subsetI)
151  {
152  label newSubsetId = newSurf.addPointSubset
153  (
154  origSurf.pointSubsetName(subsetI)
155  );
156 
157  labelList origPoints;
158  origSurf.pointsInSubset(subsetI, origPoints);
159 
160  forAll(origPoints, faceI)
161  {
162  newSurf.addPointToSubset
163  (
164  newSubsetId,
165  origPoints[faceI]
166  );
167  }
168  }
169 }
170 
171 
172 // Merge the supplied list of patchIds onto a new patch
174 (
175  const triSurf& origSurf, // Surface
176  const UList<label>& patchIds, // Ids of patches to merge
177  const word& newPatchName, // Name of new (merged) patch
178  bool keepPatches // Keep the original patches - they will be emptied
179 )
180 {
181  const geometricSurfacePatchList& origPatches = origSurf.patches();
182  const LongList<labelledTri>& origFacets = origSurf.facets();
183 
184  label newPatchId = origPatches.size();
185 
186  // Determine new patch type
187  word newPatchType = origPatches[patchIds[0]].geometricType();
188 
189  // Create patch addressing
190  List<DynamicList<label> > patchAddr(origPatches.size()+1);
191 
192  forAll(origFacets, faceI)
193  {
194  patchAddr[origFacets[faceI].region()].append(faceI);
195  }
196 
197  // Move selected patches to new patch
198  forAll(patchIds, patchI)
199  {
200  patchAddr[newPatchId].append(patchAddr[patchIds[patchI]]);
201  patchAddr[patchIds[patchI]].clear();
202  }
203 
204  // Create new facets list
205  LongList<labelledTri> newFacets(origFacets.size());
206  labelList newFaceAddr(origFacets.size(), -1);
207 
208  label patchCount = 0;
209  label faceI = 0;
210  forAll(patchAddr, patchI)
211  {
212  const unallocLabelList& addr = patchAddr[patchI];
213 
214  if(addr.size())
215  {
216  forAll(addr, i)
217  {
218  newFacets[faceI] = origFacets[addr[i]];
219  newFacets[faceI].region() = patchCount;
220 
221  newFaceAddr[addr[i]] = faceI;
222 
223  faceI++;
224  }
225  }
226 
227  if(addr.size() || keepPatches)
228  {
229  patchCount++;
230  }
231  }
232 
233  // Create new patch list
234  geometricSurfacePatchList newPatches(patchCount);
235 
236  patchCount = 0;
237  forAll(origPatches, patchI)
238  {
239  // Only add patches if they contain faces
240  if(patchAddr[patchI].size())
241  {
242  newPatches[patchCount] = origPatches[patchI];
243  newPatches[patchCount].index() = patchCount;
244  }
245 
246  if(patchAddr[patchI].size() || keepPatches)
247  {
248  patchCount++;
249  }
250  }
251 
252  // Add new patch if it contains faces
253  if(patchAddr[patchAddr.size()-1].size())
254  {
255  newPatches[patchCount] = geometricSurfacePatch
256  (
257  newPatchType,
258  newPatchName,
259  patchCount
260  );
261  }
262  if(patchAddr[patchAddr.size()-1].size() || keepPatches)
263  {
264  patchCount++;
265  }
266 
267  // Create new surface
268  autoPtr<triSurf> newSurf
269  (
270  new triSurf
271  (
272  newFacets,
273  newPatches,
274  origSurf.featureEdges(),
275  origSurf.points()
276  )
277  );
278 
279  // Transfer face subsets
280  copyFaceSubsets(origSurf, newSurf());
281  newSurf->updateFacetsSubsets(newFaceAddr);
282 
283  // Transfer feature edge subsets
284  copyEdgeSubsets(origSurf, newSurf());
285 
286  // Transfer point subsets
287  copyPointSubsets(origSurf, newSurf());
288 
289  // Done
290  return newSurf;
291 }
292 
293 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
294 
295 int main(int argc, char *argv[])
296 {
298  argList::validArgs.clear();
299 
300  argList::validArgs.append("input surface file");
301  argList::validArgs.append("new patch");
302  argList::validOptions.insert("patchNames", "list of names");
303  argList::validOptions.insert("patchIds", "list of patchIds");
304  argList::validOptions.insert("patchIdRange", "( start end )");
305  argList::validOptions.insert("output", "file name (default overwrite)");
306  argList::validOptions.insert("keep", "");
307  argList args(argc, argv);
308 
309  // Process commandline arguments
310  fileName inFileName(args.args()[1]);
311 
312  word newPatchName(args.args()[2]);
313 
314  fileName outFileName(inFileName);
315 
316  if( args.options().found("output") )
317  {
318  outFileName = args.options()["output"];
319  }
320 
321  bool keepPatches = false;
322 
323  if( args.options().found("keep") )
324  {
325  keepPatches = true;
326  }
327 
328  // Read original surface
329  triSurf origSurf(inFileName);
330 
331  // Get patch ids
332  DynamicList<label> patchIds;
333 
334  if (args.options().found("patchNames"))
335  {
336  if (args.options().found("patchIds"))
337  {
338  FatalError() << "Cannot specify both patch names and ids"
340  }
341 
342  IStringStream is(args.options()["patchNames"]);
343  wordList patchNames(is);
344 
346  (
347  origSurf,
348  patchNames,
349  patchIds
350  );
351  }
352  if (args.options().found("patchIds"))
353  {
354  IStringStream is(args.options()["patchIds"]);
355 
356  patchIds = labelList(is);
357  }
358  if (args.options().found("patchIds"))
359  {
360  IStringStream is(args.options()["patchIds"]);
361 
362  patchIds.append(labelList(is));
363  }
364  if (args.options().found("patchIdRange"))
365  {
366  IStringStream is(args.options()["patchIdRange"]);
367 
368  Pair<label> idRange(is);
369 
370  for(label id = idRange.first(); id <= idRange.second(); id++)
371  {
372  patchIds.append(id);
373  }
374  }
375  if (!patchIds.size())
376  {
377  FatalError() << "No patches specified"
379  }
380 
381  // Merge patches
383  (
384  origSurf,
385  patchIds,
386  newPatchName,
387  keepPatches
388  );
389 
390  // Write new surface mesh
391  newSurf->writeSurface(outFileName);
392 
393  Info << "Original surface patches: " << origSurf.patches().size() << endl;
394  Info << "Final surface patches: " << newSurf->patches().size() << endl;
395  Info << "Surface written to " << outFileName << endl;
396 
397  Info << "End\n" << endl;
398 
399  return 0;
400 }
401 
402 // ************************************************************************* //
Foam::argList::validArgs
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:143
Foam::triSurfPoints::pointsInSubset
void pointsInSubset(const label, ListType &) const
Definition: triSurfPointsI.H:117
main
int main(int argc, char *argv[])
Definition: mergeSurfacePatches.C:295
getPatchIds
void getPatchIds(const triSurf &origSurf, const wordList &patchNames, DynamicList< label > &patchIds)
Definition: mergeSurfacePatches.C:46
triSurf.H
Foam::triSurfPoints::pointSubsetName
word pointSubsetName(const label) const
Definition: triSurfPoints.C:84
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::argList::args
const stringList & args() const
Return arguments.
Definition: argListI.H:66
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::triSurfFeatureEdges::addEdgeSubset
label addEdgeSubset(const word &)
point subsets
Definition: triSurfFeatureEdges.C:54
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::DynamicList< label >
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::triSurfPoints::points
const pointField & points() const
access to points
Definition: triSurfPointsI.H:44
Foam::triSurfFeatureEdges::edgesInSubset
void edgesInSubset(const label, ListType &) const
Definition: triSurfFeatureEdgesI.H:118
Foam::geometricSurfacePatch
The geometricSurfacePatch is like patchIdentifier but for surfaces. Holds type, name and index.
Definition: geometricSurfacePatch.H:53
Foam::Pair::first
const Type & first() const
Return first.
Definition: Pair.H:87
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:97
triSurfModifier.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Pair.H
Foam::LongList::size
label size() const
Size of the active part of the list.
Definition: LongListI.H:203
Foam::HashSet
A HashTable with keys but without contents.
Definition: HashSet.H:59
Foam::triSurfFeatureEdges::addEdgeToSubset
void addEdgeToSubset(const label, const label)
Definition: triSurfFeatureEdgesI.H:55
Foam::triSurfPoints::addPointSubset
label addPointSubset(const word &)
point subsets
Definition: triSurfPoints.C:54
Foam::triSurfFeatureEdges::featureEdges
const edgeLongList & featureEdges() const
access to feature edges
Definition: triSurfFeatureEdgesI.H:44
Foam::LongList
Definition: LongList.H:55
Foam::argList::options
const Foam::HashTable< string > & options() const
Return options.
Definition: argListI.H:90
Foam::triSurfFacets::addFacetToSubset
void addFacetToSubset(const label, const label)
Definition: triSurfFacetsI.H:60
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
copyFaceSubsets
void copyFaceSubsets(const triSurf &origSurf, triSurf &newSurf)
Definition: mergeSurfacePatches.C:78
Foam::triSurfPoints::addPointToSubset
void addPointToSubset(const label, const label)
Definition: triSurfPointsI.H:57
Foam::List::append
void append(const T &)
Append an element at the end of the list.
Foam::Info
messageStream Info
copyPointSubsets
void copyPointSubsets(const triSurf &origSurf, triSurf &newSurf)
Definition: mergeSurfacePatches.C:142
argList.H
Foam::triSurfFacets::patches
const geometricSurfacePatchList & patches() const
access to patches
Definition: triSurfFacetsI.H:49
Foam::Pair::second
const Type & second() const
Return second.
Definition: Pair.H:99
patchNames
wordList patchNames(nPatches)
Foam::triSurfFacets::addFacetSubset
label addFacetSubset(const word &)
point subsets
Definition: triSurfFacets.C:105
Foam::argList::validOptions
static HashTable< string > validOptions
A list of valid options.
Definition: argList.H:146
Foam::FatalError
error FatalError
Foam::HashTable< nil, word, string::hash >::found
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
Foam::IStringStream
Input from memory buffer stream.
Definition: IStringStream.H:49
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::DynList< label >
Foam::triSurfPoints::pointSubsetIndices
void pointSubsetIndices(DynList< label > &) const
Definition: triSurfPointsI.H:102
Foam::DynamicList::append
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
Foam::Pair< label >
Foam::triSurfFeatureEdges::edgeSubsetIndices
void edgeSubsetIndices(DynList< label > &) const
Definition: triSurfFeatureEdgesI.H:101
Foam::triSurfFacets::facetSubsetIndices
void facetSubsetIndices(DynList< label > &) const
Definition: triSurfFacetsI.H:105
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: List.C:379
copyEdgeSubsets
void copyEdgeSubsets(const triSurf &origSurf, triSurf &newSurf)
Definition: mergeSurfacePatches.C:110
Foam::triSurfFacets::facets
const LongList< labelledTri > & facets() const
access to facets
Definition: triSurfFacetsI.H:44
Foam::triSurfFacets::facetSubsetName
word facetSubsetName(const label) const
Definition: triSurfFacets.C:135
WarningIn
#define WarningIn(functionName)
Report a warning using Foam::Warning.
Definition: messageStream.H:254
Foam::triSurfFacets::facetsInSubset
void facetsInSubset(const label, ListType &) const
Definition: triSurfFacetsI.H:120
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::argList::noParallel
static void noParallel()
Remove the parallel options.
Definition: argList.C:161
Foam::triSurfFeatureEdges::edgeSubsetName
word edgeSubsetName(const label) const
Definition: triSurfFeatureEdges.C:84
Foam::UList::size
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
args
Foam::argList args(argc, argv)
mergeSurfacePatches
autoPtr< triSurf > mergeSurfacePatches(const triSurf &origSurf, const UList< label > &patchIds, const word &newPatchName, bool keepPatches)
Definition: mergeSurfacePatches.C:174
Foam::triSurf
Definition: triSurf.H:59
autoPtr.H