mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
527 lines
17 KiB
C++
527 lines
17 KiB
C++
/*=========================================================================
|
|
|
|
Program: ParaView
|
|
Module: $RCSfile$
|
|
|
|
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 "vtkSMChartSeriesSelectionDomain.h"
|
|
|
|
#include "vtkChartRepresentation.h"
|
|
#include "vtkColorSeries.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkDataObject.h"
|
|
#include "vtkNew.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPVArrayInformation.h"
|
|
#include "vtkPVCompositeDataInformation.h"
|
|
#include "vtkPVDataInformation.h"
|
|
#include "vtkPVDataSetAttributesInformation.h"
|
|
#include "vtkPVXMLElement.h"
|
|
#include "vtkSMArrayListDomain.h"
|
|
#include "vtkSMSourceProxy.h"
|
|
#include "vtkSMStringVectorProperty.h"
|
|
#include "vtkSMUncheckedPropertyHelper.h"
|
|
#include "vtkStdString.h"
|
|
#include "vtkStringList.h"
|
|
|
|
#include <algorithm>
|
|
#include <assert.h>
|
|
#include <map>
|
|
#include <set>
|
|
#include <vector>
|
|
#include <sstream>
|
|
#include <vtksys/RegularExpression.hxx>
|
|
|
|
vtkStandardNewMacro(vtkSMChartSeriesSelectionDomain);
|
|
namespace
|
|
{
|
|
// match string like: "ACCL (0)" or "VEL (1)"
|
|
static vtksys::RegularExpression PotentailComponentNameRe(".*\\([0-9]+\\)");
|
|
|
|
typedef std::pair<vtksys::RegularExpression, bool> SeriesVisibilityPair;
|
|
static std::vector<SeriesVisibilityPair> SeriesVisibilityDefaults;
|
|
static void InitSeriesVisibilityDefaults()
|
|
{
|
|
// initialize SeriesVisibilityDefaults the first time.
|
|
if (SeriesVisibilityDefaults.size() == 0)
|
|
{
|
|
const char* defaults[] = {
|
|
"^arc_length",
|
|
"^bin_extents",
|
|
"^FileId",
|
|
"^GlobalElementId",
|
|
"^GlobalNodeId",
|
|
"^ObjectId",
|
|
"^Pedigree.*",
|
|
"^Points_.*",
|
|
"^Time",
|
|
"^vtkOriginal.*",
|
|
"^vtkValidPointMask",
|
|
"^N .*",
|
|
NULL
|
|
};
|
|
for (int cc=0; defaults[cc] != NULL; cc++)
|
|
{
|
|
SeriesVisibilityDefaults.push_back(SeriesVisibilityPair(
|
|
vtksys::RegularExpression(defaults[cc]), false));
|
|
}
|
|
}
|
|
}
|
|
static void AddSeriesVisibilityDefault(const char* regex, bool value)
|
|
{
|
|
InitSeriesVisibilityDefaults();
|
|
if (regex && regex[0])
|
|
{
|
|
SeriesVisibilityDefaults.push_back(SeriesVisibilityPair(
|
|
vtksys::RegularExpression(regex), value));
|
|
}
|
|
}
|
|
|
|
static bool GetSeriesVisibilityDefault(const char* regex, bool &value)
|
|
{
|
|
InitSeriesVisibilityDefaults();
|
|
for (size_t cc=0; cc < SeriesVisibilityDefaults.size(); cc++)
|
|
{
|
|
if (SeriesVisibilityDefaults[cc].first.find(regex))
|
|
{
|
|
value = SeriesVisibilityDefaults[cc].second;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
class vtkSMChartSeriesSelectionDomain::vtkInternals
|
|
{
|
|
int ColorCounter;
|
|
vtkNew<vtkColorSeries> Colors;
|
|
public:
|
|
std::map<std::string, bool> VisibilityOverrides;
|
|
|
|
vtkInternals() : ColorCounter(0)
|
|
{
|
|
}
|
|
|
|
vtkColor3ub GetNextColor()
|
|
{
|
|
return this->Colors->GetColorRepeating(this->ColorCounter++);
|
|
}
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMChartSeriesSelectionDomain::vtkSMChartSeriesSelectionDomain() :
|
|
Internals(new vtkSMChartSeriesSelectionDomain::vtkInternals())
|
|
{
|
|
this->DefaultMode = vtkSMChartSeriesSelectionDomain::UNDEFINED;
|
|
this->DefaultValue = 0;
|
|
this->SetDefaultValue("");
|
|
this->FlattenTable = true;
|
|
|
|
this->AddObserver(vtkCommand::DomainModifiedEvent,
|
|
this, &vtkSMChartSeriesSelectionDomain::OnDomainModified);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkSMChartSeriesSelectionDomain::~vtkSMChartSeriesSelectionDomain()
|
|
{
|
|
this->SetDefaultValue(NULL);
|
|
delete this->Internals;
|
|
this->Internals = NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkPVDataInformation* vtkSMChartSeriesSelectionDomain::GetInputInformation()
|
|
{
|
|
vtkSMProperty* inputProperty = this->GetRequiredProperty("Input");
|
|
assert(inputProperty);
|
|
|
|
vtkSMUncheckedPropertyHelper helper(inputProperty);
|
|
if (helper.GetNumberOfElements() > 0)
|
|
{
|
|
vtkSMSourceProxy* sp = vtkSMSourceProxy::SafeDownCast(helper.GetAsProxy(0));
|
|
if (sp)
|
|
{
|
|
return sp->GetDataInformation(helper.GetOutputPort());
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkSMChartSeriesSelectionDomain::ReadXMLAttributes(
|
|
vtkSMProperty* prop, vtkPVXMLElement* element)
|
|
{
|
|
if (!this->Superclass::ReadXMLAttributes(prop, element))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
const char* default_mode = element->GetAttribute("default_mode");
|
|
if (default_mode)
|
|
{
|
|
if (strcmp(default_mode, "visibility") == 0)
|
|
{
|
|
this->DefaultMode = vtkSMChartSeriesSelectionDomain::VISIBILITY;
|
|
}
|
|
else if (strcmp(default_mode, "label") == 0)
|
|
{
|
|
this->DefaultMode = vtkSMChartSeriesSelectionDomain::LABEL;
|
|
}
|
|
else if (strcmp(default_mode, "color") == 0)
|
|
{
|
|
this->DefaultMode = vtkSMChartSeriesSelectionDomain::COLOR;
|
|
}
|
|
else if (strcmp(default_mode, "value") == 0)
|
|
{
|
|
this->DefaultMode = vtkSMChartSeriesSelectionDomain::VALUE;
|
|
if (element->GetAttribute("default_value"))
|
|
{
|
|
this->SetDefaultValue(element->GetAttribute("default_value"));
|
|
}
|
|
}
|
|
}
|
|
|
|
const char* flatten_table = element->GetAttribute("flatten_table");
|
|
if (flatten_table)
|
|
{
|
|
this->FlattenTable = (strcmp(default_mode, "true") == 0);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMChartSeriesSelectionDomain::Update(vtkSMProperty*)
|
|
{
|
|
vtkSMProperty* input = this->GetRequiredProperty("Input");
|
|
vtkSMProperty* fieldDataSelection =
|
|
this->GetRequiredProperty("FieldDataSelection");
|
|
vtkSMVectorProperty* compositeIndex = vtkSMVectorProperty::SafeDownCast(
|
|
this->GetRequiredProperty("CompositeIndexSelection"));
|
|
|
|
if (!input || !fieldDataSelection)
|
|
{
|
|
vtkWarningMacro("Missing required properties. Update failed.");
|
|
return;
|
|
}
|
|
|
|
// build strings based on the current domain.
|
|
vtkPVDataInformation* dataInfo = this->GetInputInformation();
|
|
if (!dataInfo)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// clear old component names.
|
|
this->Internals->VisibilityOverrides.clear();
|
|
|
|
if (compositeIndex == NULL ||
|
|
dataInfo->GetCompositeDataInformation()->GetDataIsComposite() == 0)
|
|
{
|
|
// since there's no way to choose which dataset from a composite one to use,
|
|
// just look at the top-level array information (skipping partial arrays).
|
|
std::vector<vtkStdString> column_names;
|
|
int fieldAssociation = vtkSMUncheckedPropertyHelper(fieldDataSelection).GetAsInt(0);
|
|
this->PopulateAvailableArrays(std::string(),
|
|
column_names, dataInfo, fieldAssociation, this->FlattenTable);
|
|
this->SetStrings(column_names);
|
|
return;
|
|
}
|
|
|
|
std::vector<vtkStdString> column_names;
|
|
int fieldAssociation = vtkSMUncheckedPropertyHelper(fieldDataSelection).GetAsInt(0);
|
|
|
|
vtkSMUncheckedPropertyHelper compositeIndexHelper(compositeIndex);
|
|
unsigned int numElems = compositeIndexHelper.GetNumberOfElements();
|
|
for (unsigned int cc=0; cc < numElems; cc++)
|
|
{
|
|
vtkPVDataInformation* childInfo =
|
|
dataInfo->GetDataInformationForCompositeIndex(compositeIndexHelper.GetAsInt(cc));
|
|
if (!childInfo)
|
|
{
|
|
continue;
|
|
}
|
|
std::ostringstream blockNameStream;
|
|
if (compositeIndex->GetRepeatCommand())
|
|
{
|
|
// we don't need to add blockName is the proxy doesn't support selecting
|
|
// multiple blocks in the dataset.
|
|
if (childInfo->GetCompositeDataSetName())
|
|
{
|
|
blockNameStream << childInfo->GetCompositeDataSetName();
|
|
}
|
|
else
|
|
{
|
|
blockNameStream << compositeIndexHelper.GetAsInt(cc);
|
|
}
|
|
}
|
|
// if there is only 1 element, use the element to avoid having partial data.
|
|
vtkPVDataInformation* dataInfoWithArrays =
|
|
numElems == 1 ? childInfo : dataInfo;
|
|
this->PopulateAvailableArrays(blockNameStream.str(),
|
|
column_names, dataInfoWithArrays, fieldAssociation,
|
|
this->FlattenTable);
|
|
}
|
|
this->SetStrings(column_names);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Add arrays from dataInfo to strings. If blockName is non-empty, then it's
|
|
// used to "uniquify" the array names.
|
|
void vtkSMChartSeriesSelectionDomain::PopulateAvailableArrays(
|
|
const std::string& blockName,
|
|
std::vector<vtkStdString>& strings,
|
|
vtkPVDataInformation* dataInfo, int fieldAssociation, bool flattenTable)
|
|
{
|
|
// this method is typically called for leaf nodes (or multi-piece).
|
|
// assert((dataInfo->GetCompositeDataInformation()->GetDataIsComposite() == 0) ||
|
|
// (dataInfo->GetCompositeDataInformation()->GetDataIsMultiPiece() == 0));
|
|
vtkChartRepresentation* chartRepr = vtkChartRepresentation::SafeDownCast(
|
|
this->GetProperty()->GetParent()->GetClientSideObject());
|
|
if (!chartRepr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// helps use avoid duplicates. duplicates may arise for plot types that treat
|
|
// multiple columns as a single series/plot e.g. quartile plots.
|
|
std::set<vtkStdString> uniquestrings;
|
|
|
|
vtkPVDataSetAttributesInformation* dsa =
|
|
dataInfo->GetAttributeInformation(fieldAssociation);
|
|
for (int cc=0; dsa != NULL && cc < dsa->GetNumberOfArrays(); cc++)
|
|
{
|
|
vtkPVArrayInformation* arrayInfo = dsa->GetArrayInformation(cc);
|
|
this->PopulateArrayComponents(chartRepr, blockName, strings, uniquestrings,
|
|
arrayInfo, flattenTable);
|
|
}
|
|
|
|
if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS)
|
|
{
|
|
vtkPVArrayInformation* pointArrayInfo = dataInfo->GetPointArrayInformation();
|
|
this->PopulateArrayComponents(chartRepr, blockName, strings, uniquestrings,
|
|
pointArrayInfo, flattenTable);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Add array component from arrayInfo to strings. If blockName is non-empty, then it's
|
|
// used to "uniquify" the array names.
|
|
void vtkSMChartSeriesSelectionDomain::PopulateArrayComponents(
|
|
vtkChartRepresentation* chartRepr,
|
|
const std::string& blockName, std::vector<vtkStdString>& strings,
|
|
std::set<vtkStdString>& uniquestrings,
|
|
vtkPVArrayInformation* arrayInfo, bool flattenTable)
|
|
{
|
|
if (arrayInfo != NULL && arrayInfo->GetIsPartial() != 1)
|
|
{
|
|
if (arrayInfo->GetNumberOfComponents() > 1 && flattenTable)
|
|
{
|
|
for (int kk=0; kk <= arrayInfo->GetNumberOfComponents(); kk++)
|
|
{
|
|
std::string component_name = vtkSMArrayListDomain::CreateMangledName(arrayInfo, kk);
|
|
component_name = chartRepr->GetDefaultSeriesLabel(blockName, component_name);
|
|
if (uniquestrings.find(component_name) == uniquestrings.end())
|
|
{
|
|
strings.push_back(component_name);
|
|
uniquestrings.insert(component_name);
|
|
}
|
|
if (kk != arrayInfo->GetNumberOfComponents())
|
|
{
|
|
// save component names so we can detect them when setting defaults
|
|
// later.
|
|
this->SetDefaultVisibilityOverride(component_name, false);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char* arrayName = arrayInfo->GetName();
|
|
if (arrayName != NULL)
|
|
{
|
|
std::string seriesName = chartRepr->GetDefaultSeriesLabel(blockName, arrayName);
|
|
if (uniquestrings.find(seriesName) == uniquestrings.end())
|
|
{
|
|
strings.push_back(seriesName);
|
|
uniquestrings.insert(seriesName);
|
|
|
|
// Special case for Quartile plots. PlotSelectionOverTime filter, when
|
|
// produces stats, likes to pre-split components in an array into multiple
|
|
// single component arrays. We still want those to be treated as
|
|
// components and not be shown by default. Hence, we use this hack.
|
|
// (See BUG #15512).
|
|
std::string seriesNameWithoutTableName = chartRepr->GetDefaultSeriesLabel(
|
|
std::string(), arrayName);
|
|
if (PotentailComponentNameRe.find(seriesNameWithoutTableName))
|
|
{
|
|
this->SetDefaultVisibilityOverride(seriesName, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
std::vector<vtkStdString> vtkSMChartSeriesSelectionDomain::GetDefaultValue(const char* series)
|
|
{
|
|
std::vector<vtkStdString> values;
|
|
if (this->DefaultMode == VISIBILITY)
|
|
{
|
|
values.push_back(
|
|
this->GetDefaultSeriesVisibility(series)?
|
|
"1" : "0");
|
|
}
|
|
else if (this->DefaultMode == LABEL)
|
|
{
|
|
// by default, label is same as the name of the series.
|
|
values.push_back(series);
|
|
}
|
|
else if (this->DefaultMode == COLOR)
|
|
{
|
|
vtkColor3ub color = this->Internals->GetNextColor();
|
|
for (int kk=0; kk < 3; kk++)
|
|
{
|
|
std::ostringstream stream;
|
|
stream << std::setprecision(2) << color.GetData()[kk]/255.0;
|
|
values.push_back(stream.str());
|
|
}
|
|
}
|
|
else if (this->DefaultMode == VALUE)
|
|
{
|
|
values.push_back(this->DefaultValue);
|
|
}
|
|
return values;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkSMChartSeriesSelectionDomain::SetDefaultValues(
|
|
vtkSMProperty* property, bool use_unchecked_values)
|
|
{
|
|
vtkSMStringVectorProperty* vp = vtkSMStringVectorProperty::SafeDownCast(property);
|
|
if (!vp)
|
|
{
|
|
vtkErrorMacro("Property must be a vtkSMVectorProperty subclass.");
|
|
return 0;
|
|
}
|
|
if (use_unchecked_values)
|
|
{
|
|
vtkWarningMacro("Developer warning: use_unchecked_values not implemented yet.");
|
|
}
|
|
|
|
this->UpdateDefaultValues(property, false);
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMChartSeriesSelectionDomain::UpdateDefaultValues(
|
|
vtkSMProperty* property, bool preserve_previous_values)
|
|
{
|
|
vtkSMStringVectorProperty* vp = vtkSMStringVectorProperty::SafeDownCast(property);
|
|
assert(vp != NULL);
|
|
|
|
vtkNew<vtkStringList> values;
|
|
std::set<std::string> seriesNames;
|
|
if (preserve_previous_values)
|
|
{
|
|
// capture old values.
|
|
unsigned int numElems = vp->GetNumberOfElements();
|
|
int stepSize = vp->GetNumberOfElementsPerCommand() > 0?
|
|
vp->GetNumberOfElementsPerCommand() : 1;
|
|
|
|
for (unsigned int cc=0; (cc+stepSize) <= numElems; cc+=stepSize)
|
|
{
|
|
seriesNames.insert(vp->GetElement(cc)? vp->GetElement(cc) : "");
|
|
for (int kk=0; kk < stepSize; kk++)
|
|
{
|
|
values->AddString(vp->GetElement(cc+kk));
|
|
}
|
|
}
|
|
}
|
|
|
|
const std::vector<vtkStdString>& domain_strings = this->GetStrings();
|
|
for (size_t cc=0; cc < domain_strings.size(); cc++)
|
|
{
|
|
if (preserve_previous_values &&
|
|
seriesNames.find(domain_strings[cc]) != seriesNames.end())
|
|
{
|
|
// skip this. This series had a value set already which we are requested
|
|
// to preserve.
|
|
continue;
|
|
}
|
|
std::vector<vtkStdString> cur_values =
|
|
this->GetDefaultValue(domain_strings[cc].c_str());
|
|
if (cur_values.size() > 0)
|
|
{
|
|
values->AddString(domain_strings[cc].c_str());
|
|
for (size_t kk=0; kk < cur_values.size(); kk++)
|
|
{
|
|
values->AddString(cur_values[kk].c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
vp->SetElements(values.GetPointer());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMChartSeriesSelectionDomain::AddSeriesVisibilityDefault(
|
|
const char* name, bool value)
|
|
{
|
|
::AddSeriesVisibilityDefault(name, value);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkSMChartSeriesSelectionDomain::GetDefaultSeriesVisibility(const char* name)
|
|
{
|
|
bool result;
|
|
if (::GetSeriesVisibilityDefault(name, result))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if (this->Internals->VisibilityOverrides.find(name) !=
|
|
this->Internals->VisibilityOverrides.end())
|
|
{
|
|
// hide components by default, we'll show the magnitudes for them.
|
|
return this->Internals->VisibilityOverrides[name];
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMChartSeriesSelectionDomain::OnDomainModified()
|
|
{
|
|
vtkSMProperty* prop = this->GetProperty();
|
|
this->UpdateDefaultValues(prop, true);
|
|
if (prop->GetParent())
|
|
{
|
|
// FIXME:
|
|
// prop->GetParent()->UpdateProperty(prop);
|
|
prop->GetParent()->UpdateVTKObjects();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMChartSeriesSelectionDomain::SetDefaultVisibilityOverride(
|
|
const vtkStdString& arrayname, bool visibility)
|
|
{
|
|
this->Internals->VisibilityOverrides[arrayname] = visibility;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkSMChartSeriesSelectionDomain::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|