mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
388 lines
13 KiB
C++
388 lines
13 KiB
C++
/*=========================================================================
|
|
|
|
Program: ParaView
|
|
Module: vtkPVContextView.cxx
|
|
|
|
Copyright (c) Kitware, Inc.
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkPVContextView.h"
|
|
|
|
#include "vtkAnnotationLink.h"
|
|
#include "vtkCamera.h"
|
|
#include "vtkChart.h"
|
|
#include "vtkChartRepresentation.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkContextInteractorStyle.h"
|
|
#include "vtkContextView.h"
|
|
#include "vtkCSVExporter.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationIntegerKey.h"
|
|
#include "vtkMultiProcessStream.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkProcessModule.h"
|
|
#include "vtkPVDataRepresentation.h"
|
|
#include "vtkPVOptions.h"
|
|
#include "vtkPVSynchronizedRenderWindows.h"
|
|
#include "vtkRenderer.h"
|
|
#include "vtkRenderWindow.h"
|
|
#include "vtkRenderWindowInteractor.h"
|
|
#include "vtkScatterPlotMatrix.h"
|
|
#include "vtkSelection.h"
|
|
#include "vtkTileDisplayHelper.h"
|
|
#include "vtkTilesHelper.h"
|
|
#include "vtkTimerLog.h"
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkPVContextView::vtkPVContextView()
|
|
: InteractorStyle()
|
|
{
|
|
vtkPVOptions* options = vtkProcessModule::GetProcessModule()?
|
|
vtkProcessModule::GetProcessModule()->GetOptions() : NULL;
|
|
|
|
this->UseOffscreenRenderingForScreenshots = false;
|
|
this->UseOffscreenRendering =
|
|
(options? options->GetUseOffscreenRendering() != 0 : false);
|
|
|
|
this->RenderWindow = this->SynchronizedWindows->NewRenderWindow();
|
|
this->RenderWindow->SetOffScreenRendering(this->UseOffscreenRendering? 1 : 0);
|
|
this->ContextView = vtkContextView::New();
|
|
|
|
// Let the application setup the interactor.
|
|
this->ContextView->SetRenderWindow(this->RenderWindow);
|
|
if (this->ContextView->GetInteractor())
|
|
{
|
|
this->ContextView->GetInteractor()->SetInteractorStyle(NULL);
|
|
}
|
|
this->ContextView->SetInteractor(NULL);
|
|
this->ContextView->GetRenderer()->AddObserver(
|
|
vtkCommand::StartEvent, this, &vtkPVContextView::OnStartRender);
|
|
this->ContextView->GetRenderer()->AddObserver(
|
|
vtkCommand::EndEvent, this, &vtkPVContextView::OnEndRender);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkPVContextView::~vtkPVContextView()
|
|
{
|
|
vtkTileDisplayHelper::GetInstance()->EraseTile(this->Identifier);
|
|
|
|
this->RenderWindow->Delete();
|
|
this->ContextView->Delete();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::Initialize(unsigned int id)
|
|
{
|
|
if (this->Identifier == id)
|
|
{
|
|
// already initialized
|
|
return;
|
|
}
|
|
this->SynchronizedWindows->AddRenderWindow(id, this->RenderWindow);
|
|
this->SynchronizedWindows->AddRenderer(id, this->ContextView->GetRenderer());
|
|
this->Superclass::Initialize(id);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::SetupInteractor(vtkRenderWindowInteractor* iren)
|
|
{
|
|
// Disable interactor on server processes (or batch processes), since
|
|
// otherwise the vtkContextInteractorStyle triggers renders on changes to the
|
|
// vtkContextView which is bad and can cause deadlock (BUG #122651).
|
|
if (this->GetLocalProcessSupportsInteraction() == false)
|
|
{
|
|
// We don't setup interactor on non-driver processes.
|
|
return;
|
|
}
|
|
this->ContextView->SetInteractor(iren);
|
|
this->InteractorStyle->SetScene(this->ContextView->GetScene());
|
|
if (iren)
|
|
{
|
|
iren->SetInteractorStyle(this->InteractorStyle.GetPointer());
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkRenderWindowInteractor* vtkPVContextView::GetInteractor()
|
|
{
|
|
return this->ContextView->GetInteractor();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::SetUseOffscreenRendering(bool use_offscreen)
|
|
{
|
|
if (this->UseOffscreenRendering == use_offscreen)
|
|
{
|
|
return;
|
|
}
|
|
|
|
vtkPVOptions* options = vtkProcessModule::GetProcessModule()->GetOptions();
|
|
bool process_use_offscreen = options->GetUseOffscreenRendering() != 0;
|
|
|
|
this->UseOffscreenRendering = use_offscreen || process_use_offscreen;
|
|
this->GetRenderWindow()->SetOffScreenRendering(this->UseOffscreenRendering);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::Update()
|
|
{
|
|
vtkMultiProcessController* s_controller =
|
|
this->SynchronizedWindows->GetClientServerController();
|
|
vtkMultiProcessController* d_controller =
|
|
this->SynchronizedWindows->GetClientDataServerController();
|
|
vtkMultiProcessController* p_controller =
|
|
vtkMultiProcessController::GetGlobalController();
|
|
vtkMultiProcessStream stream;
|
|
|
|
if (this->SynchronizedWindows->GetLocalProcessIsDriver())
|
|
{
|
|
std::vector<int> need_delivery;
|
|
int num_reprs = this->GetNumberOfRepresentations();
|
|
for (int cc=0; cc < num_reprs; cc++)
|
|
{
|
|
vtkPVDataRepresentation* repr = vtkPVDataRepresentation::SafeDownCast(
|
|
this->GetRepresentation(cc));
|
|
if (repr && repr->GetNeedUpdate())
|
|
{
|
|
need_delivery.push_back(cc);
|
|
}
|
|
}
|
|
stream << static_cast<int>(need_delivery.size());
|
|
for (size_t cc=0; cc < need_delivery.size(); cc++)
|
|
{
|
|
stream << need_delivery[cc];
|
|
}
|
|
|
|
if (s_controller)
|
|
{
|
|
s_controller->Send(stream, 1, 998878);
|
|
}
|
|
if (d_controller)
|
|
{
|
|
d_controller->Send(stream, 1, 998878);
|
|
}
|
|
if (p_controller)
|
|
{
|
|
p_controller->Broadcast(stream, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (s_controller)
|
|
{
|
|
s_controller->Receive(stream, 1, 998878);
|
|
}
|
|
if (d_controller)
|
|
{
|
|
d_controller->Receive(stream, 1, 998878);
|
|
}
|
|
if (p_controller)
|
|
{
|
|
p_controller->Broadcast(stream, 0);
|
|
}
|
|
}
|
|
|
|
int size;
|
|
stream >> size;
|
|
for (int cc=0; cc < size; cc++)
|
|
{
|
|
int index;
|
|
stream >> index;
|
|
vtkPVDataRepresentation* repr = vtkPVDataRepresentation::SafeDownCast(
|
|
this->GetRepresentation(index));
|
|
if (repr)
|
|
{
|
|
repr->MarkModified();
|
|
}
|
|
}
|
|
this->Superclass::Update();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::StillRender()
|
|
{
|
|
vtkTimerLog::MarkStartEvent("Still Render");
|
|
this->Render(false);
|
|
vtkTimerLog::MarkEndEvent("Still Render");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::InteractiveRender()
|
|
{
|
|
vtkTimerLog::MarkStartEvent("Interactive Render");
|
|
this->Render(true);
|
|
vtkTimerLog::MarkEndEvent("Interactive Render");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::Render(bool vtkNotUsed(interactive))
|
|
{
|
|
this->SynchronizedWindows->SetEnabled(this->InTileDisplayMode());
|
|
this->SynchronizedWindows->BeginRender(this->GetIdentifier());
|
|
|
|
// Call Render() on local render window only on the client (or root node in
|
|
// batch mode).
|
|
if (this->SynchronizedWindows->GetLocalProcessIsDriver() ||
|
|
this->InTileDisplayMode())
|
|
{
|
|
vtkTimerLog::MarkStartEvent("vtkPVContextView::PrepareForRender");
|
|
// on rendering-nodes call Render-pass so that representations can update the
|
|
// vtk-charts as needed.
|
|
this->CallProcessViewRequest(vtkPVView::REQUEST_RENDER(),
|
|
this->RequestInformation, this->ReplyInformationVector);
|
|
vtkTimerLog::MarkEndEvent("vtkPVContextView::PrepareForRender");
|
|
|
|
this->ContextView->Render();
|
|
}
|
|
this->SynchronizedWindows->SetEnabled(false);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::OnStartRender()
|
|
{
|
|
vtkTileDisplayHelper::GetInstance()->EraseTile(this->Identifier,
|
|
this->ContextView->GetRenderer()->GetActiveCamera()->GetLeftEye());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::OnEndRender()
|
|
{
|
|
if (this->SynchronizedWindows->GetLocalProcessIsDriver() ||
|
|
!this->InTileDisplayMode())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// this code needs to be called on only server-nodes in tile-display mode.
|
|
|
|
double viewport[4];
|
|
this->ContextView->GetRenderer()->GetViewport(viewport);
|
|
|
|
int tile_dims[2], tile_mullions[2];
|
|
this->SynchronizedWindows->GetTileDisplayParameters(tile_dims, tile_mullions);
|
|
|
|
double tile_viewport[4];
|
|
this->GetRenderWindow()->GetTileViewport(tile_viewport);
|
|
|
|
double physical_viewport[4];
|
|
vtkSmartPointer<vtkTilesHelper> tilesHelper = vtkSmartPointer<vtkTilesHelper>::New();
|
|
tilesHelper->SetTileDimensions(tile_dims);
|
|
tilesHelper->SetTileMullions(tile_mullions);
|
|
tilesHelper->SetTileWindowSize(this->GetRenderWindow()->GetActualSize());
|
|
if (tilesHelper->GetPhysicalViewport(viewport,
|
|
vtkMultiProcessController::GetGlobalController()->GetLocalProcessId(),
|
|
physical_viewport))
|
|
{
|
|
// When tiling, vtkContextActor renders the result at the
|
|
// "physical_viewport" location on the window. So we grab the image only
|
|
// from that section of the view.
|
|
vtkSynchronizedRenderers::vtkRawImage image;
|
|
this->ContextView->GetRenderer()->SetViewport(physical_viewport);
|
|
image.Capture(this->ContextView->GetRenderer());
|
|
this->ContextView->GetRenderer()->SetViewport(viewport);
|
|
|
|
vtkTileDisplayHelper::GetInstance()->SetTile(
|
|
this->Identifier,
|
|
physical_viewport,
|
|
this->ContextView->GetRenderer(),
|
|
image);
|
|
}
|
|
|
|
vtkTileDisplayHelper::GetInstance()->FlushTiles(this->Identifier,
|
|
this->ContextView->GetRenderer()->GetActiveCamera()->GetLeftEye());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
template <class T>
|
|
vtkSelection* vtkPVContextView::GetSelectionImplementation(T* chart)
|
|
{
|
|
if (vtkSelection* selection = chart->GetAnnotationLink()->GetCurrentSelection())
|
|
{
|
|
if (this->SelectionClone == NULL ||
|
|
this->SelectionClone->GetMTime() < selection->GetMTime() ||
|
|
this->SelectionClone->GetMTime() < chart->GetAnnotationLink()->GetMTime())
|
|
{
|
|
// we need to treat vtkSelection obtained from vtkAnnotationLink as
|
|
// constant and not modify it. Hence, we create a clone.
|
|
this->SelectionClone = vtkSmartPointer<vtkSelection>::New();
|
|
this->SelectionClone->ShallowCopy(selection);
|
|
|
|
// Allow the view to transform the selection as appropriate since the raw
|
|
// selection created by the VTK view is on the "transformed" data put in
|
|
// the view and not original input data.
|
|
if (this->MapSelectionToInput(this->SelectionClone) == false)
|
|
{
|
|
this->SelectionClone->Initialize();
|
|
}
|
|
}
|
|
return this->SelectionClone;
|
|
}
|
|
this->SelectionClone = NULL;
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSelection* vtkPVContextView::GetSelection()
|
|
{
|
|
if (vtkChart *chart = vtkChart::SafeDownCast(this->GetContextItem()))
|
|
{
|
|
return this->GetSelectionImplementation(chart);
|
|
}
|
|
else if (vtkScatterPlotMatrix* schart = vtkScatterPlotMatrix::SafeDownCast(this->GetContextItem()))
|
|
{
|
|
return this->GetSelectionImplementation(schart);
|
|
}
|
|
|
|
vtkWarningMacro("Unsupported context item type.");
|
|
this->SelectionClone = NULL;
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkPVContextView::MapSelectionToInput(vtkSelection* sel)
|
|
{
|
|
for (int cc = 0, max = this->GetNumberOfRepresentations(); cc < max; cc++)
|
|
{
|
|
vtkChartRepresentation* repr = vtkChartRepresentation::SafeDownCast(
|
|
this->GetRepresentation(cc));
|
|
if (repr && repr->GetVisibility() && repr->MapSelectionToInput(sel))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
// error! we cannot have a selection created in the view, there's no visible
|
|
// representation!
|
|
return false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkPVContextView::Export(vtkCSVExporter* exporter)
|
|
{
|
|
exporter->Open(vtkCSVExporter::STREAM_COLUMNS);
|
|
for (int cc=0, max=this->GetNumberOfRepresentations(); cc < max; cc++)
|
|
{
|
|
vtkChartRepresentation* repr = vtkChartRepresentation::SafeDownCast(
|
|
this->GetRepresentation(cc));
|
|
if (repr && repr->GetVisibility() && !repr->Export(exporter))
|
|
{
|
|
exporter->Abort();
|
|
vtkErrorMacro("Failed to export to CSV. Exporting may not be supported by this view.");
|
|
return false;
|
|
}
|
|
}
|
|
exporter->Close();
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkPVContextView::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|