Commit 22cf7b84 authored by Andrew Heather's avatar Andrew Heather

ENH: runTimePostProcessing FO camera update

    - Removed the camera 'mode'
    - The (old) static camera was only appropriate when parallel
      projection was inactive, and the view was centred at (0 0 0)
    - Camera input now always requires 'position' and 'focalPoint'
    - Clip box is now optional.  Note that this is applied after the
      camera
      set-up and so will override the camera position
    - View angle is only appropriate when not using parallel projection
    - Zoom now required, applied after all other operations
      - 1 = do nothing, >1 = zoom in, <1 = zoom out

    Example input:

        camera
        {
            // Total number of frames to generate
            nFrameTotal 1;

            // Parallel projection flag
            parallelProjection no;

            // Optional clippling box
            clipBox     (-0.0206 -0.0254 -0.0005) (0.29 0.0254 0.0005);
            focalPoint  (0 0 0);
            up          (0 1 0);
            position    (0 0 1);
            viewAngle   20;
            zoom        1.1;
        }
parent 7a6c0bce
......@@ -38,28 +38,6 @@ License
#include "vtkRenderWindow.h"
#include "vtkWindowToImageFilter.h"
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
namespace Foam
{
template<>
const char* NamedEnum
<
functionObjects::runTimePostPro::scene::modeType,
2
>::names[] =
{
"static",
"flightPath"
};
}
const Foam::NamedEnum
<
Foam::functionObjects::runTimePostPro::scene::modeType,
2
> modeTypeNames_;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
......@@ -92,9 +70,6 @@ void Foam::functionObjects::runTimePostPro::scene::readCamera
}
}
dict.lookup("parallelProjection") >> parallelProjection_;
if (nFrameTotal_ > 1)
{
scalar endPosition = dict.lookupOrDefault<scalar>("endPosition", 1);
......@@ -107,77 +82,28 @@ void Foam::functionObjects::runTimePostPro::scene::readCamera
dPosition_ = (endPosition - startPosition_)/scalar(nFrameTotal_ - 1);
}
mode_ = modeTypeNames_.read(dict.lookup("mode"));
cameraPosition_ = Function1<vector>::New("position", dict);
cameraFocalPoint_ = Function1<point>::New("focalPoint", dict);
cameraUp_ = Function1<vector>::New("up", dict);
word coeffsName = modeTypeNames_[mode_] + word("Coeffs");
const dictionary& coeffs = dict.subDict(coeffsName);
switch (mode_)
dict.readIfPresent("clipBox", clipBox_);
dict.lookup("parallelProjection") >> parallelProjection_;
if (!parallelProjection_)
{
case mtStatic:
if (dict.found("viewAngle"))
{
clipBox_ = boundBox(coeffs.lookup("clipBox"));
const vector lookDir(vector(coeffs.lookup("lookDir")));
cameraPosition_.reset
(
new Function1Types::Constant<point>("position", -lookDir)
);
const vector focalPoint(coeffs.lookup("focalPoint"));
cameraFocalPoint_.reset
(
new Function1Types::Constant<point>("focalPoint", focalPoint)
);
const vector up(coeffs.lookup("up"));
cameraUp_.reset(new Function1Types::Constant<point>("up", up));
if (nFrameTotal_ > 1)
{
WarningInFunction
<< "Static mode with nFrames > 1 - please check your setup"
<< endl;
}
break;
cameraViewAngle_ = Function1<scalar>::New("viewAngle", dict);
}
case mtFlightPath:
else
{
cameraPosition_.reset
(
Function1<vector>::New("position", coeffs).ptr()
);
cameraFocalPoint_.reset
cameraViewAngle_.reset
(
Function1<point>::New("focalPoint", coeffs).ptr()
new Function1Types::Constant<scalar>("viewAngle", 35.0)
);
cameraUp_.reset(Function1<vector>::New("up", coeffs).ptr());
break;
}
default:
{
FatalErrorInFunction
<< "Unhandled enumeration " << modeTypeNames_[mode_]
<< abort(FatalError);
}
}
if (dict.found("zoom"))
{
cameraZoom_.reset(Function1<scalar>::New("zoom", dict).ptr());
}
else
{
cameraZoom_.reset(new Function1Types::Constant<scalar>("zoom", 1.0));
}
if (dict.found("viewAngle"))
{
cameraViewAngle_.reset(Function1<scalar>::New("viewAngle", dict).ptr());
}
else
{
cameraViewAngle_.reset
(
new Function1Types::Constant<scalar>("viewAngle", 35.0)
);
}
cameraZoom_ = Function1<scalar>::New("zoom", dict);
}
......@@ -239,25 +165,11 @@ void Foam::functionObjects::runTimePostPro::scene::initialise
camera->SetParallelProjection(parallelProjection_);
renderer->SetActiveCamera(camera);
// Initialise the camera
const vector up = cameraUp_->value(position_);
const vector pos = cameraPosition_->value(position_);
const point focalPoint = cameraFocalPoint_->value(position_);
camera->SetViewUp(up.x(), up.y(), up.z());
camera->SetPosition(pos.x(), pos.y(), pos.z());
camera->SetFocalPoint(focalPoint.x(), focalPoint.y(), focalPoint.z());
camera->Modified();
// Add the lights
vtkSmartPointer<vtkLightKit> lightKit = vtkSmartPointer<vtkLightKit>::New();
lightKit->AddLightsToRenderer(renderer);
// For static mode initialise the clip box
if (mode_ == mtStatic)
if (clipBox_ != boundBox::greatBox)
{
const point& min = clipBox_.min();
const point& max = clipBox_.max();
......@@ -276,15 +188,10 @@ void Foam::functionObjects::runTimePostPro::scene::initialise
vtkSmartPointer<vtkPolyDataMapper>::New();
clipMapper->SetInputConnection(clipBox->GetOutputPort());
vtkSmartPointer<vtkActor> clipActor = vtkSmartPointer<vtkActor>::New();
clipActor->SetMapper(clipMapper);
clipActor->VisibilityOff();
renderer->AddActor(clipActor);
// Call resetCamera to fit clip box in view
clipActor->VisibilityOn();
renderer->ResetCamera();
clipActor->VisibilityOff();
clipBoxActor_ = vtkSmartPointer<vtkActor>::New();
clipBoxActor_->SetMapper(clipMapper);
clipBoxActor_->VisibilityOff();
renderer->AddActor(clipBoxActor_);
}
}
......@@ -294,26 +201,44 @@ void Foam::functionObjects::runTimePostPro::scene::setCamera
vtkRenderer* renderer
) const
{
if (mode_ == mtFlightPath)
vtkCamera* camera = renderer->GetActiveCamera();
if (parallelProjection_)
{
const vector up = cameraUp_->value(position_);
const vector pos = cameraPosition_->value(position_);
const point focalPoint = cameraFocalPoint_->value(position_);
vtkCamera* camera = renderer->GetActiveCamera();
camera->SetViewUp(up.x(), up.y(), up.z());
camera->SetPosition(pos.x(), pos.y(), pos.z());
camera->SetFocalPoint(focalPoint.x(), focalPoint.y(), focalPoint.z());
camera->Modified();
// Restore parallel scale to allow application of zoom (later)
camera->SetParallelScale(1);
}
if (!parallelProjection_)
else
{
// Restore viewAngle (it might be reset by clipping)
vtkCamera* camera = renderer->GetActiveCamera();
camera->SetViewAngle(cameraViewAngle_->value(position_));
camera->Modified();
}
const vector up = cameraUp_->value(position_);
const vector pos = cameraPosition_->value(position_);
const point focalPoint = cameraFocalPoint_->value(position_);
const scalar zoom = cameraZoom_->value(position_);
camera->SetViewUp(up.x(), up.y(), up.z());
camera->SetPosition(pos.x(), pos.y(), pos.z());
camera->SetFocalPoint(focalPoint.x(), focalPoint.y(), focalPoint.z());
// Apply clipping if required
// Note: possible optimisation - if the camera is static, this only needs
// to be done once on initialisation
if (clipBox_ != boundBox::greatBox)
{
// Call ResetCamera() to fit clip box in view
clipBoxActor_->VisibilityOn();
renderer->ResetCamera();
clipBoxActor_->VisibilityOff();
}
// Zoom applied after all other operations
camera->Zoom(zoom);
camera->Modified();
}
......@@ -338,12 +263,13 @@ Foam::functionObjects::runTimePostPro::scene::scene
obr_(obr),
name_(name),
colours_(),
mode_(mtStatic),
cameraPosition_(nullptr),
cameraFocalPoint_(nullptr),
cameraUp_(nullptr),
cameraViewAngle_(nullptr),
clipBox_(),
cameraZoom_(nullptr),
clipBox_(boundBox::greatBox),
clipBoxActor_(),
parallelProjection_(true),
nFrameTotal_(1),
startPosition_(0),
......@@ -381,7 +307,10 @@ Foam::scalar Foam::functionObjects::runTimePostPro::scene::position() const
}
void Foam::functionObjects::runTimePostPro::scene::read(const dictionary& dict)
void Foam::functionObjects::runTimePostPro::scene::read
(
const dictionary& dict
)
{
readCamera(dict.subDict("camera"));
readColours(dict.subDict("colours"));
......
......@@ -49,6 +49,7 @@ SourceFiles
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
class vtkActor;
class vtkRenderer;
class vtkRenderWindow;
......@@ -58,22 +59,12 @@ namespace functionObjects
{
namespace runTimePostPro
{
/*---------------------------------------------------------------------------*\
Class scene Declaration
\*---------------------------------------------------------------------------*/
class scene
{
public:
enum modeType{mtStatic, mtFlightPath};
NamedEnum<modeType, 2> modeTypeNames_;
private:
// Private data
//- Reference to the object registry
......@@ -88,7 +79,7 @@ private:
//- Read camera properties
void readCamera(const dictionary& dict);
//- Read solour properties
//- Read colour properties
void readColours(const dictionary& dict);
//- Disallow default bitwise copy construct
......@@ -108,9 +99,6 @@ protected:
// Camera settings
//- Mode
modeType mode_;
//- Position
autoPtr<Function1<point>> cameraPosition_;
......@@ -120,18 +108,23 @@ protected:
//- Up direction
autoPtr<Function1<vector>> cameraUp_;
//- Zoom level
autoPtr<Function1<scalar>> cameraZoom_;
//- View angle
autoPtr<Function1<scalar>> cameraViewAngle_;
//- Zoom: 1 = do nothing, >1 = zoom in, <1 = zoom out
// - perspective mode: reduces view angle
// - parallel mode: manipulate parallel scale
autoPtr<Function1<scalar>> cameraZoom_;
// Scene management
//- Clipping box
boundBox clipBox_;
//- Clipping box actor
vtkSmartPointer<vtkActor> clipBoxActor_;
//- Parallel projection flag
bool parallelProjection_;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment