surfaceTransformPoints.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) 2017-2020 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  surfaceTransformPoints
29 
30 Group
31  grpSurfaceUtilities
32 
33 Description
34  Transform (scale/rotate) a surface.
35  Like transformPoints but for surfaces.
36 
37  The rollPitchYaw and yawPitchRoll options take three angles (degrees)
38  that describe the intrinsic Euler rotation.
39 
40  rollPitchYaw
41  - roll (rotation about X) followed by
42  - pitch (rotation about Y) followed by
43  - yaw (rotation about Z)
44 
45  yawPitchRoll
46  - yaw (rotation about Z) followed by
47  - pitch (rotation about Y) followed by
48  - roll (rotation about X)
49 
50 \*---------------------------------------------------------------------------*/
51 
52 #include "argList.H"
53 #include "Fstream.H"
54 #include "boundBox.H"
55 #include "transformField.H"
56 #include "Pair.H"
57 #include "Tuple2.H"
58 #include "axisAngleRotation.H"
60 #include "MeshedSurfaces.H"
61 
62 using namespace Foam;
63 using namespace Foam::coordinateRotations;
64 
65 static word getExtension(const fileName& name)
66 {
67  word ext(name.ext());
68  if (ext == "gz")
69  {
70  ext = name.lessExt().ext();
71  }
72 
73  return ext;
74 }
75 
76 
77 // Non-short-circuiting check to get all warnings
78 static bool hasReadWriteTypes(const word& readType, const word& writeType)
79 {
80  volatile bool good = true;
81 
82  if (!meshedSurface::canReadType(readType, true))
83  {
84  good = false;
85  }
86 
87  if (!meshedSurface::canWriteType(writeType, true))
88  {
89  good = false;
90  }
91 
92  return good;
93 }
94 
95 
96 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
97 
98 int main(int argc, char *argv[])
99 {
101  (
102  "Transform (translate / rotate / scale) surface points.\n"
103  "Like transformPoints but for surfaces.\n"
104  "Note: roll=rotate about x, pitch=rotate about y, yaw=rotate about z"
105  );
107  argList::addArgument("input", "The input surface file");
108  argList::addArgument("output", "The output surface file");
110  (
111  "translate",
112  "vector",
113  "Translate by specified <vector> - eg, '(1 0 0)' before rotations"
114  );
116  (
117  "origin",
118  "point",
119  "Use specified <point> as origin for rotations"
120  );
122  (
123  "rotate",
124  "(vectorA vectorB)",
125  "Rotate from <vectorA> to <vectorB> - eg, '((1 0 0) (0 0 1))'"
126  );
128  (
129  "rotate-angle",
130  "(vector scalar)",
131  "Rotate <angle> degrees about <vector> - eg, '((1 0 0) 45)'"
132  );
134  (
135  "rollPitchYaw",
136  "vector",
137  "Rotate by '(roll pitch yaw)' degrees"
138  );
140  (
141  "yawPitchRoll",
142  "vector",
143  "Rotate by '(yaw pitch roll)' degrees"
144  );
146  (
147  "scale",
148  "scalar | vector",
149  "Scale by the specified amount - Eg, for uniform [mm] to [m] scaling "
150  "use either '(0.001 0.001 0.001)' or simply '0.001'"
151  );
153  (
154  "read-format",
155  "type",
156  "Input format (default: use file extension)"
157  );
159  (
160  "write-format",
161  "type",
162  "Output format (default: use file extension)"
163  );
164 
165  argList args(argc, argv);
166 
167  // Verify that an operation has been specified
168  {
169  const List<word> operationNames
170  {
171  "translate",
172  "rotate",
173  "rotate-angle",
174  "rollPitchYaw",
175  "yawPitchRoll",
176  "scale"
177  };
178 
179  if (!args.count(operationNames))
180  {
181  FatalError
182  << "No operation supplied, "
183  << "use at least one of the following:" << nl
184  << " ";
185 
186  for (const auto& opName : operationNames)
187  {
188  FatalError
189  << " -" << opName;
190  }
191 
192  FatalError
193  << nl << exit(FatalError);
194  }
195  }
196 
197  const fileName importName(args[1]);
198  const fileName exportName(args[2]);
199 
200  const word readFileType
201  (
202  args.getOrDefault<word>("read-format", getExtension(importName))
203  );
204 
205  const word writeFileType
206  (
207  args.getOrDefault<word>("write-format", getExtension(exportName))
208  );
209 
210 
211  // Check that reading/writing is supported
212  if (!hasReadWriteTypes(readFileType, writeFileType))
213  {
214  FatalError
215  << "Unsupported file format(s)" << nl
216  << exit(FatalError);
217  }
218 
219 
220  Info<< "Reading surf from " << importName << " ..." << nl
221  << "Writing surf to " << exportName << " ..." << endl;
222 
223 
224  meshedSurface surf1(importName, readFileType);
225 
226  pointField points(surf1.points());
227 
228  vector v;
229  if (args.readIfPresent("translate", v))
230  {
231  Info<< "Translating points by " << v << endl;
232 
233  points += v;
234  }
235 
236  vector origin(Zero);
237  const bool useOrigin = args.readIfPresent("origin", origin);
238  if (useOrigin)
239  {
240  Info<< "Set origin for rotations to " << origin << endl;
241  points -= origin;
242  }
243 
244  if (args.found("rotate"))
245  {
246  Pair<vector> n1n2
247  (
248  args.lookup("rotate")()
249  );
250  n1n2[0].normalise();
251  n1n2[1].normalise();
252 
253  const tensor rot(rotationTensor(n1n2[0], n1n2[1]));
254 
255  Info<< "Rotating points by " << rot << endl;
256  points = transform(rot, points);
257  }
258  else if (args.found("rotate-angle"))
259  {
260  const Tuple2<vector, scalar> rotAxisAngle
261  (
262  args.lookup("rotate-angle")()
263  );
264 
265  const vector& axis = rotAxisAngle.first();
266  const scalar& angle = rotAxisAngle.second();
267 
268  Info<< "Rotating points " << nl
269  << " about " << axis << nl
270  << " angle " << angle << nl;
271 
272  const tensor rot(axisAngle::rotation(axis, angle, true));
273 
274  Info<< "Rotating points by " << rot << endl;
275  points = transform(rot, points);
276  }
277  else if (args.readIfPresent("rollPitchYaw", v))
278  {
279  Info<< "Rotating points by" << nl
280  << " roll " << v.x() << nl
281  << " pitch " << v.y() << nl
282  << " yaw " << v.z() << nl;
283 
284  const tensor rot(euler::rotation(euler::eulerOrder::XYZ, v, true));
285 
286  Info<< "Rotating points by " << rot << endl;
287  points = transform(rot, points);
288  }
289  else if (args.readIfPresent("yawPitchRoll", v))
290  {
291  Info<< "Rotating points by" << nl
292  << " yaw " << v.x() << nl
293  << " pitch " << v.y() << nl
294  << " roll " << v.z() << nl;
295 
296  const tensor rot(euler::rotation(euler::eulerOrder::ZYX, v, true));
297 
298  Info<< "Rotating points by " << rot << endl;
299  points = transform(rot, points);
300  }
301 
302  List<scalar> scaling;
303  if (args.readListIfPresent("scale", scaling))
304  {
305  // readListIfPresent handles single or multiple values
306 
307  if
308  (
309  scaling.size() == 1
310  ||
311  (
312  scaling.size() == 3
313  && equal(scaling[0], scaling[1])
314  && equal(scaling[0], scaling[2])
315  )
316  )
317  {
318  Info<< "Scaling points uniformly by " << scaling[0] << nl;
319  points *= scaling[0];
320  }
321  else if (scaling.size() == 3)
322  {
323  Info<< "Scaling points by ("
324  << scaling[0] << ' '
325  << scaling[1] << ' '
326  << scaling[2] << ')' << nl;
327 
331  }
332  else
333  {
334  FatalError
335  << "-scale with 1 or 3 components only" << nl
336  << "given: " << args["scale"] << endl
337  << exit(FatalError);
338  }
339  }
340 
341  if (useOrigin)
342  {
343  Info<< "Unset origin for rotations from " << origin << endl;
344  points += origin;
345  }
346 
347  surf1.movePoints(points);
348  surf1.write(exportName, writeFileType);
349 
350  Info<< "End\n" << endl;
351 
352  return 0;
353 }
354 
355 
356 // ************************************************************************* //
Foam::argList::count
label count(const UList< word > &optionNames) const
Return how many of the specified options were used.
Definition: argList.C:1569
Foam::word::lessExt
word lessExt() const
Return word without extension (part before last .)
Definition: word.C:113
Foam::Tensor< scalar >
Foam::Vector< scalar >::Z
Definition: Vector.H:81
EulerCoordinateRotation.H
Foam::Vector< scalar >::Y
Definition: Vector.H:81
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:286
Foam::MeshedSurface< face >::canReadType
static bool canReadType(const word &fileType, bool verbose=false)
Can we read this file format? Also checks friend types.
Definition: MeshedSurface.C:60
Tuple2.H
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:123
Foam::argList::readListIfPresent
bool readListIfPresent(const word &optName, List< T > &list) const
Definition: argListI.H:373
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Pair.H
Foam::word::ext
word ext() const
Return file name extension (part after last .)
Definition: word.C:126
Foam::MeshedSurface< face >::canWriteType
static bool canWriteType(const word &fileType, bool verbose=false)
Can we write this file format? Also checks proxy types.
Definition: MeshedSurface.C:77
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:519
Foam::argList::readIfPresent
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:302
transformField.H
Spatial transformation functions for primitive fields.
Foam::argList::addArgument
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:302
Foam::argList::lookup
ITstream lookup(const word &optName) const
Return an input stream from the named option.
Definition: argListI.H:163
Foam::coordinateRotations::axisAngle::rotation
static tensor rotation(const vector &axis, const scalar angle, bool degrees=false)
The rotation tensor for given axis/angle.
Definition: axisAngleRotation.C:65
Foam::Field< vector >
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::coordinateRotations
Namespace for coordinate system rotations.
Definition: axesRotation.C:37
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::Vector< scalar >::X
Definition: Vector.H:81
argList.H
axisAngleRotation.H
Foam::Field::replace
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
Definition: Field.C:563
Foam::FatalError
error FatalError
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::Field::component
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
Definition: Field.C:551
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
boundBox.H
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:54
Fstream.H
Input/output from file streams.
Foam::Vector< scalar >
Foam::List< word >
MeshedSurfaces.H
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::coordinateRotations::euler::rotation
static tensor rotation(const vector &angles, bool degrees=false)
Definition: EulerCoordinateRotation.C:239
Foam::rotationTensor
tensor rotationTensor(const vector &n1, const vector &n2)
Rotational transformation tensor from vector n1 to n2.
Definition: transform.H:51
Foam::Tuple2< vector, scalar >
Foam::argList::noParallel
static void noParallel()
Remove the parallel options.
Definition: argList.C:491
Foam::MeshedSurface< face >
Foam::argList::addOption
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:336
args
Foam::argList args(argc, argv)
Foam::equal
bool equal(const T &s1, const T &s2)
Compare two values for equality.
Definition: doubleFloat.H:46
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:157