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-2022 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  );
131  (
132  "read-format",
133  "type",
134  "Input format (default: use file extension)"
135  );
137  (
138  "write-format",
139  "type",
140  "Output format (default: use file extension)"
141  );
143  (
144  "read-scale",
145  "factor",
146  "Input geometry scaling factor"
147  );
149  (
150  "write-scale",
151  "factor",
152  "Output geometry scaling factor"
153  );
154 
155  argList::addOptionCompat("read-scale", {"scaleIn", 1912});
156  argList::addOptionCompat("write-scale", {"scaleOut", 1912});
157 
158  argList::addOption("dict", "file", "Alternative coordinateSystems");
159 
161  (
162  "from",
163  "system",
164  "The source coordinate system, applied after '-read-scale'",
165  true // advanced
166  );
168  (
169  "to",
170  "system",
171  "The target coordinate system, applied before '-write-scale'",
172  true // advanced
173  );
175  (
176  "tri",
177  "Triangulate surface"
178  );
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  if (importName == exportName)
188  {
189  FatalError
190  << "Output file would overwrite input file."
191  << exit(FatalError);
192  }
193 
194  const word readFileType
195  (
196  args.getOrDefault<word>("read-format", getExtension(importName))
197  );
198 
199  const word writeFileType
200  (
201  args.getOrDefault<word>("write-format", getExtension(exportName))
202  );
203 
204 
205  // Check that reading/writing is supported
206  if (!hasReadWriteTypes(readFileType, writeFileType))
207  {
208  FatalError
209  << "Unsupported file format(s)" << nl
210  << exit(FatalError);
211  }
212 
213 
214  scalar scaleFactor(0);
215 
216  // The coordinate transformations (must be cartesian)
219 
220  if (args.found("from") || args.found("to"))
221  {
223  (
224  IOobject
225  (
226  coordinateSystems::typeName,
227  runTime.constant(),
228  runTime,
231  false
232  ),
233  args.getOrDefault<fileName>("dict", "")
234  );
235 
236  if (!ioCsys.typeHeaderOk<coordinateSystems>(false))
237  {
238  FatalError
239  << "Cannot open coordinateSystems file\n "
240  << ioCsys.objectPath() << nl
241  << exit(FatalError);
242  }
243 
244  coordinateSystems globalCoords(ioCsys);
245 
246  if (args.found("from"))
247  {
248  const word csName(args["from"]);
249  const auto* csPtr = globalCoords.cfind(csName);
250 
251  if (!csPtr)
252  {
253  FatalError
254  << "Cannot find -from " << csName << nl
255  << "available coordinateSystems: "
256  << flatOutput(globalCoords.names()) << nl
257  << exit(FatalError);
258  }
259 
260  fromCsys = autoPtr<coordSystem::cartesian>::New(*csPtr);
261  }
262 
263  if (args.found("to"))
264  {
265  const word csName(args["to"]);
266  const auto* csPtr = globalCoords.cfind(csName);
267 
268  if (!csPtr)
269  {
270  FatalError
271  << "Cannot find -to " << csName << nl
272  << "available coordinateSystems: "
273  << flatOutput(globalCoords.names()) << nl
274  << exit(FatalError);
275  }
276 
277  toCsys = autoPtr<coordSystem::cartesian>::New(*csPtr);
278  }
279 
280  // Maybe fix this later
281  if (fromCsys && toCsys)
282  {
283  FatalError
284  << "Only allowed '-from' or '-to' option at the moment."
285  << exit(FatalError);
286  }
287  }
288 
289 
290  {
291  meshedSurface surf(importName, readFileType);
292 
293  if (args.readIfPresent("read-scale", scaleFactor) && scaleFactor > 0)
294  {
295  Info<< "scale input " << scaleFactor << nl;
296  surf.scalePoints(scaleFactor);
297  }
298 
299  if (args.found("clean"))
300  {
301  surf.cleanup(true);
302  }
303 
304  if (fromCsys)
305  {
306  Info<< "move points from coordinate system: "
307  << fromCsys->name() << nl;
308  tmp<pointField> tpf = fromCsys->localPosition(surf.points());
309  surf.movePoints(tpf());
310  }
311 
312  if (toCsys)
313  {
314  Info<< "move points to coordinate system: "
315  << toCsys->name() << nl;
316  tmp<pointField> tpf = toCsys->globalPosition(surf.points());
317  surf.movePoints(tpf());
318  }
319 
320  if (args.readIfPresent("write-scale", scaleFactor) && scaleFactor > 0)
321  {
322  Info<< "scale output " << scaleFactor << nl;
323  surf.scalePoints(scaleFactor);
324  }
325 
326  if (args.found("tri"))
327  {
328  Info<< "triangulate" << nl;
329  surf.triangulate();
330  }
331 
332  Info<< "writing " << exportName;
333  surf.write(exportName, writeFileType);
334  }
335 
336  Info<< "\nEnd\n" << endl;
337 
338  return 0;
339 }
340 
341 // ************************************************************************* //
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:453
A class for handling file names.
Definition: fileName.H:71
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:49
A centralized collection of named coordinate systems.
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:365
static void noParallel()
Remove the parallel options.
Definition: argList.C:551
static void addOptionCompat(const word &optName, std::pair< const char *, int > compat)
Specify an alias for the option name.
Definition: argList.C:409
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:239
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 INVALID.
Definition: exprTraits.C:52
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:376
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 (uses typeFilePath to find file) and check its info.
const word & constant() const noexcept
Return constant name.
Definition: TimePathsI.H:89
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:342
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:166
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:231
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225