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-2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
27Application
28 surfaceMeshConvert
29
30Group
31 grpSurfaceUtilities
32
33Description
34 Convert between surface formats with optional scaling or
35 transformations (rotate/translate) on a coordinateSystem.
36
37Usage
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
68Note
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
80using namespace Foam;
81
82static word getExtension(const fileName& name)
83{
84 word ext(name.ext());
85 if (ext == "gz")
86 {
87 ext = name.lessExt().ext();
88 }
89
90 return ext;
91}
92
93// Non-short-circuiting check to get all warnings
94static 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
114int main(int argc, char *argv[])
115{
116 argList::addNote
117 (
118 "Convert between surface formats, using MeshSurface library components"
119 );
120
121 argList::noParallel();
122 argList::addArgument("input", "The input surface file");
123 argList::addArgument("output", "The output surface file");
124
125 argList::addBoolOption
126 (
127 "clean",
128 "Perform some surface checking/cleanup on the input surface"
129 );
130 argList::addOption
131 (
132 "read-format",
133 "type",
134 "Input format (default: use file extension)"
135 );
136 argList::addOption
137 (
138 "write-format",
139 "type",
140 "Output format (default: use file extension)"
141 );
142 argList::addOption
143 (
144 "read-scale",
145 "factor",
146 "Input geometry scaling factor"
147 );
148 argList::addOption
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
160 argList::addOption
161 (
162 "from",
163 "system",
164 "The source coordinate system, applied after '-read-scale'",
165 true // advanced
166 );
167 argList::addOption
168 (
169 "to",
170 "system",
171 "The target coordinate system, applied before '-write-scale'",
172 true // advanced
173 );
174 argList::addBoolOption
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 {
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 {
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 {
222 IOobject ioCsys = IOobject::selectIO
223 (
225 (
226 coordinateSystems::typeName,
227 runTime.constant(),
228 runTime,
229 IOobject::MUST_READ,
230 IOobject::NO_WRITE,
231 false
232 ),
233 args.getOrDefault<fileName>("dict", "")
234 );
235
236 if (!ioCsys.typeHeaderOk<coordinateSystems>(false))
237 {
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 {
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 {
271 << "Cannot find -to " << csName << nl
272 << "available coordinateSystems: "
273 << flatOutput(globalCoords.names()) << nl
274 << exit(FatalError);
275 }
276
278 }
279
280 // Maybe fix this later
281 if (fromCsys && toCsys)
282 {
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// ************************************************************************* //
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
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.
fileName objectPath() const
The complete path + object name.
Definition: IOobjectI.H:214
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:124
T get(const label index) const
Get a value from the argument at index.
Definition: argListI.H:278
const fileName & rootPath() const noexcept
Return root path.
Definition: argListI.H:63
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:178
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:323
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:307
const fileName & caseName() const noexcept
Return case name (parallel run) or global case (serial run)
Definition: argListI.H:69
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
A centralized collection of named coordinate systems.
A class for handling file names.
Definition: fileName.H:76
A class for managing temporary objects.
Definition: tmp.H:65
A class for handling words, derived from Foam::string.
Definition: word.H:68
word ext() const
Return file name extension (part after last .)
Definition: word.C:126
word lessExt() const
Return word without extension (part before last .)
Definition: word.C:113
engineTime & runTime
Namespace for OpenFOAM.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:215
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
Foam::argList args(argc, argv)