mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
706 lines
24 KiB
C++
706 lines
24 KiB
C++
/*=========================================================================
|
|
|
|
Program: ParaView
|
|
Module: vtkSMParaViewPipelineControllerWithRendering.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 "vtkSMParaViewPipelineControllerWithRendering.h"
|
|
|
|
#include "vtkErrorCode.h"
|
|
#include "vtkImageData.h"
|
|
#include "vtkNew.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkProcessModule.h"
|
|
#include "vtkPVDataInformation.h"
|
|
#include "vtkPVXMLElement.h"
|
|
#include "vtkSmartPointer.h"
|
|
#include "vtkSMPropertyHelper.h"
|
|
#include "vtkSMPropertyIterator.h"
|
|
#include "vtkSMProxyProperty.h"
|
|
#include "vtkSMProxySelectionModel.h"
|
|
#include "vtkSMPVRepresentationProxy.h"
|
|
#include "vtkSMSessionProxyManager.h"
|
|
#include "vtkSMSourceProxy.h"
|
|
#include "vtkSMTrace.h"
|
|
#include "vtkSMTransferFunctionManager.h"
|
|
#include "vtkSMUtilities.h"
|
|
#include "vtkSMViewLayoutProxy.h"
|
|
#include "vtkSMViewProxy.h"
|
|
|
|
#include <string>
|
|
#include <cassert>
|
|
|
|
namespace
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
const char* vtkFindTypeFromHints(vtkPVXMLElement* hints, const int outputPort,
|
|
const char* xmlTag,
|
|
const char* xmlAttributeName=NULL,
|
|
const char* xmlAttributeValue=NULL)
|
|
{
|
|
if (!hints)
|
|
{
|
|
return NULL;
|
|
}
|
|
for (unsigned int cc=0, max=hints->GetNumberOfNestedElements(); cc < max; cc++)
|
|
{
|
|
vtkPVXMLElement* child = hints->GetNestedElement(cc);
|
|
if (child && child->GetName() && strcmp(child->GetName(), xmlTag) == 0)
|
|
{
|
|
int port;
|
|
// If port exists, then it must match the port number for this port.
|
|
if (child->GetScalarAttribute("port", &port) && (port != outputPort))
|
|
{
|
|
continue;
|
|
}
|
|
// if xmlAttributeName and xmlAttributeValue are provided, the XML must match the
|
|
// (name,value) pair, if present.
|
|
if (xmlAttributeValue && xmlAttributeName && child->GetAttribute(xmlAttributeName))
|
|
{
|
|
if (strcmp(child->GetAttribute(xmlAttributeName), xmlAttributeValue) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
if (const char* type = child->GetAttribute("type"))
|
|
{
|
|
return type;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
bool vtkTreatDataAsText(vtkPVXMLElement* hints, const int outputPort)
|
|
{
|
|
if (!hints)
|
|
{
|
|
return false;
|
|
}
|
|
for (unsigned int cc=0, max=hints->GetNumberOfNestedElements(); cc < max; cc++)
|
|
{
|
|
vtkPVXMLElement* child = hints->GetNestedElement(cc);
|
|
if (child && child->GetName() && strcmp(child->GetName(), "OutputPort") == 0)
|
|
{
|
|
int port;
|
|
// If port exists, then it must match the port number for this port.
|
|
if (child->GetScalarAttribute("port", &port) && (port != outputPort))
|
|
{
|
|
continue;
|
|
}
|
|
if (const char* type = child->GetAttribute("type"))
|
|
{
|
|
return (strcmp(type, "text") == 0);
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void vtkInheritRepresentationProperties(
|
|
vtkSMRepresentationProxy* repr,
|
|
vtkSMSourceProxy* producer,
|
|
unsigned int producerPort,
|
|
vtkSMViewProxy* view, const unsigned long initTimeStamp)
|
|
{
|
|
if (producer->GetProperty("Input") == NULL)
|
|
{
|
|
// if producer is not a filter, nothing to do.
|
|
return;
|
|
}
|
|
|
|
vtkSMPropertyHelper inputHelper(producer, "Input", true);
|
|
vtkSMProxy* inputRepr = view->FindRepresentation(
|
|
vtkSMSourceProxy::SafeDownCast(inputHelper.GetAsProxy()),
|
|
inputHelper.GetOutputPort());
|
|
if (inputRepr == NULL)
|
|
{
|
|
// if producer's input has no representation in the view, nothing to do.
|
|
return;
|
|
}
|
|
|
|
// Irrespective of other properties, scalar coloring is inherited if
|
|
// possible.
|
|
if (vtkSMPVRepresentationProxy::GetUsingScalarColoring(inputRepr) &&
|
|
!vtkSMPVRepresentationProxy::GetUsingScalarColoring(repr))
|
|
{
|
|
vtkSMPropertyHelper colorArrayHelper(inputRepr, "ColorArrayName");
|
|
const char* arrayName = colorArrayHelper.GetInputArrayNameToProcess();
|
|
int arrayAssociation = colorArrayHelper.GetInputArrayAssociation();
|
|
|
|
if (producer->GetDataInformation(producerPort)->GetArrayInformation(
|
|
arrayName, arrayAssociation))
|
|
{
|
|
vtkSMPVRepresentationProxy::SetScalarColoring(
|
|
repr, colorArrayHelper.GetInputArrayNameToProcess(),
|
|
colorArrayHelper.GetInputArrayAssociation());
|
|
}
|
|
}
|
|
|
|
if (!vtkSMParaViewPipelineControllerWithRendering::GetInheritRepresentationProperties())
|
|
{
|
|
return;
|
|
}
|
|
// copy properties from inputRepr to repr is they weren't modified.
|
|
vtkSMPropertyIterator* iter = inputRepr->NewPropertyIterator();
|
|
for (iter->Begin(); !iter->IsAtEnd(); iter->Next())
|
|
{
|
|
const char* pname = iter->GetKey();
|
|
vtkSMProperty* dest = repr->GetProperty(pname);
|
|
vtkSMProperty* source = iter->GetProperty();
|
|
if (pname &&
|
|
(strcmp(pname, "ColorArrayName") == 0 ||
|
|
strcmp(pname, "LookupTable") == 0 ||
|
|
strcmp(pname, "ScalarOpacityFunction") == 0))
|
|
{
|
|
// HACK: to fix BUG #15539. We avoid copying coloring properties since
|
|
// they are already inherited if needed. The tricky question is how do
|
|
// we inherit data-dependent properties using a generic API? We need a
|
|
// domain-aware-copy method. This method will copy values from a source
|
|
// property that are valid for the destination property's domain. It of
|
|
// course gets more complicated for this like the
|
|
// LookupTable/ScalarOpacityFunction properties. How are those to be
|
|
// copied over esp. since they depend on how ColorArrayName property was
|
|
// copied.
|
|
continue;
|
|
}
|
|
if (vtkSMProxyProperty::SafeDownCast(source))
|
|
{
|
|
// HACK: we skip proxy properties. Without this change, the properties
|
|
// like GlyphType end up inheriting the value from the upstream
|
|
// representation, which is incorrect.
|
|
continue;
|
|
}
|
|
if (dest && source &&
|
|
// the property wasn't modified since initialization or if it is
|
|
// "Representation" property -- (HACK)
|
|
(dest->GetMTime() < initTimeStamp || strcmp("Representation", pname) == 0) &&
|
|
// the property types match.
|
|
strcmp(dest->GetClassName(), source->GetClassName())==0 )
|
|
{
|
|
dest->Copy(source);
|
|
}
|
|
}
|
|
iter->Delete();
|
|
repr->UpdateVTKObjects();
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void vtkPickRepresentationType(
|
|
vtkSMRepresentationProxy* repr, vtkSMSourceProxy* producer, unsigned int outputPort,
|
|
vtkSMViewProxy* view)
|
|
{
|
|
(void)producer;
|
|
(void)outputPort;
|
|
|
|
// Check if there's a hint for the producer. If so, use that.
|
|
if (const char* reprtype = vtkFindTypeFromHints(
|
|
producer->GetHints(), outputPort, "RepresentationType", "view", view->GetXMLName()))
|
|
{
|
|
if (repr->SetRepresentationType(reprtype))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
// currently, this just ensures that the "Representation" type chosen has
|
|
// proper color type etc. setup. At some point, we could deprecate
|
|
// vtkSMRepresentationTypeDomain and let this logic pick the default
|
|
// representation type.
|
|
if (vtkSMProperty* smproperty = repr->GetProperty("Representation"))
|
|
{
|
|
repr->SetRepresentationType(vtkSMPropertyHelper(smproperty).GetAsString());
|
|
}
|
|
}
|
|
}
|
|
|
|
bool vtkSMParaViewPipelineControllerWithRendering::HideScalarBarOnHide = true;
|
|
bool vtkSMParaViewPipelineControllerWithRendering::InheritRepresentationProperties = false;
|
|
|
|
vtkObjectFactoryNewMacro(vtkSMParaViewPipelineControllerWithRendering);
|
|
//----------------------------------------------------------------------------
|
|
vtkSMParaViewPipelineControllerWithRendering::vtkSMParaViewPipelineControllerWithRendering()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMParaViewPipelineControllerWithRendering::~vtkSMParaViewPipelineControllerWithRendering()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMParaViewPipelineControllerWithRendering::SetHideScalarBarOnHide(bool val)
|
|
{
|
|
vtkSMParaViewPipelineControllerWithRendering::HideScalarBarOnHide = val;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMParaViewPipelineControllerWithRendering::SetInheritRepresentationProperties(bool val)
|
|
{
|
|
vtkSMParaViewPipelineControllerWithRendering::InheritRepresentationProperties = val;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMParaViewPipelineControllerWithRendering::GetInheritRepresentationProperties()
|
|
{
|
|
return vtkSMParaViewPipelineControllerWithRendering::InheritRepresentationProperties;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMParaViewPipelineControllerWithRendering::PostInitializeProxy(vtkSMProxy* proxy)
|
|
{
|
|
// save current time, we can check is a property is modified by the superclass
|
|
// call.
|
|
vtkTimeStamp ts;
|
|
ts.Modified();
|
|
|
|
if (!this->Superclass::PostInitializeProxy(proxy))
|
|
{
|
|
return false;
|
|
}
|
|
// BUG #14773: The domains for ColorArrayName and Representation properties
|
|
// come up with a good default separately. In reality, we need the
|
|
// ColorArrayName to depend on Representation and not pick any value when
|
|
// using Outline representation. However, since ColorArrayName is on a property
|
|
// on a subproxy while Representation is a property on the outer proxy, we
|
|
// cannot add dependency between the two. So we explicitly manage that here.
|
|
// Note that if the user set the ColorArrayName manually, we should not be
|
|
// changing it here, hence the check of initTime.
|
|
vtkSMProperty* colorArrayName = proxy->GetProperty("ColorArrayName");
|
|
vtkSMProperty* representation = proxy->GetProperty("Representation");
|
|
if (colorArrayName && representation && (colorArrayName->GetMTime() > ts))
|
|
{
|
|
vtkSMPropertyHelper helperRep(representation);
|
|
if (helperRep.GetAsString(0) &&
|
|
strcmp(helperRep.GetAsString(0), "Outline") == 0)
|
|
{
|
|
vtkSMPropertyHelper helper(colorArrayName);
|
|
helper.SetInputArrayToProcess(helper.GetInputArrayAssociation(), "");
|
|
proxy->UpdateVTKObjects();
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMParaViewPipelineControllerWithRendering::RegisterRepresentationProxy(vtkSMProxy* proxy)
|
|
{
|
|
if (!this->Superclass::RegisterRepresentationProxy(proxy))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (vtkSMPVRepresentationProxy::GetUsingScalarColoring(proxy))
|
|
{
|
|
// If representation has been initialized to use scalar coloring and no
|
|
// transfer functions are setup, we setup the transfer functions.
|
|
vtkSMPropertyHelper helper(proxy, "ColorArrayName");
|
|
const char* arrayName = helper.GetInputArrayNameToProcess();
|
|
if (arrayName != NULL && arrayName[0] != '\0')
|
|
{
|
|
vtkNew<vtkSMTransferFunctionManager> mgr;
|
|
if (vtkSMProperty* sofProperty = proxy->GetProperty("ScalarOpacityFunction"))
|
|
{
|
|
vtkSMProxy* sofProxy =
|
|
mgr->GetOpacityTransferFunction(arrayName, proxy->GetSessionProxyManager());
|
|
vtkSMPropertyHelper(sofProperty).Set(sofProxy);
|
|
}
|
|
if (vtkSMProperty* lutProperty = proxy->GetProperty("LookupTable"))
|
|
{
|
|
vtkSMProxy* lutProxy =
|
|
mgr->GetColorTransferFunction(arrayName, proxy->GetSessionProxyManager());
|
|
vtkSMPropertyHelper(lutProperty).Set(lutProxy);
|
|
vtkSMPVRepresentationProxy::RescaleTransferFunctionToDataRange(proxy, true);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMProxy* vtkSMParaViewPipelineControllerWithRendering::Show(
|
|
vtkSMSourceProxy* producer, int outputPort, vtkSMViewProxy* view)
|
|
{
|
|
if (producer == NULL || static_cast<int>(producer->GetNumberOfOutputPorts()) <= outputPort)
|
|
{
|
|
vtkErrorMacro("Invalid producer (" << producer << ") or outputPort ("
|
|
<< outputPort << ")");
|
|
return NULL;
|
|
}
|
|
|
|
if (view == NULL)
|
|
{
|
|
view = this->ShowInPreferredView(producer, outputPort, NULL);
|
|
return (view? view->FindRepresentation(producer, outputPort) : NULL);
|
|
}
|
|
|
|
// find is there's already a representation in this view.
|
|
if (vtkSMProxy* repr = view->FindRepresentation(producer, outputPort))
|
|
{
|
|
SM_SCOPED_TRACE(Show).arg("producer", producer)
|
|
.arg("port", outputPort)
|
|
.arg("view", view)
|
|
.arg("display", repr);
|
|
|
|
vtkSMPropertyHelper(repr, "Visibility").Set(1);
|
|
repr->UpdateVTKObjects();
|
|
|
|
vtkSMViewProxy::HideOtherRepresentationsIfNeeded(view, repr);
|
|
return repr;
|
|
}
|
|
|
|
// update pipeline to create correct representation type.
|
|
this->UpdatePipelineBeforeDisplay(producer, outputPort, view);
|
|
|
|
// Since no repr exists, create a new one if possible.
|
|
if (vtkSMRepresentationProxy* repr = view->CreateDefaultRepresentation(producer, outputPort))
|
|
{
|
|
SM_SCOPED_TRACE(Show).arg("producer", producer)
|
|
.arg("port", outputPort)
|
|
.arg("view", view)
|
|
.arg("display", repr);
|
|
|
|
this->PreInitializeProxy(repr);
|
|
|
|
vtkTimeStamp ts;
|
|
ts.Modified();
|
|
|
|
vtkSMPropertyHelper(repr, "Visibility").Set(1);
|
|
vtkSMPropertyHelper(repr, "Input").Set(producer, outputPort);
|
|
this->PostInitializeProxy(repr);
|
|
|
|
// check some setting and then inherit properties.
|
|
vtkInheritRepresentationProperties(repr, producer, outputPort, view, ts);
|
|
|
|
// pick good representation type.
|
|
vtkPickRepresentationType(repr, producer, outputPort, view);
|
|
|
|
this->RegisterRepresentationProxy(repr);
|
|
repr->UpdateVTKObjects();
|
|
|
|
vtkSMPropertyHelper(view, "Representations").Add(repr);
|
|
view->UpdateVTKObjects();
|
|
repr->FastDelete();
|
|
|
|
vtkSMViewProxy::HideOtherRepresentationsIfNeeded(view, repr);
|
|
return repr;
|
|
}
|
|
|
|
// give up.
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMProxy* vtkSMParaViewPipelineControllerWithRendering::Hide(
|
|
vtkSMSourceProxy* producer, int outputPort, vtkSMViewProxy* view)
|
|
{
|
|
if (producer == NULL || static_cast<int>(producer->GetNumberOfOutputPorts()) <= outputPort)
|
|
{
|
|
vtkErrorMacro("Invalid producer (" << producer << ") or outputPort ("
|
|
<< outputPort << ")");
|
|
return NULL;
|
|
}
|
|
if (view == NULL)
|
|
{
|
|
// already hidden, I guess :).
|
|
return NULL;
|
|
}
|
|
|
|
SM_SCOPED_TRACE(Hide).arg("producer", producer)
|
|
.arg("port", outputPort)
|
|
.arg("view", view);
|
|
|
|
// find is there's already a representation in this view.
|
|
if (vtkSMProxy* repr = view->FindRepresentation(producer, outputPort))
|
|
{
|
|
this->Hide(repr, view);
|
|
return repr;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMParaViewPipelineControllerWithRendering::Hide(
|
|
vtkSMProxy* repr, vtkSMViewProxy* view)
|
|
{
|
|
if (repr)
|
|
{
|
|
vtkSMPropertyHelper(repr, "Visibility").Set(0);
|
|
repr->UpdateVTKObjects();
|
|
|
|
if (vtkSMParaViewPipelineControllerWithRendering::HideScalarBarOnHide)
|
|
{
|
|
vtkSMPVRepresentationProxy::HideScalarBarIfNotNeeded(repr, view);
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMParaViewPipelineControllerWithRendering::GetVisibility(
|
|
vtkSMSourceProxy* producer, int outputPort, vtkSMViewProxy* view)
|
|
{
|
|
if (producer == NULL || static_cast<int>(producer->GetNumberOfOutputPorts()) <= outputPort)
|
|
{
|
|
return false;
|
|
}
|
|
if (view == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
if (vtkSMRepresentationProxy* repr = view->FindRepresentation(producer, outputPort))
|
|
{
|
|
return vtkSMPropertyHelper(repr, "Visibility").GetAsInt() != 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMViewProxy* vtkSMParaViewPipelineControllerWithRendering::ShowInPreferredView(
|
|
vtkSMSourceProxy* producer, int outputPort, vtkSMViewProxy* view)
|
|
{
|
|
if (producer == NULL || static_cast<int>(producer->GetNumberOfOutputPorts()) <= outputPort)
|
|
{
|
|
vtkErrorMacro("Invalid producer (" << producer << ") or outputPort ("
|
|
<< outputPort << ")");
|
|
return NULL;
|
|
}
|
|
|
|
this->UpdatePipelineBeforeDisplay(producer, outputPort, view);
|
|
|
|
vtkSMSessionProxyManager* pxm = producer->GetSessionProxyManager();
|
|
if (const char* preferredViewType = this->GetPreferredViewType(producer, outputPort))
|
|
{
|
|
if (// no view is specified.
|
|
view == NULL ||
|
|
// the "view" is not of the preferred type.
|
|
strcmp(preferredViewType, view->GetXMLName()) != 0)
|
|
{
|
|
vtkSmartPointer<vtkSMProxy> targetView;
|
|
targetView.TakeReference(pxm->NewProxy("views", preferredViewType));
|
|
if (vtkSMViewProxy* preferredView = vtkSMViewProxy::SafeDownCast(targetView))
|
|
{
|
|
this->InitializeProxy(preferredView);
|
|
this->RegisterViewProxy(preferredView);
|
|
if (this->Show(producer, outputPort, preferredView) == NULL)
|
|
{
|
|
vtkErrorMacro("Data cannot be shown in the preferred view!!");
|
|
return NULL;
|
|
}
|
|
return preferredView;
|
|
}
|
|
else
|
|
{
|
|
vtkErrorMacro(
|
|
"Failed to create preferred view (" << preferredViewType << ")");
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert(view);
|
|
if (!this->Show(producer, outputPort, view))
|
|
{
|
|
vtkErrorMacro("Data cannot be shown in the preferred view!!");
|
|
return NULL;
|
|
}
|
|
return view;
|
|
}
|
|
}
|
|
else if (view)
|
|
{
|
|
// If there's no preferred view, check if active view can show the data. If
|
|
// so, show it in that view.
|
|
if (view->CanDisplayData(producer, outputPort))
|
|
{
|
|
if (this->Show(producer, outputPort, view))
|
|
{
|
|
return view;
|
|
}
|
|
|
|
vtkErrorMacro("View should have been able to show the data, "
|
|
"but it failed to do so. This may point to a development bug.");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// No preferred view is found and "view" is NULL or cannot show the data.
|
|
// ParaView's default behavior is to create a render view, in that case, if the
|
|
// render view can show the data.
|
|
if (view == NULL || strcmp(view->GetXMLName(), "RenderView") != 0)
|
|
{
|
|
vtkSmartPointer<vtkSMProxy> renderView;
|
|
renderView.TakeReference(pxm->NewProxy("views", "RenderView"));
|
|
if (vtkSMViewProxy* preferredView = vtkSMViewProxy::SafeDownCast(renderView))
|
|
{
|
|
this->InitializeProxy(preferredView);
|
|
this->RegisterViewProxy(preferredView);
|
|
if (this->Show(producer, outputPort, preferredView) == NULL)
|
|
{
|
|
vtkErrorMacro("Data cannot be shown in the defaulted render view!!");
|
|
return NULL;
|
|
}
|
|
return preferredView;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const char* vtkSMParaViewPipelineControllerWithRendering::GetPreferredViewType(
|
|
vtkSMSourceProxy* producer, int outputPort)
|
|
{
|
|
// 1. Check if there's a hint for the producer. If so, use that.
|
|
if (const char* viewType = vtkFindTypeFromHints(producer->GetHints(), outputPort, "View"))
|
|
{
|
|
return viewType;
|
|
}
|
|
|
|
vtkPVDataInformation* dataInfo = producer->GetDataInformation(outputPort);
|
|
if (dataInfo->DataSetTypeIsA("vtkTable") &&
|
|
(vtkTreatDataAsText(producer->GetHints(), outputPort) == false))
|
|
{
|
|
return "SpreadSheetView";
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMParaViewPipelineControllerWithRendering::UpdatePipelineBeforeDisplay(
|
|
vtkSMSourceProxy* producer, int outputPort, vtkSMViewProxy* view)
|
|
{
|
|
(void) outputPort;
|
|
if (!producer)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Update using view time, or timekeeper time.
|
|
double time = view? vtkSMPropertyHelper(view, "ViewTime").GetAsDouble() :
|
|
vtkSMPropertyHelper(this->FindTimeKeeper(producer->GetSession()), "Time").GetAsDouble();
|
|
producer->UpdatePipeline(time);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
template<class T>
|
|
bool vtkWriteImage(T* viewOrLayout, const char* filename, int magnification, int quality)
|
|
{
|
|
if (!viewOrLayout)
|
|
{
|
|
return false;
|
|
}
|
|
SM_SCOPED_TRACE(SaveCameras).arg("proxy", viewOrLayout);
|
|
|
|
SM_SCOPED_TRACE(CallFunction)
|
|
.arg("SaveScreenshot")
|
|
.arg(filename)
|
|
.arg((vtkSMViewProxy::SafeDownCast(viewOrLayout)? "view" : "layout"), viewOrLayout)
|
|
.arg("magnification", magnification)
|
|
.arg("quality", quality)
|
|
.arg("comment", "save screenshot");
|
|
|
|
vtkSmartPointer<vtkImageData> img;
|
|
img.TakeReference(viewOrLayout->CaptureWindow(magnification));
|
|
if (img &&
|
|
vtkProcessModule::GetProcessModule()->GetPartitionId() == 0)
|
|
{
|
|
return vtkSMUtilities::SaveImage(img.GetPointer(), filename, quality) == vtkErrorCode::NoError;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMParaViewPipelineControllerWithRendering::WriteImage(
|
|
vtkSMViewProxy* view, const char* filename, int magnification, int quality)
|
|
{
|
|
return vtkWriteImage<vtkSMViewProxy>(view, filename, magnification, quality);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMParaViewPipelineControllerWithRendering::WriteImage(
|
|
vtkSMViewLayoutProxy* layout, const char* filename, int magnification, int quality)
|
|
{
|
|
return vtkWriteImage<vtkSMViewLayoutProxy>(layout, filename, magnification, quality);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMParaViewPipelineControllerWithRendering::RegisterViewProxy(
|
|
vtkSMProxy* proxy, const char* proxyname)
|
|
{
|
|
if (!proxy)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
vtkSMSessionProxyManager* pxm = proxy->GetSessionProxyManager();
|
|
|
|
// locate layout (create a new one if needed).
|
|
vtkSMProxySelectionModel* selmodel = pxm->GetSelectionModel("ActiveView");
|
|
assert(selmodel != NULL);
|
|
vtkSMViewProxy* activeView = vtkSMViewProxy::SafeDownCast(selmodel->GetCurrentProxy());
|
|
vtkSMProxy* activeLayout = vtkSMViewLayoutProxy::FindLayout(activeView);
|
|
activeLayout = activeLayout? activeLayout : this->FindProxy(pxm, "layouts", "misc", "ViewLayout");
|
|
if (!activeLayout)
|
|
{
|
|
// no active layout is present at all. Create a new one.
|
|
activeLayout = pxm->NewProxy("misc", "ViewLayout");
|
|
if (activeLayout)
|
|
{
|
|
this->InitializeProxy(activeLayout);
|
|
this->RegisterLayoutProxy(activeLayout);
|
|
activeLayout->FastDelete();
|
|
}
|
|
}
|
|
if (activeLayout)
|
|
{
|
|
// ensure that we "access" the layout, before the view is created, other the
|
|
// trace ends up incorrect (this is needed since RegisterViewProxy() results
|
|
// in the Qt client assigning a frame for the view, if the Qt client didn't
|
|
// do that, this code will get a lot simpler.
|
|
SM_SCOPED_TRACE(EnsureLayout).arg(activeLayout);
|
|
}
|
|
|
|
bool retval = this->Superclass::RegisterViewProxy(proxy, proxyname);
|
|
if (activeLayout)
|
|
{
|
|
vtkSMProxy* layoutAssigned = vtkSMViewLayoutProxy::FindLayout(vtkSMViewProxy::SafeDownCast(proxy));
|
|
activeLayout = layoutAssigned? layoutAssigned : activeLayout;
|
|
vtkSMViewLayoutProxy::SafeDownCast(activeLayout)->AssignViewToAnyCell(
|
|
vtkSMViewProxy::SafeDownCast(proxy), 0);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMParaViewPipelineControllerWithRendering::RegisterLayoutProxy(
|
|
vtkSMProxy* proxy, const char* proxyname)
|
|
{
|
|
if (!proxy)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
SM_SCOPED_TRACE(RegisterLayoutProxy).arg("layout", proxy);
|
|
|
|
vtkSMSessionProxyManager* pxm = proxy->GetSessionProxyManager();
|
|
pxm->RegisterProxy("layouts", proxyname, proxy);
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMParaViewPipelineControllerWithRendering::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|