surfaceTransformPoints: Generalised to apply a sequence of transformations

The transformation sequence is specified like a substitution string used by

Description
    Transform (translate, rotate, scale) a surface.

    The rollPitchYaw option takes three angles (degrees):
    - roll (rotation about x) followed by
    - pitch (rotation about y) followed by
    - yaw (rotation about z)

    The yawPitchRoll does yaw followed by pitch followed by roll.

Usage
    \b surfaceTransformPoints "\<transformations\>" \<input\> \<output\>

    Example usage:
        surfaceTransformPoints \
            "translate=(-0.586 0 -0.156), \
            rollPitchYaw=(0 -3.485 0), \
            translate=(0.586 0 0.156)" \
            constant/geometry/w3_orig.stl constant/geometry/w3.stl
This commit is contained in:
Henry Weller
2021-03-28 13:36:50 +01:00
parent 516ee1675e
commit 45dca30c51
3 changed files with 83 additions and 124 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -25,8 +25,7 @@ Application
surfaceTransformPoints surfaceTransformPoints
Description Description
Transform (scale/rotate) a surface. Transform (translate, rotate, scale) a surface.
Like transformPoints but for surfaces.
The rollPitchYaw option takes three angles (degrees): The rollPitchYaw option takes three angles (degrees):
- roll (rotation about x) followed by - roll (rotation about x) followed by
@ -35,22 +34,27 @@ Description
The yawPitchRoll does yaw followed by pitch followed by roll. The yawPitchRoll does yaw followed by pitch followed by roll.
Usage
\b surfaceTransformPoints "\<transformations\>" \<input\> \<output\>
Example usage:
surfaceTransformPoints \
"translate=(-0.586 0 -0.156), \
rollPitchYaw=(0 -3.485 0), \
translate=(0.586 0 0.156)" \
constant/geometry/w3_orig.stl constant/geometry/w3.stl
See also
transformPoints
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "argList.H" #include "argList.H"
#include "OFstream.H"
#include "IFstream.H"
#include "boundBox.H"
#include "transformField.H"
#include "Pair.H"
#include "quaternion.H" #include "quaternion.H"
#include "mathematicalConstants.H" #include "unitConversion.H"
#include "MeshedSurfaces.H" #include "MeshedSurfaces.H"
using namespace Foam; using namespace Foam;
using namespace Foam::constant::mathematical;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -60,132 +64,89 @@ int main(int argc, char *argv[])
argList::addNote argList::addNote
( (
"Transform (scale/rotate) a surface. " "Transform (translate, rotate, scale) a surface."
"Like transformPoints but for surfaces."
); );
argList::noParallel(); argList::noParallel();
argList::validArgs.append("transformations");
argList::validArgs.append("surface file"); argList::validArgs.append("surface file");
argList::validArgs.append("output surface file"); argList::validArgs.append("output surface file");
argList::addOption
(
"translate",
"vector",
"translate by the specified <vector> - eg, '(1 0 0)'"
);
argList::addOption
(
"rotate",
"(vectorA vectorB)",
"transform in terms of a rotation between <vectorA> and <vectorB> "
"- eg, '( (1 0 0) (0 0 1) )'"
);
argList::addOption
(
"scale",
"vector",
"scale by the specified amount - eg, '(0.001 0.001 0.001)' for a "
"uniform [mm] to [m] scaling"
);
argList::addOption
(
"rollPitchYaw",
"vector",
"transform in terms of '( roll pitch yaw )' in degrees"
);
argList::addOption
(
"yawPitchRoll",
"vector",
"transform in terms of '( yaw pitch roll )' in degrees"
);
argList args(argc, argv); argList args(argc, argv);
const fileName surfFileName = args[1]; const string transformationString(args[1]);
const fileName outFileName = args[2]; const fileName surfFileName(args[2]);
const fileName outFileName(args[3]);
Info<< "Reading surf from " << surfFileName << " ..." << nl Info<< "Reading surf from " << surfFileName << " ..." << nl
<< "Writing surf to " << outFileName << " ..." << endl; << "Writing surf to " << outFileName << " ..." << endl;
if (args.options().empty()) wordReList simpleTransformations;
{ List<Tuple2<word, string>> transformations;
FatalErrorInFunction dictArgList(transformationString, simpleTransformations, transformations);
<< "No options supplied, please use one or more of "
"-translate, -rotate or -scale options."
<< exit(FatalError);
}
meshedSurface surf1(surfFileName); meshedSurface surf1(surfFileName);
pointField points(surf1.points()); pointField points(surf1.points());
vector v; forAll(transformations, i)
if (args.optionReadIfPresent("translate", v))
{ {
Info<< "Translating points by " << v << endl; if (transformations[i].first() == "translate")
{
const vector v(IStringStream(transformations[i].second())());
Info<< "Translating points by " << v << endl;
points += v;
}
else if (transformations[i].first() == "rotate")
{
Pair<vector> n1n2(IStringStream(transformations[i].second())());
points += v; n1n2[0] /= mag(n1n2[0]);
} n1n2[1] /= mag(n1n2[1]);
if (args.optionFound("rotate")) const tensor T = rotationTensor(n1n2[0], n1n2[1]);
{
Pair<vector> n1n2
(
args.optionLookup("rotate")()
);
n1n2[0] /= mag(n1n2[0]);
n1n2[1] /= mag(n1n2[1]);
tensor T = rotationTensor(n1n2[0], n1n2[1]); Info<< "Rotating points by " << T << endl;
Info<< "Rotating points by " << T << endl; points = transform(T, points);
}
else if (transformations[i].first() == "rollPitchYaw")
{
const vector v(IStringStream(transformations[i].second())());
points = transform(T, points); Info<< "Rotating points by "
} << " roll = " << v.x()
else if (args.optionReadIfPresent("rollPitchYaw", v)) << ", pitch = " << v.y()
{ << ", yaw = " << v.z() << nl;
Info<< "Rotating points by" << nl
<< " roll " << v.x() << nl
<< " pitch " << v.y() << nl
<< " yaw " << v.z() << nl;
// Convert to radians const quaternion R(quaternion::rotationSequence::XYZ, degToRad(v));
v *= pi/180.0; points = transform(R, points);
}
else if (transformations[i].first() == "yawPitchRoll")
{
const vector v(IStringStream(transformations[i].second())());
quaternion R(quaternion::rotationSequence::XYZ, v); Info<< "Rotating points by "
<< " yaw " << v.x()
<< ", pitch " << v.y()
<< ", roll " << v.z() << nl;
Info<< "Rotating points by quaternion " << R << endl; const quaternion R
points = transform(R, points); (
} quaternion::rotationSequence::ZYX,
else if (args.optionReadIfPresent("yawPitchRoll", v)) degToRad(vector(v.z(), v.y(), v.x()))
{ );
Info<< "Rotating points by" << nl points = transform(R, points);
<< " yaw " << v.x() << nl }
<< " pitch " << v.y() << nl else if (transformations[i].first() == "scale")
<< " roll " << v.z() << nl; {
const vector v(IStringStream(transformations[i].second())());
Info<< "Scaling points by " << v << endl;
// Convert to radians points.replace(vector::X, v.x()*points.component(vector::X));
v *= pi/180.0; points.replace(vector::Y, v.y()*points.component(vector::Y));
points.replace(vector::Z, v.z()*points.component(vector::Z));
scalar yaw = v.x(); }
scalar pitch = v.y();
scalar roll = v.z();
quaternion R = quaternion(vector(0, 0, 1), yaw);
R *= quaternion(vector(0, 1, 0), pitch);
R *= quaternion(vector(1, 0, 0), roll);
Info<< "Rotating points by quaternion " << R << endl;
points = transform(R, points);
}
if (args.optionReadIfPresent("scale", v))
{
Info<< "Scaling points by " << v << endl;
points.replace(vector::X, v.x()*points.component(vector::X));
points.replace(vector::Y, v.y()*points.component(vector::Y));
points.replace(vector::Z, v.z()*points.component(vector::Z));
} }
surf1.movePoints(points); surf1.movePoints(points);

View File

@ -4,12 +4,11 @@ cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions # Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions . $WM_PROJECT_DIR/bin/tools/RunFunctions
runApplication surfaceTransformPoints -translate '(-0.586 0 -0.156)' \ runApplication surfaceTransformPoints \
constant/geometry/w3_orig.stl constant/geometry/w3.stl "translate=(-0.586 0 -0.156), \
runApplication -a surfaceTransformPoints -rollPitchYaw '(0 -3.485 0)' \ rollPitchYaw=(0 -3.485 0), \
constant/geometry/w3.stl constant/geometry/w3.stl translate=(0.586 0 0.156)" \
runApplication -a surfaceTransformPoints -translate '(0.586 0 0.156)' \ constant/geometry/w3_orig.stl constant/geometry/w3.stl
constant/geometry/w3.stl constant/geometry/w3.stl
runApplication surfaceFeatures runApplication surfaceFeatures

View File

@ -4,12 +4,11 @@ cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions # Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions . $WM_PROJECT_DIR/bin/tools/RunFunctions
runApplication surfaceTransformPoints -translate '(-0.586 0 -0.156)' \ runApplication surfaceTransformPoints \
constant/geometry/w3_orig.stl constant/geometry/w3.stl "translate=(-0.586 0 -0.156), \
runApplication -a surfaceTransformPoints -rollPitchYaw '(0 -3.485 0)' \ rollPitchYaw=(0 -3.485 0), \
constant/geometry/w3.stl constant/geometry/w3.stl translate=(0.586 0 0.156)" \
runApplication -a surfaceTransformPoints -translate '(0.586 0 0.156)' \ constant/geometry/w3_orig.stl constant/geometry/w3.stl
constant/geometry/w3.stl constant/geometry/w3.stl
runApplication surfaceFeatures runApplication surfaceFeatures