transformPoints: Generalised to apply a sequence of transformations
This makes usage of transformPoints the same as for
surfaceTransformPoints. Transformations are supplied as a string and are
applied in sequence.
Usage
transformPoints "\<transformations\>" [OPTION]
Supported transformations:
- "translate=<translation vector>"
Translational transformation by given vector
- "rotate=(<n1 vector> <n2 vector>)"
Rotational transformation from unit vector n1 to n2
- "Rx=<angle [deg] about x-axis>"
Rotational transformation by given angle about x-axis
- "Ry=<angle [deg] about y-axis>"
Rotational transformation by given angle about y-axis
- "Rz=<angle [deg] about z-axis>"
Rotational transformation by given angle about z-axis
- "Ra=<axis vector> <angle [deg] about axis>"
Rotational transformation by given angle about given axis
- "scale=<x-y-z scaling vector>"
Anisotropic scaling by the given vector in the x, y, z
coordinate directions
Example usage:
transformPoints \
"translate=(-0.05 -0.05 0), \
Rz=45, \
translate=(0.05 0.05 0)"
This commit is contained in:
@ -0,0 +1,72 @@
|
||||
transformer transforms;
|
||||
|
||||
{
|
||||
wordReList simpleTransformations;
|
||||
List<Tuple2<word, string>> transformations;
|
||||
dictArgList(transformationString, simpleTransformations, transformations);
|
||||
|
||||
forAll(transformations, i)
|
||||
{
|
||||
if (transformations[i].first() == "translate")
|
||||
{
|
||||
const vector v(IStringStream(transformations[i].second())());
|
||||
transforms = transformer::translation(v) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "rotate")
|
||||
{
|
||||
Pair<vector> n1n2(IStringStream(transformations[i].second())());
|
||||
|
||||
n1n2[0] /= mag(n1n2[0]);
|
||||
n1n2[1] /= mag(n1n2[1]);
|
||||
|
||||
transforms =
|
||||
transformer::rotation(rotationTensor(n1n2[0], n1n2[1]))
|
||||
& transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "Rx")
|
||||
{
|
||||
const scalar a
|
||||
(
|
||||
readScalar(IStringStream(transformations[i].second())())
|
||||
);
|
||||
transforms = transformer::rotation(Rx(degToRad(a))) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "Ry")
|
||||
{
|
||||
const scalar a
|
||||
(
|
||||
readScalar(IStringStream(transformations[i].second())())
|
||||
);
|
||||
transforms = transformer::rotation(Ry(degToRad(a))) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "Rz")
|
||||
{
|
||||
const scalar a
|
||||
(
|
||||
readScalar(IStringStream(transformations[i].second())())
|
||||
);
|
||||
transforms = transformer::rotation(Rz(degToRad(a))) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "Ra")
|
||||
{
|
||||
IStringStream istr(transformations[i].second());
|
||||
const vector v(istr);
|
||||
const scalar a(readScalar(istr));
|
||||
transforms = transformer::rotation(Ra(v, degToRad(a))) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "scale")
|
||||
{
|
||||
const vector v(IStringStream(transformations[i].second())());
|
||||
transforms =
|
||||
transformer::scaling(diagTensor(v.x(), v.y(), v.z()))
|
||||
& transforms;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.printUsage();
|
||||
FatalErrorInFunction
|
||||
<< "Unknown transformation " << transformations[i].first()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -25,40 +25,42 @@ Application
|
||||
transformPoints
|
||||
|
||||
Description
|
||||
Transforms the mesh points in the polyMesh directory according to the
|
||||
translate, rotate and scale options.
|
||||
Transform (translate, rotate, scale) the mesh points, and optionally also
|
||||
any vector and tensor fields.
|
||||
|
||||
Usage
|
||||
\b transformPoints [OPTION]
|
||||
\b transformPoints "\<transformations\>" [OPTION]
|
||||
|
||||
Supported transformations:
|
||||
- \par translate=<translation vector>
|
||||
Translational transformation by given vector
|
||||
- \par rotate=(\<n1 vector\> \<n2 vector\>)
|
||||
Rotational transformation from unit vector n1 to n2
|
||||
- \par Rx=\<angle [deg] about x-axis\>
|
||||
Rotational transformation by given angle about x-axis
|
||||
- \par Ry=\<angle [deg] about y-axis\>
|
||||
Rotational transformation by given angle about y-axis
|
||||
- \par Rz=\<angle [deg] about z-axis\>
|
||||
Rotational transformation by given angle about z-axis
|
||||
- \par Ra=\<axis vector\> \<angle [deg] about axis\>
|
||||
Rotational transformation by given angle about given axis
|
||||
- \par scale=\<x-y-z scaling vector\>
|
||||
Anisotropic scaling by the given vector in the x, y, z
|
||||
coordinate directions
|
||||
|
||||
Options:
|
||||
- \par -translate \<vector\> \n
|
||||
Translates the points by the given vector.
|
||||
|
||||
- \par -rotate (\<vector\> \<vector\>) \n
|
||||
Rotates the points from the first vector to the second.
|
||||
|
||||
- \par -yawPitchRoll (\<yawdegrees\> \<pitchdegrees\> \<rolldegrees\>) \n
|
||||
Alternative rotation specification:
|
||||
yaw (rotation about z)
|
||||
pitch (rotation about y)
|
||||
roll (rotation about x)
|
||||
|
||||
- \par -rollPitchYaw (\<rolldegrees\> \<pitchdegrees\> \<yawdegrees\>) \n
|
||||
Alternative rotation specification:
|
||||
roll (rotation about x)
|
||||
pitch (rotation about y)
|
||||
yaw (rotation about z)
|
||||
|
||||
- \par -rotateFields \n
|
||||
In combination with \a -rotate, \a -yawPitchRoll or \a -rollPitchYaw
|
||||
additionally transform vector and tensor fields.
|
||||
Additionally transform vector and tensor fields.
|
||||
|
||||
- \par -scale \<vector\> \n
|
||||
Scales the points by the given vector.
|
||||
Example usage:
|
||||
transformPoints \
|
||||
"translate=(-0.05 -0.05 0), \
|
||||
Rz=45, \
|
||||
translate=(0.05 0.05 0)"
|
||||
|
||||
Any or all of the three transformation option types may be specified and are
|
||||
processed in the above order.
|
||||
See also
|
||||
Foam::transformer
|
||||
surfaceTransformPoints
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -71,10 +73,9 @@ Usage
|
||||
#include "pointFields.H"
|
||||
#include "transformField.H"
|
||||
#include "transformGeometricField.H"
|
||||
#include "mathematicalConstants.H"
|
||||
#include "unitConversion.H"
|
||||
|
||||
using namespace Foam;
|
||||
using namespace Foam::constant::mathematical;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -105,36 +106,26 @@ void rotateFields(const argList& args, const Time& runTime, const tensor& T)
|
||||
IOobjectList objects(mesh, runTime.timeName());
|
||||
|
||||
// Read vol fields.
|
||||
|
||||
PtrList<volScalarField> vsFlds;
|
||||
readAndRotateFields(vsFlds, mesh, T, objects);
|
||||
|
||||
PtrList<volVectorField> vvFlds;
|
||||
readAndRotateFields(vvFlds, mesh, T, objects);
|
||||
|
||||
PtrList<volSphericalTensorField> vstFlds;
|
||||
readAndRotateFields(vstFlds, mesh, T, objects);
|
||||
|
||||
PtrList<volSymmTensorField> vsymtFlds;
|
||||
readAndRotateFields(vsymtFlds, mesh, T, objects);
|
||||
|
||||
PtrList<volTensorField> vtFlds;
|
||||
readAndRotateFields(vtFlds, mesh, T, objects);
|
||||
|
||||
// Read surface fields.
|
||||
|
||||
PtrList<surfaceScalarField> ssFlds;
|
||||
readAndRotateFields(ssFlds, mesh, T, objects);
|
||||
|
||||
PtrList<surfaceVectorField> svFlds;
|
||||
readAndRotateFields(svFlds, mesh, T, objects);
|
||||
|
||||
PtrList<surfaceSphericalTensorField> sstFlds;
|
||||
readAndRotateFields(sstFlds, mesh, T, objects);
|
||||
|
||||
PtrList<surfaceSymmTensorField> ssymtFlds;
|
||||
readAndRotateFields(ssymtFlds, mesh, T, objects);
|
||||
|
||||
PtrList<surfaceTensorField> stFlds;
|
||||
readAndRotateFields(stFlds, mesh, T, objects);
|
||||
|
||||
@ -146,42 +137,32 @@ void rotateFields(const argList& args, const Time& runTime, const tensor& T)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addOption
|
||||
const wordList supportedTransformations
|
||||
(
|
||||
"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
|
||||
(
|
||||
"rollPitchYaw",
|
||||
"vector",
|
||||
"transform in terms of '(roll pitch yaw)' in degrees"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"yawPitchRoll",
|
||||
"vector",
|
||||
"transform in terms of '(yaw pitch roll)' in degrees"
|
||||
{"translate", "rotate", "Rx", "Ry", "Rz", "Ra", "scale"}
|
||||
);
|
||||
|
||||
{
|
||||
OStringStream supportedTransformationsStr;
|
||||
supportedTransformationsStr << supportedTransformations << endl;
|
||||
|
||||
argList::addNote
|
||||
(
|
||||
"Transforms a mesh e.g.\n"
|
||||
"transformPoints "
|
||||
"\"translate=(-0.586 0 -0.156), "
|
||||
"Ry=3.485, "
|
||||
"translate=(0.586 0 0.156)\"\n\n"
|
||||
"Supported transformations " + supportedTransformationsStr.str()
|
||||
);
|
||||
}
|
||||
|
||||
argList::validArgs.append("transformations");
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"rotateFields",
|
||||
"read and transform vector and tensor fields too"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"scale",
|
||||
"vector",
|
||||
"scale by the specified amount - eg, '(0.001 0.001 0.001)' for a "
|
||||
"uniform [mm] to [m] scaling"
|
||||
"transform vector and tensor fields"
|
||||
);
|
||||
|
||||
#include "addRegionOption.H"
|
||||
@ -189,8 +170,14 @@ int main(int argc, char *argv[])
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
|
||||
const string transformationString(args[1]);
|
||||
|
||||
#include "createTransforms.H"
|
||||
|
||||
const wordList regionNames(selectRegionNames(args, runTime));
|
||||
|
||||
const bool doRotateFields = args.optionFound("rotateFields");
|
||||
|
||||
forAll(regionNames, regioni)
|
||||
{
|
||||
const word& regionName = regionNames[regioni];
|
||||
@ -212,98 +199,11 @@ int main(int argc, char *argv[])
|
||||
)
|
||||
);
|
||||
|
||||
const bool doRotateFields = args.optionFound("rotateFields");
|
||||
transforms.transformPosition(points, points);
|
||||
|
||||
// this is not actually stringent enough:
|
||||
if (args.options().empty())
|
||||
if (doRotateFields)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No options supplied, please use one or more of "
|
||||
"-translate, -rotate or -scale options."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
vector v;
|
||||
if (args.optionReadIfPresent("translate", v))
|
||||
{
|
||||
Info<< "Translating points by " << v << endl;
|
||||
|
||||
points += v;
|
||||
}
|
||||
|
||||
if (args.optionFound("rotate"))
|
||||
{
|
||||
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;
|
||||
|
||||
points = transform(T, points);
|
||||
|
||||
if (doRotateFields)
|
||||
{
|
||||
rotateFields(args, runTime, T);
|
||||
}
|
||||
}
|
||||
else if (args.optionReadIfPresent("rollPitchYaw", v))
|
||||
{
|
||||
Info<< "Rotating points by" << nl
|
||||
<< " roll " << v.x() << nl
|
||||
<< " pitch " << v.y() << nl
|
||||
<< " yaw " << v.z() << nl;
|
||||
|
||||
// Convert to radians
|
||||
v *= pi/180.0;
|
||||
|
||||
quaternion R(quaternion::rotationSequence::XYZ, v);
|
||||
|
||||
Info<< "Rotating points by quaternion " << R << endl;
|
||||
points = transform(R, points);
|
||||
|
||||
if (doRotateFields)
|
||||
{
|
||||
rotateFields(args, runTime, R.R());
|
||||
}
|
||||
}
|
||||
else if (args.optionReadIfPresent("yawPitchRoll", v))
|
||||
{
|
||||
Info<< "Rotating points by" << nl
|
||||
<< " yaw " << v.x() << nl
|
||||
<< " pitch " << v.y() << nl
|
||||
<< " roll " << v.z() << nl;
|
||||
|
||||
// Convert to radians
|
||||
v *= pi/180.0;
|
||||
|
||||
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 (doRotateFields)
|
||||
{
|
||||
rotateFields(args, runTime, R.R());
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
rotateFields(args, runTime, transforms.T());
|
||||
}
|
||||
|
||||
// Set the precision of the points data to 10
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||
-I$(FOAM_UTILITIES)/mesh/manipulation/transformPoints
|
||||
|
||||
EXE_LIBS = \
|
||||
-lsurfMesh
|
||||
|
||||
@ -103,80 +103,11 @@ int main(int argc, char *argv[])
|
||||
const fileName surfFileName(args[2]);
|
||||
const fileName outFileName(args[3]);
|
||||
|
||||
#include "createTransforms.H"
|
||||
|
||||
Info<< "Reading surf from " << surfFileName << " ..." << nl
|
||||
<< "Writing surf to " << outFileName << " ..." << endl;
|
||||
|
||||
wordReList simpleTransformations;
|
||||
List<Tuple2<word, string>> transformations;
|
||||
dictArgList(transformationString, simpleTransformations, transformations);
|
||||
|
||||
transformer transforms;
|
||||
|
||||
forAll(transformations, i)
|
||||
{
|
||||
if (transformations[i].first() == "translate")
|
||||
{
|
||||
const vector v(IStringStream(transformations[i].second())());
|
||||
transforms = transformer::translation(v) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "rotate")
|
||||
{
|
||||
Pair<vector> n1n2(IStringStream(transformations[i].second())());
|
||||
|
||||
n1n2[0] /= mag(n1n2[0]);
|
||||
n1n2[1] /= mag(n1n2[1]);
|
||||
|
||||
transforms =
|
||||
transformer::rotation(rotationTensor(n1n2[0], n1n2[1]))
|
||||
& transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "Rx")
|
||||
{
|
||||
const scalar a
|
||||
(
|
||||
readScalar(IStringStream(transformations[i].second())())
|
||||
);
|
||||
transforms = transformer::rotation(Rx(degToRad(a))) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "Ry")
|
||||
{
|
||||
const scalar a
|
||||
(
|
||||
readScalar(IStringStream(transformations[i].second())())
|
||||
);
|
||||
transforms = transformer::rotation(Ry(degToRad(a))) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "Rz")
|
||||
{
|
||||
const scalar a
|
||||
(
|
||||
readScalar(IStringStream(transformations[i].second())())
|
||||
);
|
||||
transforms = transformer::rotation(Rz(degToRad(a))) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "Ra")
|
||||
{
|
||||
IStringStream istr(transformations[i].second());
|
||||
const vector v(istr);
|
||||
const scalar a(readScalar(istr));
|
||||
transforms = transformer::rotation(Ra(v, degToRad(a))) & transforms;
|
||||
}
|
||||
else if (transformations[i].first() == "scale")
|
||||
{
|
||||
const vector v(IStringStream(transformations[i].second())());
|
||||
transforms =
|
||||
transformer::scaling(diagTensor(v.x(), v.y(), v.z()))
|
||||
& transforms;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.printUsage();
|
||||
FatalErrorInFunction
|
||||
<< "Unknown transformation " << transformations[i].first()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
meshedSurface surf1(surfFileName);
|
||||
pointField points(surf1.points());
|
||||
transforms.transformPosition(points, points);
|
||||
|
||||
@ -10,6 +10,6 @@ cd "${0%/*}" || exit 1
|
||||
runApplication blockMesh
|
||||
runApplication topoSet
|
||||
runApplication refineMesh -overwrite
|
||||
runApplication transformPoints -scale "(0.01 0.01 0.01)"
|
||||
runApplication transformPoints "scale=(0.01 0.01 0.01)"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -4937,7 +4937,7 @@ _transformPoints_ ()
|
||||
local line=${COMP_LINE}
|
||||
local used=$(echo "$line" | grep -oE "\-[a-zA-Z]+ ")
|
||||
|
||||
opts="-allRegions -case -doc -fileHandler -help -hostRoots -libs -noFunctionObjects -parallel -region -rollPitchYaw -roots -rotate -rotateFields -scale -srcDoc -translate -yawPitchRoll"
|
||||
opts="-allRegions -case -doc -fileHandler -help -hostRoots -libs -noFunctionObjects -parallel -region -roots -rotateFields -srcDoc"
|
||||
for o in $used ; do opts="${opts/$o/}" ; done
|
||||
extra=""
|
||||
|
||||
@ -4947,7 +4947,7 @@ _transformPoints_ ()
|
||||
opts="" ; extra="-d" ;;
|
||||
-fileHandler)
|
||||
opts="uncollated collated masterUncollated" ; extra="" ;;
|
||||
-hostRoots|-libs|-region|-rollPitchYaw|-roots|-rotate|-scale|-translate|-yawPitchRoll)
|
||||
-hostRoots|-libs|-region|-roots)
|
||||
opts="" ; extra="" ;;
|
||||
*) ;;
|
||||
esac
|
||||
|
||||
@ -10,7 +10,7 @@ cp $FOAM_TUTORIALS/resources/geometry/NACA0012.obj.gz constant/geometry/
|
||||
application="$(getApplication)"
|
||||
|
||||
runApplication blockMesh
|
||||
runApplication transformPoints -scale "(1 0 1)"
|
||||
runApplication transformPoints "scale=(1 0 1)"
|
||||
runApplication extrudeMesh
|
||||
|
||||
runApplication $application
|
||||
|
||||
@ -10,7 +10,7 @@ cp $FOAM_TUTORIALS/resources/geometry/NACA0012.obj.gz constant/geometry/
|
||||
application="$(getApplication)"
|
||||
|
||||
runApplication blockMesh
|
||||
runApplication transformPoints -scale "(1 0 1)"
|
||||
runApplication transformPoints "scale=(1 0 1)"
|
||||
runApplication extrudeMesh
|
||||
|
||||
runApplication $application
|
||||
|
||||
@ -6,7 +6,7 @@ cd ${0%/*} || exit 1 # Run from this directory
|
||||
|
||||
runApplication blockMesh
|
||||
runApplication topoSet
|
||||
runApplication transformPoints -scale "(0.01 0.01 0.01)"
|
||||
runApplication transformPoints "scale=(0.01 0.01 0.01)"
|
||||
runApplication splitMeshRegions -cellZones -defaultRegionName fluid -overwrite
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -8,7 +8,7 @@ cd ${0%/*} || exit 1 # Run from this directory
|
||||
application=$(getApplication)
|
||||
|
||||
runApplication blockMesh
|
||||
runApplication transformPoints -scale '(1.6666 1 1)'
|
||||
runApplication transformPoints "scale=(1.6666 1 1)"
|
||||
|
||||
runApplication mirrorMesh -dict mirrorMeshDict.x -overwrite
|
||||
rm log.mirrorMesh
|
||||
|
||||
Reference in New Issue
Block a user