783bc15ffd
As a general C++ "rule of three," if one of a copy constructor, copy assignment, or destructor is defined, all three should be defined. Some compilers issue warnings if this rule of three is violated. It is sometimes the case that we define a destructor simply because it is only valid in the control environment. When doing so, add implementations for copy constructor and assignment as well.
279 lines
7.8 KiB
C++
279 lines
7.8 KiB
C++
//============================================================================
|
|
// Copyright (c) Kitware, Inc.
|
|
// All rights reserved.
|
|
// See LICENSE.txt 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.
|
|
//============================================================================
|
|
#ifndef vtk_m_filter_FieldSelection_h
|
|
#define vtk_m_filter_FieldSelection_h
|
|
|
|
#include <initializer_list>
|
|
#include <set>
|
|
#include <vtkm/Pair.h>
|
|
#include <vtkm/cont/Field.h>
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace filter
|
|
{
|
|
|
|
/// A \c FieldSelection stores information about fields to map for input dataset to output
|
|
/// when a filter is executed. A \c FieldSelection object is passed to
|
|
/// `vtkm::filter::Filter::Execute` to execute the filter and map selected
|
|
/// fields. It is possible to easily construct \c FieldSelection that selects all or
|
|
/// none of the input fields.
|
|
class FieldSelection
|
|
{
|
|
public:
|
|
enum ModeEnum
|
|
{
|
|
MODE_NONE,
|
|
MODE_ALL,
|
|
MODE_SELECT,
|
|
MODE_EXCLUDE
|
|
};
|
|
|
|
VTKM_CONT
|
|
FieldSelection(ModeEnum mode = MODE_SELECT)
|
|
: Mode(mode)
|
|
{
|
|
}
|
|
|
|
/// Use this constructor to create a field selection given a single field name
|
|
/// \code{cpp}
|
|
/// FieldSelection("field_name");
|
|
/// \endcode
|
|
VTKM_CONT
|
|
FieldSelection(const std::string& field, ModeEnum mode = MODE_SELECT)
|
|
: Mode(mode)
|
|
{
|
|
this->AddField(field, vtkm::cont::Field::Association::ANY);
|
|
}
|
|
|
|
/// Use this constructor to create a field selection given a single field name
|
|
/// \code{cpp}
|
|
/// FieldSelection("field_name");
|
|
/// \endcode
|
|
VTKM_CONT
|
|
FieldSelection(const char* field, ModeEnum mode = MODE_SELECT)
|
|
: Mode(mode)
|
|
{
|
|
this->AddField(field, vtkm::cont::Field::Association::ANY);
|
|
}
|
|
|
|
/// Use this constructor to create a field selection given a single name and association.
|
|
/// \code{cpp}
|
|
/// FieldSelection("field_name", vtkm::cont::Field::Association::POINTS)
|
|
/// \endcode{cpp}
|
|
VTKM_CONT
|
|
FieldSelection(const std::string& field,
|
|
vtkm::cont::Field::Association association,
|
|
ModeEnum mode = MODE_SELECT)
|
|
: Mode(mode)
|
|
{
|
|
this->AddField(field, association);
|
|
}
|
|
|
|
/// Use this constructor to create a field selection given the field names.
|
|
/// \code{cpp}
|
|
/// FieldSelection({"field_one", "field_two"});
|
|
/// \endcode
|
|
VTKM_CONT
|
|
FieldSelection(std::initializer_list<std::string> fields, ModeEnum mode = MODE_SELECT)
|
|
: Mode(mode)
|
|
{
|
|
for (const std::string& afield : fields)
|
|
{
|
|
this->AddField(afield, vtkm::cont::Field::Association::ANY);
|
|
}
|
|
}
|
|
|
|
/// Use this constructor create a field selection given the field names and
|
|
/// associations e.g.
|
|
/// @code{cpp}
|
|
/// using pair_type = std::pair<std::string, vtkm::cont::Field::Association>;
|
|
/// FieldSelection({
|
|
/// pair_type{"field_one", vtkm::cont::Field::Association::POINTS},
|
|
/// pair_type{"field_two", vtkm::cont::Field::Association::CELL_SET} });
|
|
/// @endcode
|
|
VTKM_CONT
|
|
FieldSelection(
|
|
std::initializer_list<std::pair<std::string, vtkm::cont::Field::Association>> fields,
|
|
ModeEnum mode = MODE_SELECT)
|
|
: Mode(mode)
|
|
{
|
|
for (const auto& item : fields)
|
|
{
|
|
this->AddField(item.first, item.second);
|
|
}
|
|
}
|
|
|
|
/// Use this constructor create a field selection given the field names and
|
|
/// associations e.g.
|
|
/// @code{cpp}
|
|
/// using pair_type = vtkm::Pair<std::string, vtkm::cont::Field::Association>;
|
|
/// FieldSelection({
|
|
/// pair_type{"field_one", vtkm::cont::Field::Association::POINTS},
|
|
/// pair_type{"field_two", vtkm::cont::Field::Association::CELL_SET} });
|
|
/// @endcode
|
|
VTKM_CONT
|
|
FieldSelection(
|
|
std::initializer_list<vtkm::Pair<std::string, vtkm::cont::Field::Association>> fields,
|
|
ModeEnum mode = MODE_SELECT)
|
|
: Mode(mode)
|
|
{
|
|
for (const auto& item : fields)
|
|
{
|
|
this->AddField(item.first, item.second);
|
|
}
|
|
}
|
|
|
|
// Normally the default compiler construction of each of these would be fine,
|
|
// but we don't want any of them compiled for devices (like CUDA), so we have
|
|
// to explicitly mark them as VTKM_CONT.
|
|
VTKM_CONT FieldSelection(const FieldSelection& src)
|
|
: Mode(src.Mode)
|
|
, Fields(src.Fields)
|
|
{
|
|
}
|
|
VTKM_CONT FieldSelection(FieldSelection&& rhs)
|
|
: Mode(rhs.Mode)
|
|
, Fields(std::move(rhs.Fields))
|
|
{
|
|
}
|
|
VTKM_CONT FieldSelection& operator=(const FieldSelection& src)
|
|
{
|
|
this->Mode = src.Mode;
|
|
this->Fields = src.Fields;
|
|
return *this;
|
|
}
|
|
VTKM_CONT FieldSelection& operator=(FieldSelection&& rhs)
|
|
{
|
|
this->Mode = rhs.Mode;
|
|
this->Fields = std::move(rhs.Fields);
|
|
return *this;
|
|
}
|
|
VTKM_CONT ~FieldSelection() {}
|
|
|
|
/// Returns true if the input field should be mapped to the output
|
|
/// dataset.
|
|
VTKM_CONT
|
|
bool IsFieldSelected(const vtkm::cont::Field& inputField) const
|
|
{
|
|
return this->IsFieldSelected(inputField.GetName(), inputField.GetAssociation());
|
|
}
|
|
|
|
bool IsFieldSelected(
|
|
const std::string& name,
|
|
vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY) const
|
|
{
|
|
switch (this->Mode)
|
|
{
|
|
case MODE_NONE:
|
|
return false;
|
|
|
|
case MODE_ALL:
|
|
return true;
|
|
|
|
case MODE_SELECT:
|
|
default:
|
|
return this->HasField(name, association);
|
|
|
|
case MODE_EXCLUDE:
|
|
return !this->HasField(name, association);
|
|
}
|
|
}
|
|
|
|
//@{
|
|
/// Add fields to map. Note, if Mode is not MODE_SELECT, then adding fields
|
|
/// will have no impact of the fields that will be mapped.
|
|
VTKM_CONT
|
|
void AddField(const vtkm::cont::Field& inputField)
|
|
{
|
|
this->AddField(inputField.GetName(), inputField.GetAssociation());
|
|
}
|
|
|
|
VTKM_CONT
|
|
void AddField(const std::string& fieldName,
|
|
vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY)
|
|
{
|
|
this->Fields.insert(Field(fieldName, association));
|
|
}
|
|
//@}
|
|
|
|
/// Returns true if the input field has been added to this selection.
|
|
/// Note that depending on the mode of this selection, the result of HasField
|
|
/// is not necessarily the same as IsFieldSelected. (If the mode is MODE_SELECT,
|
|
/// then the result of the two will be the same.)
|
|
VTKM_CONT
|
|
bool HasField(const vtkm::cont::Field& inputField) const
|
|
{
|
|
return this->HasField(inputField.GetName(), inputField.GetAssociation());
|
|
}
|
|
|
|
bool HasField(
|
|
const std::string& name,
|
|
vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY) const
|
|
{
|
|
if (this->Fields.find(Field(name, association)) != this->Fields.end())
|
|
{
|
|
return true;
|
|
}
|
|
// if not exact match, let's lookup for Association::ANY.
|
|
for (const auto& aField : this->Fields)
|
|
{
|
|
if (aField.Name == name)
|
|
{
|
|
if (aField.Association == vtkm::cont::Field::Association::ANY ||
|
|
association == vtkm::cont::Field::Association::ANY)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// Clear all fields added using `AddField`.
|
|
VTKM_CONT
|
|
void ClearFields() { this->Fields.clear(); }
|
|
|
|
VTKM_CONT
|
|
ModeEnum GetMode() const { return this->Mode; }
|
|
void SetMode(ModeEnum val) { this->Mode = val; }
|
|
|
|
private:
|
|
ModeEnum Mode; ///< mode
|
|
|
|
struct Field
|
|
{
|
|
std::string Name;
|
|
vtkm::cont::Field::Association Association;
|
|
Field() = default;
|
|
Field(const std::string& name, vtkm::cont::Field::Association assoc)
|
|
: Name(name)
|
|
, Association(assoc)
|
|
{
|
|
}
|
|
|
|
Field(const Field&) = default;
|
|
Field& operator=(const Field&) = default;
|
|
|
|
bool operator<(const Field& other) const
|
|
{
|
|
return (this->Association == other.Association) ? (this->Name < other.Name)
|
|
: (this->Association < other.Association);
|
|
}
|
|
};
|
|
|
|
std::set<Field> Fields;
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
#endif // vtk_m_filter_FieldSelection_h
|