ENH: support rotationCentre for surface output formats (#2565)

- as an alternative output transform (supplementary to the regular
  coordinate system specification - issue #2505) it is now possible to
  specify the rotation centre directly.

  Example:

      formatOptions
      {
          vtk
          {
              scale 1000;  // m -> mm
              transform
              {
                  origin  (0 0 0);
                  rotationCentre  (1 0 0);
                  rotation axisAngle;
                  axis    (0 0 1);
                  angle   -45;
              }
          }
      }

   This behaves like the transformPoints and surfaceTransformPoints
   '-centre' option (formerly '-origin') in that it removes the
   specified amount from the point locations, applies the rotation and
   finally adds the specified amount back to the newly rotated point
   locations.

   The results of specifying a `rotationCentre` and a non-zero
   coordinate system `origin` may not be intuitively evident.
This commit is contained in:
Mark Olesen 2022-08-18 11:07:53 +02:00
parent e827c117e3
commit 7ea185b0b5
3 changed files with 61 additions and 16 deletions

View File

@ -144,6 +144,7 @@ Foam::surfaceWriter::surfaceWriter()
adjustedSurf_(),
mergeDim_(defaultMergeDim),
geometryScale_(1),
geometryCentre_(Zero),
geometryTransform_(),
upToDate_(false),
wroteGeom_(false),
@ -168,6 +169,7 @@ Foam::surfaceWriter::surfaceWriter(const dictionary& options)
options.readIfPresent("verbose", verbose_);
geometryScale_ = 1;
geometryCentre_ = Zero;
geometryTransform_.clear();
options.readIfPresent("scale", geometryScale_);
@ -175,8 +177,9 @@ Foam::surfaceWriter::surfaceWriter(const dictionary& options)
const dictionary* dictptr;
// Optional cartesian coordinate system transform
if ((dictptr = options.findDict("transform", keyType::LITERAL))!= nullptr)
if ((dictptr = options.findDict("transform", keyType::LITERAL)) != nullptr)
{
dictptr->readIfPresent("rotationCentre", geometryCentre_);
geometryTransform_ = coordSystem::cartesian(*dictptr);
}
@ -471,23 +474,43 @@ const Foam::meshedSurfRef& Foam::surfaceWriter::adjustSurface() const
{
adjustedSurf_.reset(surface());
if
(
geometryTransform_.valid()
&&
(
(magSqr(geometryTransform_.origin()) > ROOTVSMALL)
|| !geometryTransform_.R().is_identity()
)
)
tmp<pointField> tpts;
if (geometryTransform_.valid())
{
// Forward transform
adjustedSurf_.movePoints
(
geometryTransform_.globalPosition(adjustedSurf_.points0())
);
if (!geometryTransform_.R().is_identity())
{
if (magSqr(geometryCentre_) > ROOTVSMALL)
{
// Set centre of rotation,
// followed by forward transform (local -> global)
tpts =
geometryTransform_.globalPosition
(
adjustedSurf_.points0() - geometryCentre_
);
// Unset centre of rotation
tpts.ref() += geometryCentre_;
}
else
{
// Forward transform (local -> global)
tpts =
geometryTransform_.globalPosition
(
adjustedSurf_.points0()
);
}
}
else if (magSqr(geometryTransform_.origin()) > ROOTVSMALL)
{
// Translate only (local -> global)
tpts = (adjustedSurf_.points0() + geometryTransform_.origin());
}
}
adjustedSurf_.movePoints(tpts);
adjustedSurf_.scalePoints(geometryScale_);
}

View File

@ -62,11 +62,11 @@ Description
transform
{
origin (0 0 0);
rotationCentre (0 0 0);
rotation axisAngle;
axis (1 0 0);
angle 45;
}
}
}
\endverbatim
@ -82,6 +82,10 @@ Description
\endtable
Note
The \c transform sub-dictionary also supports a \c rotationCentre
keyword which applies \em untranslate by that amount prior to the rotation,
and subsequently followed by a \em translate.
For surface formats that require geometry in a separate file,
it is the responsibility of the implementation (not the caller)
to ensure that this occurs.
@ -147,6 +151,9 @@ protected:
//- Output geometry scaling after rotate/translate
scalar geometryScale_;
//- The centre of rotation (untranslate, translate)
point geometryCentre_;
//- Local coordinate system transformation
coordSystem::cartesian geometryTransform_;

View File

@ -111,6 +111,21 @@ debug
isoValue 1e5;
regularise true;
interpolate true;
formatOptions
{
ensight
{
transform
{
origin (0 0 0);
rotationCentre (0.025 0 0);
rotation axisAngle;
axis (0 1 0);
angle 90;
}
}
}
}
// Top channel