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

View File

@ -62,11 +62,11 @@ Description
transform transform
{ {
origin (0 0 0); origin (0 0 0);
rotationCentre (0 0 0);
rotation axisAngle; rotation axisAngle;
axis (1 0 0); axis (1 0 0);
angle 45; angle 45;
} }
} }
} }
\endverbatim \endverbatim
@ -82,6 +82,10 @@ Description
\endtable \endtable
Note 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, For surface formats that require geometry in a separate file,
it is the responsibility of the implementation (not the caller) it is the responsibility of the implementation (not the caller)
to ensure that this occurs. to ensure that this occurs.
@ -147,6 +151,9 @@ protected:
//- Output geometry scaling after rotate/translate //- Output geometry scaling after rotate/translate
scalar geometryScale_; scalar geometryScale_;
//- The centre of rotation (untranslate, translate)
point geometryCentre_;
//- Local coordinate system transformation //- Local coordinate system transformation
coordSystem::cartesian geometryTransform_; coordSystem::cartesian geometryTransform_;

View File

@ -111,6 +111,21 @@ debug
isoValue 1e5; isoValue 1e5;
regularise true; regularise true;
interpolate 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 // Top channel