surfaceMeshConvert.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) 2018-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 Application
28  surfaceMeshConvert
29 
30 Group
31  grpSurfaceUtilities
32 
33 Description
34  Convert between surface formats with optional scaling or
35  transformations (rotate/translate) on a coordinateSystem.
36 
37 Usage
38  \b surfaceMeshConvert inputFile outputFile [OPTION]
39 
40  Options:
41  - \par -clean
42  Perform some surface checking/cleanup on the input surface.
43 
44  - \par -read-format <type>
45  The input file format (default: use file extension)
46 
47  - \par -write-format <type>
48  The output file format (default: use file extension)
49 
50  - \par -read-scale <scale>
51  Input geometry scaling factor.
52 
53  - \par -write-scale <scale>
54  Output geometry scaling factor.
55 
56  - \par -dict <dictionary>
57  Alternative dictionary for constant/coordinateSystems.
58 
59  - \par -from <coordinateSystem>
60  Apply specified coordinate system after reading file.
61 
62  - \par -to <coordinateSystem>
63  Apply specified coordinate system before writing file.
64 
65  - \par -tri
66  Triangulate surface.
67 
68 Note
69  The filename extensions are used to determine the default file formats.
70 
71 \*---------------------------------------------------------------------------*/
72 
73 #include "argList.H"
74 #include "Time.H"
75 
76 #include "MeshedSurfaces.H"
77 #include "coordinateSystems.H"
78 #include "cartesianCS.H"
79 
80 using namespace Foam;
81 
82 static word getExtension(const fileName& name)
83 {
84  return
85  (
86  name.has_ext("gz")
87  ? name.stem().ext()
88  : name.ext()
89  );
90 }
91 
92 
93 // Non-short-circuiting check to get all warnings
94 static bool hasReadWriteTypes(const word& readType, const word& writeType)
95 {
96  volatile bool good = true;
97 
98  if (!meshedSurface::canReadType(readType, true))
99  {
100  good = false;
101  }
102 
103  if (!meshedSurface::canWriteType(writeType, true))
104  {
105  good = false;
106  }
107 
108  return good;
109 }
110 
111 
112 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
113 
114 int main(int argc, char *argv[])
115 {
117  (
118  "Convert between surface formats, using MeshSurface library components"
119  );
120 
122  argList::addArgument("input", "The input surface file");
123  argList::addArgument("output", "The output surface file");
124 
126  (
127  "clean",
128  "Perform some surface checking/cleanup on the input surface"
129  );
132  (
133  "read-format",
134  "type",
135  "Input format (default: use file extension)"
136  );
138  (
139  "write-format",
140  "type",
141  "Output format (default: use file extension)"
142  );
144  (
145  "read-scale",
146  "factor",
147  "Input geometry scaling factor"
148  );
150  (
151  "write-scale",
152  "factor",
153  "Output geometry scaling factor"
154  );
155 
156  argList::addOptionCompat("read-scale", {"scaleIn", 1912});
157  argList::addOptionCompat("write-scale", {"scaleOut", 1912});
158 
159  argList::addOption("dict", "file", "Alternative coordinateSystems");
160 
162  (
163  "from",
164  "system",
165  "The source coordinate system, applied after '-read-scale'",
166  true // advanced
167  );
169  (
170  "to",
171  "system",
172  "The target coordinate system, applied before '-write-scale'",
173  true // advanced
174  );
176  (
177  "tri",
178  "Triangulate surface"
179  );
180 
181  argList args(argc, argv);
183 
184  const auto importName = args.get<fileName>(1);
185  const auto exportName = args.get<fileName>(2);
186 
187  const int optVerbose = args.verbose();
188 
189  if (importName == exportName)
190  {
191  FatalError
192  << "Output file would overwrite input file."
193  << exit(FatalError);
194  }
195 
196  const word readFileType
197  (
198  args.getOrDefault<word>("read-format", getExtension(importName))
199  );
200 
201  const word writeFileType
202  (
203  args.getOrDefault<word>("write-format", getExtension(exportName))
204  );
205 
206 
207  // Check that reading/writing is supported
208  if (!hasReadWriteTypes(readFileType, writeFileType))
209  {
210  FatalError
211  << "Unsupported file format(s)" << nl
212  << exit(FatalError);
213  }
214 
215 
216  scalar scaleFactor(0);
217 
218  // The coordinate transformations (must be cartesian)
221 
222  if (args.found("from") || args.found("to"))
223  {
225  (
226  IOobject
227  (
228  coordinateSystems::typeName,
229  runTime.constant(),
230  runTime,
234  ),
235  args.getOrDefault<fileName>("dict", "")
236  );
237 
238  if (!ioCsys.typeHeaderOk<coordinateSystems>(false))
239  {
240  FatalError
241  << "Cannot open coordinateSystems file\n "
242  << ioCsys.objectPath() << nl
243  << exit(FatalError);
244  }
245 
246  coordinateSystems globalCoords(ioCsys);
247 
248  if (args.found("from"))
249  {
250  const word csName(args["from"]);
251  const auto* csPtr = globalCoords.cfind(csName);
252 
253  if (!csPtr)
254  {
255  FatalError
256  << "Cannot find -from " << csName << nl
257  << "available coordinateSystems: "
258  << flatOutput(globalCoords.names()) << nl
259  << exit(FatalError);
260  }
261 
262  fromCsys = autoPtr<coordSystem::cartesian>::New(*csPtr);
263  }
264 
265  if (args.found("to"))
266  {
267  const word csName(args["to"]);
268  const auto* csPtr = globalCoords.cfind(csName);
269 
270  if (!csPtr)
271  {
272  FatalError
273  << "Cannot find -to " << csName << nl
274  << "available coordinateSystems: "
275  << flatOutput(globalCoords.names()) << nl
276  << exit(FatalError);
277  }
278 
279  toCsys = autoPtr<coordSystem::cartesian>::New(*csPtr);
280  }
281 
282  // Maybe fix this later
283  if (fromCsys && toCsys)
284  {
285  FatalError
286  << "Only allowed '-from' or '-to' option at the moment."
287  << exit(FatalError);
288  }
289  }
290 
291 
292  {
293  meshedSurface surf(importName, readFileType);
294 
295  if (args.readIfPresent("read-scale", scaleFactor) && scaleFactor > 0)
296  {
297  Info<< "scale input " << scaleFactor << nl;
298  surf.scalePoints(scaleFactor);
299  }
300 
301  if (args.found("clean"))
302  {
303  surf.cleanup(optVerbose);
304  }
305 
306  if (fromCsys)
307  {
308  Info<< "move points from coordinate system: "
309  << fromCsys->name() << nl;
310  tmp<pointField> tpf = fromCsys->localPosition(surf.points());
311  surf.movePoints(tpf());
312  }
313 
314  if (toCsys)
315  {
316  Info<< "move points to coordinate system: "
317  << toCsys->name() << nl;
318  tmp<pointField> tpf = toCsys->globalPosition(surf.points());
319  surf.movePoints(tpf());
320  }
321 
322  if (args.readIfPresent("write-scale", scaleFactor) && scaleFactor > 0)
323  {
324  Info<< "scale output " << scaleFactor << nl;
325  surf.scalePoints(scaleFactor);
326  }
327 
328  if (args.found("tri"))
329  {
330  Info<< "triangulate" << nl;
331  surf.triangulate();
332  }
333 
334  Info<< "writing " << exportName;
335  surf.write(exportName, writeFileType);
336  }
337 
338  Info<< "\nEnd\n" << endl;
339 
340  return 0;
341 }
342 
343 // ************************************************************************* //
point globalPosition(const point &local) const
From local coordinate position to global (cartesian) position.
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:462
A class for handling file names.
Definition: fileName.H:72
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
A centralized collection of named coordinate systems.
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:374
static void noParallel()
Remove the parallel options.
Definition: argList.C:584
static void addOptionCompat(const word &optName, std::pair< const char *, int > compat)
Specify an alias for the option name.
Definition: argList.C:418
Ignore writing from objectRegistry::writeObject()
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:300
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
fileName objectPath() const
The complete path + object name.
Definition: IOobjectI.H:284
point localPosition(const point &global) const
From global (cartesian) position to local coordinate position.
word ext() const
Return file name extension (part after last .)
Definition: wordI.H:171
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
bool has_ext() const
Various checks for extensions.
Definition: stringI.H:43
A class for handling words, derived from Foam::string.
Definition: word.H:63
Extract command arguments and options from the supplied argc and argv parameters. ...
Definition: argList.H:118
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:385
const fileName & caseName() const noexcept
Return case name (parallel run) or global case (serial run)
Definition: argListI.H:62
bool typeHeaderOk(const bool checkType=true, const bool search=true, const bool verbose=true)
Read header (respects is_globalIOobject trait) and check its info.
static void addVerboseOption(const string &usage="", bool advanced=false)
Enable a &#39;verbose&#39; bool option, with usage information.
Definition: argList.C:520
const word & constant() const noexcept
Return constant name.
Definition: TimePathsI.H:112
const fileName & rootPath() const noexcept
Return root path.
Definition: argListI.H:56
static bool canWriteType(const word &fileType, bool verbose=false)
Can we write this file format? Also checks proxy types.
Definition: MeshedSurface.C:70
T get(const label index) const
Get a value from the argument at index.
Definition: argListI.H:271
static bool canReadType(const word &fileType, bool verbose=false)
Can we read this file format? Also checks friend types.
Definition: MeshedSurface.C:53
virtual const word & name() const
Return the name.
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:351
messageStream Info
Information stream (stdout output on master, null elsewhere)
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:316
A class for managing temporary objects.
Definition: HashPtrTable.H:50
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition: autoPtr.H:178
Foam::argList args(argc, argv)
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
int verbose() const noexcept
Return the verbose flag.
Definition: argListI.H:121
Do not request registration (bool: false)
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171
Namespace for OpenFOAM.
static IOobject selectIO(const IOobject &io, const fileName &altFile, const word &ioName="")
Return the IOobject, but also consider an alternative file name.
Definition: IOobject.C:256
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225