Files
ThirdParty-6/ParaView-5.0.1/ParaViewCore/ServerManager/Rendering/vtkSMTransferFunctionManager.cxx

386 lines
13 KiB
C++

/*=========================================================================
Program: ParaView
Module: vtkSMTransferFunctionManager.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 "vtkSMTransferFunctionManager.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkSMCoreUtilities.h"
#include "vtkSMParaViewPipelineController.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMProxyIterator.h"
#include "vtkSMPVRepresentationProxy.h"
#include "vtkSMScalarBarWidgetRepresentationProxy.h"
#include "vtkSMSessionProxyManager.h"
#include "vtkSMSettings.h"
#include "vtkSMTransferFunctionProxy.h"
#include <assert.h>
#include <sstream>
#include <vtksys/RegularExpression.hxx>
#include <set>
namespace
{
vtkSMProxy* FindProxy(const char* groupName,
const char* arrayName,
vtkSMSessionProxyManager* pxm)
{
// Proxies are registered as (arrayName).(ProxyXMLName).
// In previous versions, they were registered as
// (numComps).(arrayName).(ProxyXMLName). We dropped the numComps, but this
// lookup should still match those old LUTs loaded from state.
std::ostringstream expr;
expr << "^[0-9.]*" << arrayName << "\\.";
vtksys::RegularExpression regExp(expr.str().c_str());
vtkNew<vtkSMProxyIterator> iter;
iter->SetSessionProxyManager(pxm);
iter->SetModeToOneGroup();
for (iter->Begin(groupName); !iter->IsAtEnd(); iter->Next())
{
const char* key = iter->GetKey();
if (key && regExp.find(key))
{
assert(iter->GetProxy() != NULL);
return iter->GetProxy();
}
}
return NULL;
}
}
vtkObjectFactoryNewMacro(vtkSMTransferFunctionManager);
//----------------------------------------------------------------------------
vtkSMTransferFunctionManager::vtkSMTransferFunctionManager()
{
}
//----------------------------------------------------------------------------
vtkSMTransferFunctionManager::~vtkSMTransferFunctionManager()
{
}
//----------------------------------------------------------------------------
vtkSMProxy* vtkSMTransferFunctionManager::GetColorTransferFunction(
const char* arrayName, vtkSMSessionProxyManager* pxm)
{
assert(arrayName != NULL && pxm != NULL);
// sanitize the arrayName. This is necessary since sometimes array names have
// characters that can mess up regular expressions.
std::string sanitizedArrayName = vtkSMCoreUtilities::SanitizeName(arrayName);
arrayName = sanitizedArrayName.c_str();
vtkSMProxy* proxy = FindProxy("lookup_tables", arrayName, pxm);
if (proxy)
{
return proxy;
}
// Create a new one.
proxy = pxm->NewProxy("lookup_tables", "PVLookupTable");
if (!proxy)
{
vtkErrorMacro("Failed to create PVLookupTable proxy.");
return NULL;
}
vtkNew<vtkSMParaViewPipelineController> controller;
controller->PreInitializeProxy(proxy);
vtkSMSettings* settings = vtkSMSettings::GetInstance();
// Load array-specific preset, if specified.
std::string stdPresetsKey = ".standard_presets.";
stdPresetsKey += arrayName;
if (settings->HasSetting(stdPresetsKey.c_str()))
{
vtkSMTransferFunctionProxy::ApplyPreset(proxy,
settings->GetSettingAsString(stdPresetsKey.c_str(), 0, "").c_str(),
/*rescale=*/false);
}
// Look up array-specific transfer function
std::ostringstream prefix;
prefix << ".array_" << proxy->GetXMLGroup() << "." << arrayName;
settings->GetProxySettings(prefix.str().c_str(), proxy);
std::ostringstream proxyName;
proxyName << arrayName << ".PVLookupTable";
if (proxy->GetProperty("ScalarOpacityFunction"))
{
vtkSMProxy* sof = this->GetOpacityTransferFunction(arrayName, pxm);
if (sof)
{
sof->UpdateVTKObjects();
vtkSMPropertyHelper(proxy, "ScalarOpacityFunction").Set(sof);
}
}
controller->PostInitializeProxy(proxy);
controller->RegisterColorTransferFunctionProxy(proxy, proxyName.str().c_str());
proxy->FastDelete();
return proxy;
}
//----------------------------------------------------------------------------
vtkSMProxy* vtkSMTransferFunctionManager::GetOpacityTransferFunction(
const char* arrayName, vtkSMSessionProxyManager* pxm)
{
assert(arrayName != NULL && pxm != NULL);
// sanitize the arrayName. This is necessary since sometimes array names have
// characters that can mess up regular expressions.
std::string sanitizedArrayName = vtkSMCoreUtilities::SanitizeName(arrayName);
arrayName = sanitizedArrayName.c_str();
vtkSMProxy* proxy = FindProxy("piecewise_functions", arrayName, pxm);
if (proxy)
{
return proxy;
}
// Create a new one.
proxy = pxm->NewProxy("piecewise_functions", "PiecewiseFunction");
if (!proxy)
{
vtkErrorMacro("Failed to create PVLookupTable proxy.");
return NULL;
}
vtkNew<vtkSMParaViewPipelineController> controller;
controller->PreInitializeProxy(proxy);
controller->PostInitializeProxy(proxy);
std::ostringstream proxyName;
proxyName << arrayName << ".PiecewiseFunction";
controller->RegisterOpacityTransferFunction(proxy, proxyName.str().c_str());
proxy->FastDelete();
proxy->UpdateVTKObjects();
return proxy;
}
//----------------------------------------------------------------------------
vtkSMProxy* vtkSMTransferFunctionManager::GetScalarBarRepresentation(
vtkSMProxy* colorTransferFunction, vtkSMProxy* view)
{
if (colorTransferFunction == NULL || view == NULL ||
!colorTransferFunction->IsA("vtkSMTransferFunctionProxy"))
{
return NULL;
}
vtkSMProxy* scalarBarProxy =
vtkSMTransferFunctionProxy::FindScalarBarRepresentation(
colorTransferFunction, view);
if (scalarBarProxy)
{
return scalarBarProxy;
}
// Create a new scalar bar representation.
vtkSMSessionProxyManager* pxm =
colorTransferFunction->GetSessionProxyManager();
scalarBarProxy = pxm->NewProxy("representations", "ScalarBarWidgetRepresentation");
if (!scalarBarProxy)
{
vtkErrorMacro("Failed to create ScalarBarWidgetRepresentation proxy.");
return NULL;
}
vtkNew<vtkSMParaViewPipelineController> controller;
// we set these values before PreInitializeProxy() so that can be overridden
// by user settings, if needed.
//vtkSMPropertyHelper(scalarBarProxy, "TitleFontSize").Set(6);
//vtkSMPropertyHelper(scalarBarProxy, "LabelFontSize").Set(6);
controller->PreInitializeProxy(scalarBarProxy);
vtkSMPropertyHelper(scalarBarProxy, "LookupTable").Set(colorTransferFunction);
controller->PostInitializeProxy(scalarBarProxy);
pxm->RegisterProxy("scalar_bars", scalarBarProxy);
scalarBarProxy->FastDelete();
vtkSMPropertyHelper(view, "Representations").Add(scalarBarProxy);
view->UpdateVTKObjects();
// Place the scalar bar in the view.
return scalarBarProxy;
}
//----------------------------------------------------------------------------
void vtkSMTransferFunctionManager::ResetAllTransferFunctionRangesUsingCurrentData(
vtkSMSessionProxyManager* pxm, bool extend)
{
vtkNew<vtkSMProxyIterator> iter;
iter->SetSessionProxyManager(pxm);
iter->SetModeToOneGroup();
for (iter->Begin("lookup_tables"); !iter->IsAtEnd(); iter->Next())
{
vtkSMProxy* lutProxy = iter->GetProxy();
assert(lutProxy != NULL);
if (vtkSMPropertyHelper(lutProxy, "LockScalarRange", true).GetAsInt() == 0)
{
if (vtkSMPropertyHelper(lutProxy, "IndexedLookup", true).GetAsInt() == 1)
{
vtkSMTransferFunctionProxy::ComputeAvailableAnnotations(lutProxy, extend);
}
else
{
double range[2] = {VTK_DOUBLE_MAX, VTK_DOUBLE_MIN};
if (vtkSMTransferFunctionProxy::ComputeDataRange(lutProxy, range))
{
vtkSMCoreUtilities::AdjustRange(range);
vtkSMTransferFunctionProxy::RescaleTransferFunction(
lutProxy, range[0], range[1], extend);
// BUG #0015076: Also reset the opacity function, if any.
if (vtkSMProxy* sof = vtkSMPropertyHelper(
lutProxy, "ScalarOpacityFunction", /*quiet*/true).GetAsProxy())
{
vtkSMTransferFunctionProxy::RescaleTransferFunction(
sof, range[0], range[1], extend);
}
}
}
}
}
}
//----------------------------------------------------------------------------
bool vtkSMTransferFunctionManager::UpdateScalarBars(
vtkSMProxy* viewProxy, unsigned int mode)
{
typedef std::set<vtkSMProxy*> proxysettype;
proxysettype currently_shown_scalar_bars;
proxysettype luts;
// colored_reprs are only those reprs that are uniquely colored with a LUT.
// i.e. if two repr have the same lut, we only add the first one to this set.
proxysettype colored_reprs;
// build a list of all transfer functions used for scalar coloring in this
// view and build a list of scalar bars currently shown in this view.
vtkSMPropertyHelper reprHelper(viewProxy, "Representations");
for (unsigned int cc=0, max=reprHelper.GetNumberOfElements(); cc < max; ++cc)
{
vtkSMProxy* proxy = reprHelper.GetAsProxy(cc);
if (vtkSMScalarBarWidgetRepresentationProxy::SafeDownCast(proxy) &&
(vtkSMPropertyHelper(proxy, "Visibility").GetAsInt() == 1))
{
currently_shown_scalar_bars.insert(proxy);
}
else if (vtkSMPropertyHelper(proxy, "Visibility", true).GetAsInt() == 1 &&
vtkSMPVRepresentationProxy::GetUsingScalarColoring(proxy))
{
vtkSMProxy* lut = vtkSMPropertyHelper(proxy, "LookupTable", true).GetAsProxy();
if (lut && luts.find(lut) == luts.end())
{
colored_reprs.insert(proxy);
luts.insert(lut);
}
}
}
bool modified = false;
if ((mode & HIDE_UNUSED_SCALAR_BARS) == HIDE_UNUSED_SCALAR_BARS)
{
// hide scalar-bars that point to lookup tables not in the luts set.
for (proxysettype::const_iterator iter=currently_shown_scalar_bars.begin();
iter != currently_shown_scalar_bars.end(); ++iter)
{
vtkSMProxy* sbProxy = (*iter);
if (sbProxy &&
(luts.find(vtkSMPropertyHelper(sbProxy, "LookupTable").GetAsProxy()) == luts.end()))
{
vtkSMPropertyHelper(sbProxy, "Visibility").Set(0);
vtkSMPropertyHelper(sbProxy, "Enabled").Set(0);
sbProxy->UpdateVTKObjects();
modified = true;
}
}
}
// NOTE: currently_shown_scalar_bars at this point also include scalar bars
// that we just hid.
if ((mode & SHOW_USED_SCALAR_BARS) == SHOW_USED_SCALAR_BARS)
{
// create and show scalar-bar for LUTs if they don't already exist.
// To do that, we iterate over reprs and turn on scalar bar. This is needed
// to ensure that a new scalar bar is created, it gets the right title.
for (proxysettype::const_iterator iter=colored_reprs.begin();
iter != colored_reprs.end(); ++iter)
{
vtkSMPVRepresentationProxy::SetScalarBarVisibility(
*iter, viewProxy, true);
modified = true; // not really truthful here.
}
}
return modified;
}
//----------------------------------------------------------------------------
bool vtkSMTransferFunctionManager::HideScalarBarIfNotNeeded(
vtkSMProxy* lutProxy, vtkSMProxy* view)
{
if (!lutProxy || !view)
{
return false;
}
vtkSMProxy* sbProxy = vtkSMTransferFunctionProxy::FindScalarBarRepresentation(
lutProxy, view);
if (!sbProxy)
{
// sb hidden.
return false;
}
vtkSMPropertyHelper visibilityHelper(sbProxy, "Visibility");
if (visibilityHelper.GetAsInt() == 0)
{
// sb hidden.
return false;
}
// build a list of all transfer functions used for scalar coloring in this
// view and build a list of scalar bars currently shown in this view.
vtkSMPropertyHelper reprHelper(view, "Representations");
for (unsigned int cc=0, max=reprHelper.GetNumberOfElements(); cc < max; ++cc)
{
vtkSMProxy* proxy = reprHelper.GetAsProxy(cc);
if (vtkSMPropertyHelper(proxy, "Visibility", true).GetAsInt() == 1 &&
vtkSMPVRepresentationProxy::GetUsingScalarColoring(proxy))
{
vtkSMProxy* lut = vtkSMPropertyHelper(proxy, "LookupTable", true).GetAsProxy();
if (lut == lutProxy)
{
// lut is being used. Don't hide the scalar bar.
return false;
}
}
}
vtkSMPropertyHelper(sbProxy, "Visibility").Set(0);
sbProxy->UpdateVTKObjects();
return true;
}
//----------------------------------------------------------------------------
void vtkSMTransferFunctionManager::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}