mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
789 lines
24 KiB
C++
789 lines
24 KiB
C++
/*=========================================================================
|
|
|
|
Program: ParaView
|
|
Module: vtkSMViewProxy.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 "vtkSMViewProxy.h"
|
|
|
|
#include "vtkClientServerStream.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkErrorCode.h"
|
|
#include "vtkGenericRenderWindowInteractor.h"
|
|
#include "vtkImageData.h"
|
|
#include "vtkMath.h"
|
|
#include "vtkNew.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkProcessModule.h"
|
|
#include "vtkPVOptions.h"
|
|
#include "vtkPVView.h"
|
|
#include "vtkPVXMLElement.h"
|
|
#include "vtkRendererCollection.h"
|
|
#include "vtkRenderer.h"
|
|
#include "vtkRenderWindow.h"
|
|
#include "vtkSmartPointer.h"
|
|
#include "vtkSMParaViewPipelineControllerWithRendering.h"
|
|
#include "vtkSMProperty.h"
|
|
#include "vtkSMProxyManager.h"
|
|
#include "vtkSMRepresentationProxy.h"
|
|
#include "vtkSMSession.h"
|
|
#include "vtkSMSessionProxyManager.h"
|
|
#include "vtkSMUncheckedPropertyHelper.h"
|
|
#include "vtkSMUtilities.h"
|
|
|
|
#include <assert.h>
|
|
|
|
namespace
|
|
{
|
|
const char* vtkGetRepresentationNameFromHints(
|
|
const char* viewType, vtkPVXMLElement* hints, int port)
|
|
{
|
|
if (!hints)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
for (unsigned int cc=0, max=hints->GetNumberOfNestedElements(); cc<max; ++cc)
|
|
{
|
|
vtkPVXMLElement* child = hints->GetNestedElement(cc);
|
|
if (child == NULL || child->GetName() == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// LEGACY: support DefaultRepresentations hint.
|
|
// <Hints>
|
|
// <DefaultRepresentations representation="Foo" />
|
|
// </Hints>
|
|
if (strcmp(child->GetName(), "DefaultRepresentations") == 0)
|
|
{
|
|
return child->GetAttribute("representation");
|
|
}
|
|
|
|
// <Hints>
|
|
// <Representation port="outputPort" view="ViewName" type="ReprName" />
|
|
// </Hints>
|
|
else if (strcmp(child->GetName(), "Representation") == 0 &&
|
|
// has an attribute "view" that matches the viewType.
|
|
child->GetAttribute("view") &&
|
|
strcmp(child->GetAttribute("view"), viewType) == 0 &&
|
|
child->GetAttribute("type") != NULL)
|
|
{
|
|
// if port is present, it must match "port".
|
|
int xmlPort;
|
|
if (child->GetScalarAttribute("port", &xmlPort) == 0 || xmlPort == port)
|
|
{
|
|
return child->GetAttribute("type");
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
};
|
|
|
|
bool vtkSMViewProxy::TransparentBackground = false;
|
|
|
|
vtkStandardNewMacro(vtkSMViewProxy);
|
|
//----------------------------------------------------------------------------
|
|
vtkSMViewProxy::vtkSMViewProxy()
|
|
{
|
|
this->SetLocation(vtkProcessModule::CLIENT_AND_SERVERS);
|
|
this->DefaultRepresentationName = 0;
|
|
this->Enable = true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMViewProxy::~vtkSMViewProxy()
|
|
{
|
|
this->SetDefaultRepresentationName(0);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkView* vtkSMViewProxy::GetClientSideView()
|
|
{
|
|
if (this->ObjectsCreated)
|
|
{
|
|
return vtkView::SafeDownCast(this->GetClientSideObject());
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMViewProxy::CreateVTKObjects()
|
|
{
|
|
if (this->ObjectsCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->Superclass::CreateVTKObjects();
|
|
|
|
// If prototype, no need to go further...
|
|
if(this->Location == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!this->ObjectsCreated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
vtkClientServerStream stream;
|
|
stream << vtkClientServerStream::Invoke
|
|
<< VTKOBJECT(this)
|
|
<< "Initialize"
|
|
<< static_cast<int>(this->GetGlobalID())
|
|
<< vtkClientServerStream::End;
|
|
this->ExecuteStream(stream);
|
|
|
|
vtkObject::SafeDownCast(this->GetClientSideObject())->AddObserver(
|
|
vtkPVView::ViewTimeChangedEvent,
|
|
this, &vtkSMViewProxy::ViewTimeChanged);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMViewProxy::ViewTimeChanged()
|
|
{
|
|
vtkSMPropertyHelper helper1(this, "Representations");
|
|
for (unsigned int cc=0; cc < helper1.GetNumberOfElements(); cc++)
|
|
{
|
|
vtkSMRepresentationProxy* repr = vtkSMRepresentationProxy::SafeDownCast(
|
|
helper1.GetAsProxy(cc));
|
|
if (repr)
|
|
{
|
|
repr->ViewTimeChanged();
|
|
}
|
|
}
|
|
|
|
vtkSMPropertyHelper helper2(this, "HiddenRepresentations", true);
|
|
for (unsigned int cc=0; cc < helper2.GetNumberOfElements(); cc++)
|
|
{
|
|
vtkSMRepresentationProxy* repr = vtkSMRepresentationProxy::SafeDownCast(
|
|
helper2.GetAsProxy(cc));
|
|
if (repr)
|
|
{
|
|
repr->ViewTimeChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMViewProxy::StillRender()
|
|
{
|
|
// bug 0013947
|
|
// on Mac OSX don't render into invalid drawable, all subsequent
|
|
// OpenGL calls fail with invalid framebuffer operation.
|
|
if (this->IsContextReadyForRendering() == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int interactive = 0;
|
|
this->InvokeEvent(vtkCommand::StartEvent, &interactive);
|
|
this->GetSession()->PrepareProgress();
|
|
// We call update separately from the render. This is done so that we don't
|
|
// get any synchronization issues with GUI responding to the data-updated
|
|
// event by making some data information requests(for example). If those
|
|
// happen while StillRender/InteractiveRender is being executed on the server
|
|
// side then we get deadlocks.
|
|
this->Update();
|
|
|
|
vtkTypeUInt32 render_location = this->PreRender(interactive==1);
|
|
|
|
if (this->ObjectsCreated)
|
|
{
|
|
vtkClientServerStream stream;
|
|
stream << vtkClientServerStream::Invoke
|
|
<< VTKOBJECT(this)
|
|
<< "StillRender"
|
|
<< vtkClientServerStream::End;
|
|
this->ExecuteStream(stream, false, render_location);
|
|
}
|
|
|
|
this->PostRender(interactive==1);
|
|
this->GetSession()->CleanupPendingProgress();
|
|
this->InvokeEvent(vtkCommand::EndEvent, &interactive);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMViewProxy::InteractiveRender()
|
|
{
|
|
int interactive = 1;
|
|
this->InvokeEvent(vtkCommand::StartEvent, &interactive);
|
|
this->GetSession()->PrepareProgress();
|
|
|
|
// Interactive render will not call Update() at all. It's expected that you
|
|
// must have either called a StillRender() or an Update() before triggering an
|
|
// interactive render. This is critical to keep interactive rates fast when
|
|
// working over a slow client-server connection.
|
|
// this->Update();
|
|
|
|
vtkTypeUInt32 render_location = this->PreRender(interactive==1);
|
|
|
|
if (this->ObjectsCreated)
|
|
{
|
|
vtkClientServerStream stream;
|
|
stream << vtkClientServerStream::Invoke
|
|
<< VTKOBJECT(this)
|
|
<< "InteractiveRender"
|
|
<< vtkClientServerStream::End;
|
|
this->ExecuteStream(stream, false, render_location);
|
|
}
|
|
|
|
this->PostRender(interactive==1);
|
|
this->GetSession()->CleanupPendingProgress();
|
|
this->InvokeEvent(vtkCommand::EndEvent, &interactive);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMViewProxy::Update()
|
|
{
|
|
if (this->ObjectsCreated && this->NeedsUpdate)
|
|
{
|
|
vtkClientServerStream stream;
|
|
|
|
// To avoid race conditions in multi-client modes, we are taking a peculiar
|
|
// approach. Any ivar that affect parallel communication are overridden
|
|
// using the client-side values in the same ExecuteStream() call. That
|
|
// ensures that two clients cannot enter race condition. This results in minor
|
|
// increase in the size of the messages sent, but overall the benefits are
|
|
// greater.
|
|
vtkPVView* pvview = vtkPVView::SafeDownCast(this->GetClientSideObject());
|
|
if (pvview)
|
|
{
|
|
int use_cache = pvview->GetUseCache()? 1 : 0;
|
|
stream << vtkClientServerStream::Invoke
|
|
<< VTKOBJECT(this)
|
|
<< "SetUseCache" << use_cache
|
|
<< vtkClientServerStream::End;
|
|
}
|
|
stream << vtkClientServerStream::Invoke
|
|
<< VTKOBJECT(this)
|
|
<< "Update"
|
|
<< vtkClientServerStream::End;
|
|
this->GetSession()->PrepareProgress();
|
|
this->ExecuteStream(stream);
|
|
this->GetSession()->CleanupPendingProgress();
|
|
|
|
unsigned int numProducers = this->GetNumberOfProducers();
|
|
for (unsigned int i=0; i<numProducers; i++)
|
|
{
|
|
vtkSMRepresentationProxy* repr = vtkSMRepresentationProxy::SafeDownCast(
|
|
this->GetProducerProxy(i));
|
|
if (repr)
|
|
{
|
|
repr->ViewUpdated(this);
|
|
}
|
|
else
|
|
{
|
|
//this->GetProducerProxy(i)->PostUpdateData();
|
|
}
|
|
}
|
|
|
|
this->PostUpdateData();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMRepresentationProxy* vtkSMViewProxy::CreateDefaultRepresentation(
|
|
vtkSMProxy* proxy, int outputPort)
|
|
{
|
|
assert("The session should be valid" && this->Session);
|
|
|
|
vtkSMSourceProxy* producer = vtkSMSourceProxy::SafeDownCast(proxy);
|
|
if (
|
|
(producer == NULL) ||
|
|
(outputPort < 0) ||
|
|
(static_cast<int>(producer->GetNumberOfOutputPorts()) <= outputPort) ||
|
|
(producer->GetSession() != this->GetSession()))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// Update with time from the view to ensure we have up-to-date data.
|
|
double view_time = vtkSMPropertyHelper(this, "ViewTime").GetAsDouble();
|
|
producer->UpdatePipeline(view_time);
|
|
|
|
const char* representationType =
|
|
this->GetRepresentationType(producer, outputPort);
|
|
if (!representationType)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
vtkSMSessionProxyManager* pxm = this->GetSessionProxyManager();
|
|
vtkSmartPointer<vtkSMProxy> p;
|
|
p.TakeReference(pxm->NewProxy("representations", representationType));
|
|
vtkSMRepresentationProxy* repr = vtkSMRepresentationProxy::SafeDownCast(p);
|
|
if (repr)
|
|
{
|
|
repr->Register(this);
|
|
return repr;
|
|
}
|
|
vtkWarningMacro("Failed to create representation (representations,"
|
|
<< representationType <<").");
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const char* vtkSMViewProxy::GetRepresentationType(
|
|
vtkSMSourceProxy* producer, int outputPort)
|
|
{
|
|
assert(producer &&
|
|
static_cast<int>(producer->GetNumberOfOutputPorts()) > outputPort);
|
|
|
|
// Process producer hints to see if indicates what type of representation
|
|
// to create for this view.
|
|
if (const char* reprName = vtkGetRepresentationNameFromHints(
|
|
this->GetXMLName(), producer->GetHints(), outputPort))
|
|
{
|
|
return reprName;
|
|
}
|
|
|
|
// check if we have default representation name specified in XML.
|
|
if (this->DefaultRepresentationName)
|
|
{
|
|
vtkSMSessionProxyManager* pxm = this->GetSessionProxyManager();
|
|
vtkSMProxy* prototype = pxm->GetPrototypeProxy(
|
|
"representations", this->DefaultRepresentationName);
|
|
if (prototype)
|
|
{
|
|
vtkSMProperty* inputProp = prototype->GetProperty("Input");
|
|
vtkSMUncheckedPropertyHelper helper(inputProp);
|
|
helper.Set(producer, outputPort);
|
|
bool acceptable = (inputProp->IsInDomains() > 0);
|
|
helper.SetNumberOfElements(0);
|
|
|
|
if (acceptable)
|
|
{
|
|
return this->DefaultRepresentationName;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMViewProxy::CanDisplayData(vtkSMSourceProxy* producer, int outputPort)
|
|
{
|
|
if (producer == NULL || outputPort < 0 ||
|
|
static_cast<int>(producer->GetNumberOfOutputPorts()) <= outputPort ||
|
|
producer->GetSession() != this->GetSession())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const char* type = this->GetRepresentationType(producer, outputPort);
|
|
if (type != NULL)
|
|
{
|
|
vtkSMSessionProxyManager* pxm = this->GetSessionProxyManager();
|
|
return (pxm->GetPrototypeProxy("representations", type) != NULL);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMRepresentationProxy* vtkSMViewProxy::FindRepresentation(
|
|
vtkSMSourceProxy* producer, int outputPort)
|
|
{
|
|
vtkSMPropertyHelper helper (this, "Representations");
|
|
for (unsigned int cc=0, max=helper.GetNumberOfElements(); cc < max; ++cc)
|
|
{
|
|
vtkSMRepresentationProxy* repr =
|
|
vtkSMRepresentationProxy::SafeDownCast(helper.GetAsProxy(cc));
|
|
if (repr &&
|
|
repr->GetProperty("Input"))
|
|
{
|
|
vtkSMPropertyHelper helper2(repr, "Input");
|
|
if (helper2.GetAsProxy() == producer &&
|
|
static_cast<int>(helper2.GetOutputPort()) == outputPort)
|
|
{
|
|
return repr;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkSMViewProxy::ReadXMLAttributes(
|
|
vtkSMSessionProxyManager* pm, vtkPVXMLElement* element)
|
|
{
|
|
if (!this->Superclass::ReadXMLAttributes(pm, element))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
const char* repr_name = element->GetAttribute("representation_name");
|
|
if (repr_name)
|
|
{
|
|
this->SetDefaultRepresentationName(repr_name);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
class vtkSMViewProxy::vtkRendererSaveInfo
|
|
{
|
|
public:
|
|
vtkRendererSaveInfo(vtkRenderer* renderer)
|
|
: Gradient(renderer->GetGradientBackground())
|
|
, Textured(renderer->GetTexturedBackground())
|
|
, Red(renderer->GetBackground()[0])
|
|
, Green(renderer->GetBackground()[1])
|
|
, Blue(renderer->GetBackground()[2])
|
|
{
|
|
}
|
|
|
|
const bool Gradient;
|
|
const bool Textured;
|
|
const double Red;
|
|
const double Green;
|
|
const double Blue;
|
|
private:
|
|
vtkRendererSaveInfo(const vtkRendererSaveInfo&); // Not implemented
|
|
void operator=(const vtkRendererSaveInfo&); // Not implemented
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageData* vtkSMViewProxy::CaptureWindow(int magnification)
|
|
{
|
|
vtkRenderWindow* window = this->GetRenderWindow();
|
|
|
|
if (window && this->TransparentBackground)
|
|
{
|
|
vtkRendererCollection* renderers = window->GetRenderers();
|
|
vtkRenderer* renderer = renderers->GetFirstRenderer();
|
|
while (renderer)
|
|
{
|
|
if (renderer->GetErase())
|
|
{
|
|
// Found a background-writing renderer.
|
|
break;
|
|
}
|
|
|
|
renderer = renderers->GetNextItem();
|
|
}
|
|
|
|
if (!renderer)
|
|
{
|
|
// No renderer?
|
|
return NULL;
|
|
}
|
|
|
|
vtkRendererSaveInfo* info = this->PrepareRendererBackground(renderer, 255, 255, 255, true);
|
|
vtkImageData* captureWhite = this->CaptureWindowSingle(magnification);
|
|
|
|
this->PrepareRendererBackground(renderer, 0, 0, 0, false);
|
|
vtkImageData* captureBlack = this->CaptureWindowSingle(magnification);
|
|
|
|
vtkImageData* capture = vtkImageData::New();
|
|
capture->CopyStructure(captureWhite);
|
|
capture->AllocateScalars(VTK_UNSIGNED_CHAR, 4);
|
|
|
|
const unsigned char* white;
|
|
const unsigned char* black;
|
|
unsigned char* out;
|
|
vtkIdType whiteStep[3];
|
|
vtkIdType blackStep[3];
|
|
vtkIdType outStep[3];
|
|
|
|
white = static_cast<const unsigned char*>(captureWhite->GetScalarPointerForExtent(captureWhite->GetExtent()));
|
|
black = static_cast<const unsigned char*>(captureBlack->GetScalarPointerForExtent(captureBlack->GetExtent()));
|
|
out = static_cast<unsigned char*>(capture->GetScalarPointerForExtent(capture->GetExtent()));
|
|
|
|
captureWhite->GetIncrements(whiteStep[0], whiteStep[1], whiteStep[2]);
|
|
captureBlack->GetIncrements(blackStep[0], blackStep[1], blackStep[2]);
|
|
capture->GetIncrements(outStep[0], outStep[1], outStep[2]);
|
|
|
|
int* extent = capture->GetExtent();
|
|
|
|
for (int i = extent[4]; i <= extent[5]; ++i)
|
|
{
|
|
const unsigned char* whiteRow = white;
|
|
const unsigned char* blackRow = black;
|
|
unsigned char* outRow = out;
|
|
|
|
for (int j = extent[2]; j <= extent[3]; ++j)
|
|
{
|
|
const unsigned char* whitePx = whiteRow;
|
|
const unsigned char* blackPx = blackRow;
|
|
unsigned char* outPx = outRow;
|
|
|
|
for (int k = extent[0]; k <= extent[1]; ++k)
|
|
{
|
|
if (whitePx[0] == blackPx[0] &&
|
|
whitePx[1] == blackPx[1] &&
|
|
whitePx[2] == blackPx[2])
|
|
{
|
|
outPx[0] = whitePx[0];
|
|
outPx[1] = whitePx[1];
|
|
outPx[2] = whitePx[2];
|
|
outPx[3] = 255;
|
|
}
|
|
else
|
|
{
|
|
// Some kind of translucency; use values from the black capture.
|
|
// The opacity is the derived from the V difference of the HSV
|
|
// colors.
|
|
double whiteHSV[3];
|
|
double blackHSV[3];
|
|
|
|
vtkMath::RGBToHSV(whitePx[0] / 255., whitePx[1] / 255., whitePx[2] / 255.,
|
|
whiteHSV + 0, whiteHSV + 1, whiteHSV + 2);
|
|
vtkMath::RGBToHSV(blackPx[0] / 255., blackPx[1] / 255., blackPx[2] / 255.,
|
|
blackHSV + 0, blackHSV + 1, blackHSV + 2);
|
|
double alpha = 1. - (whiteHSV[2] - blackHSV[2]);
|
|
|
|
outPx[0] = static_cast<unsigned char>(blackPx[0] / alpha);
|
|
outPx[1] = static_cast<unsigned char>(blackPx[1] / alpha);
|
|
outPx[2] = static_cast<unsigned char>(blackPx[2] / alpha);
|
|
outPx[3] = static_cast<unsigned char>(255 * alpha);
|
|
}
|
|
|
|
whitePx += whiteStep[0];
|
|
blackPx += blackStep[0];
|
|
outPx += outStep[0];
|
|
}
|
|
|
|
whiteRow += whiteStep[1];
|
|
blackRow += blackStep[1];
|
|
outRow += outStep[1];
|
|
}
|
|
|
|
white += whiteStep[2];
|
|
black += blackStep[2];
|
|
out += outStep[2];
|
|
}
|
|
|
|
this->RestoreRendererBackground(renderer, info);
|
|
|
|
captureWhite->Delete();
|
|
captureBlack->Delete();
|
|
return capture;
|
|
}
|
|
|
|
// Fall back to using no transparency.
|
|
return this->CaptureWindowSingle(magnification);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMViewProxy::vtkRendererSaveInfo* vtkSMViewProxy::PrepareRendererBackground(
|
|
vtkRenderer* renderer,
|
|
double r, double g, double b, bool save)
|
|
{
|
|
vtkRendererSaveInfo* info = NULL;
|
|
|
|
if (save)
|
|
{
|
|
info = new vtkRendererSaveInfo(renderer);
|
|
}
|
|
|
|
renderer->SetGradientBackground(false);
|
|
renderer->SetTexturedBackground(false);
|
|
renderer->SetBackground(r, g, b);
|
|
|
|
return info;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMViewProxy::RestoreRendererBackground(vtkRenderer* renderer,
|
|
vtkRendererSaveInfo* info)
|
|
{
|
|
renderer->SetGradientBackground(info->Gradient);
|
|
renderer->SetTexturedBackground(info->Textured);
|
|
renderer->SetBackground(info->Red, info->Green, info->Blue);
|
|
|
|
delete info;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageData* vtkSMViewProxy::CaptureWindowSingle(int magnification)
|
|
{
|
|
if (this->ObjectsCreated)
|
|
{
|
|
vtkClientServerStream stream;
|
|
stream << vtkClientServerStream::Invoke
|
|
<< VTKOBJECT(this)
|
|
<< "PrepareForScreenshot"
|
|
<< vtkClientServerStream::End;
|
|
this->ExecuteStream(stream);
|
|
}
|
|
|
|
vtkImageData* capture = this->CaptureWindowInternal(magnification);
|
|
|
|
if (this->ObjectsCreated)
|
|
{
|
|
vtkClientServerStream stream;
|
|
stream << vtkClientServerStream::Invoke
|
|
<< VTKOBJECT(this)
|
|
<< "CleanupAfterScreenshot"
|
|
<< vtkClientServerStream::End;
|
|
this->ExecuteStream(stream);
|
|
}
|
|
|
|
if (capture)
|
|
{
|
|
int position[2];
|
|
vtkSMPropertyHelper(this, "ViewPosition").Get(position, 2);
|
|
|
|
// Update image extents based on ViewPosition
|
|
int extents[6];
|
|
capture->GetExtent(extents);
|
|
for (int cc=0; cc < 4; cc++)
|
|
{
|
|
extents[cc] += position[cc/2]*magnification;
|
|
}
|
|
capture->SetExtent(extents);
|
|
}
|
|
return capture;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int vtkSMViewProxy::WriteImage(const char* filename,
|
|
const char* writerName, int magnification)
|
|
{
|
|
if (!filename || !writerName)
|
|
{
|
|
return vtkErrorCode::UnknownError;
|
|
}
|
|
|
|
vtkSmartPointer<vtkImageData> shot;
|
|
shot.TakeReference(this->CaptureWindow(magnification));
|
|
|
|
if (vtkProcessModule::GetProcessModule()->GetOptions()->GetSymmetricMPIMode())
|
|
{
|
|
return vtkSMUtilities::SaveImageOnProcessZero(shot, filename, writerName);
|
|
}
|
|
return vtkSMUtilities::SaveImage(shot, filename, writerName);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMViewProxy::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMViewProxy::SetTransparentBackground(bool val)
|
|
{
|
|
vtkSMViewProxy::TransparentBackground = val;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMViewProxy::GetTransparentBackground()
|
|
{
|
|
return vtkSMViewProxy::TransparentBackground;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMViewProxy::IsContextReadyForRendering()
|
|
{
|
|
if (vtkRenderWindow* window = this->GetRenderWindow())
|
|
{
|
|
return window->IsDrawable();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMViewProxy::HideOtherRepresentationsIfNeeded(vtkSMProxy* repr)
|
|
{
|
|
if (repr == NULL ||
|
|
this->GetHints() == NULL ||
|
|
this->GetHints()->FindNestedElementByName("ShowOneRepresentationAtATime") == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
vtkNew<vtkSMParaViewPipelineControllerWithRendering> controller;
|
|
|
|
bool modified = false;
|
|
vtkSMPropertyHelper helper(this, "Representations");
|
|
for (unsigned int cc=0, max=helper.GetNumberOfElements(); cc < max; ++cc)
|
|
{
|
|
vtkSMRepresentationProxy* arepr =
|
|
vtkSMRepresentationProxy::SafeDownCast(helper.GetAsProxy(cc));
|
|
if (arepr && arepr != repr)
|
|
{
|
|
if (vtkSMPropertyHelper(arepr, "Visibility", /*quiet*/true).GetAsInt() == 1)
|
|
{
|
|
controller->Hide(arepr, this);
|
|
modified = true;
|
|
}
|
|
}
|
|
}
|
|
return modified;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMViewProxy::GetLocalProcessSupportsInteraction()
|
|
{
|
|
this->CreateVTKObjects();
|
|
vtkPVView* pvview = vtkPVView::SafeDownCast(this->GetClientSideObject());
|
|
return pvview? pvview->GetLocalProcessSupportsInteraction() : false;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMViewProxy::MakeRenderWindowInteractor(bool quiet)
|
|
{
|
|
if (this->GetInteractor() != NULL)
|
|
{
|
|
// all's setup already. nothing to do.
|
|
return true;
|
|
}
|
|
if (!this->GetLocalProcessSupportsInteraction())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
vtkRenderWindow* renWin = this->GetRenderWindow();
|
|
if (!renWin)
|
|
{
|
|
if (!quiet)
|
|
{
|
|
vtkWarningMacro("Not a view that has a vtkRenderWindow. Cannot setup interactor.");
|
|
}
|
|
return false;
|
|
}
|
|
if (renWin->GetMapped())
|
|
{
|
|
if (!quiet)
|
|
{
|
|
vtkErrorMacro("Window is currently mapped. "
|
|
"Currently, interaction is only supported on unmapped windows.");
|
|
}
|
|
return false;
|
|
}
|
|
// in reality batch shouldn't have an interactor at all. However, to avoid the
|
|
// mismatch in the vtkPVAxesWidget (orientation widget) when using pvpython or
|
|
// pvbatch, we do create one. However, lets create a non-interactive
|
|
// interactor in batch mode.
|
|
vtkSmartPointer<vtkRenderWindowInteractor> iren;
|
|
if (vtkProcessModule::GetProcessType() != vtkProcessModule::PROCESS_BATCH)
|
|
{
|
|
iren = renWin->MakeRenderWindowInteractor();
|
|
}
|
|
else
|
|
{
|
|
iren = vtkSmartPointer<vtkGenericRenderWindowInteractor>::New();
|
|
// This initialize is essential. Otherwise vtkRenderWindow::Render causes
|
|
// the interactor to initialize which in turn triggers a render!
|
|
iren->Initialize();
|
|
}
|
|
this->SetupInteractor(iren);
|
|
return this->GetInteractor() != NULL;
|
|
}
|