mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 09:59:12 +00:00
377 lines
11 KiB
C++
377 lines
11 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.
|
|
//============================================================================
|
|
|
|
#include <vtkm/cont/CellSetExplicit.h>
|
|
#include <vtkm/cont/CellSetExtrude.h>
|
|
#include <vtkm/cont/CellSetSingleType.h>
|
|
#include <vtkm/cont/CellSetStructured.h>
|
|
#include <vtkm/cont/DataSet.h>
|
|
#include <vtkm/cont/ErrorBadValue.h>
|
|
#include <vtkm/cont/Logging.h>
|
|
|
|
#include <algorithm>
|
|
|
|
namespace
|
|
{
|
|
|
|
VTKM_CONT void CheckFieldSize(const vtkm::cont::UnknownCellSet& cellSet,
|
|
const vtkm::cont::Field& field)
|
|
{
|
|
if (!cellSet.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
switch (field.GetAssociation())
|
|
{
|
|
case vtkm::cont::Field::Association::Points:
|
|
if (cellSet.GetNumberOfPoints() != field.GetData().GetNumberOfValues())
|
|
{
|
|
VTKM_LOG_S(vtkm::cont::LogLevel::Warn,
|
|
"The size of field `"
|
|
<< field.GetName() << "` (" << field.GetData().GetNumberOfValues()
|
|
<< " values) does not match the size of the data set structure ("
|
|
<< cellSet.GetNumberOfPoints() << " points).");
|
|
}
|
|
break;
|
|
case vtkm::cont::Field::Association::Cells:
|
|
if (cellSet.GetNumberOfCells() != field.GetData().GetNumberOfValues())
|
|
{
|
|
VTKM_LOG_S(vtkm::cont::LogLevel::Warn,
|
|
"The size of field `"
|
|
<< field.GetName() << "` (" << field.GetData().GetNumberOfValues()
|
|
<< " values) does not match the size of the data set structure ("
|
|
<< cellSet.GetNumberOfCells() << " cells).");
|
|
}
|
|
break;
|
|
default:
|
|
// Ignore as the association does not match any topological element.
|
|
break;
|
|
}
|
|
}
|
|
|
|
VTKM_CONT void CheckFieldSizes(const vtkm::cont::UnknownCellSet& cellSet,
|
|
const vtkm::cont::internal::FieldCollection& fields)
|
|
{
|
|
vtkm::IdComponent numFields = fields.GetNumberOfFields();
|
|
for (vtkm::IdComponent fieldIndex = 0; fieldIndex < numFields; ++fieldIndex)
|
|
{
|
|
CheckFieldSize(cellSet, fields.GetField(fieldIndex));
|
|
}
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace cont
|
|
{
|
|
|
|
VTKM_CONT std::string& GlobalGhostCellFieldName() noexcept
|
|
{
|
|
static std::string GhostCellName("vtkGhostCells");
|
|
return GhostCellName;
|
|
}
|
|
|
|
VTKM_CONT const std::string& GetGlobalGhostCellFieldName() noexcept
|
|
{
|
|
return GlobalGhostCellFieldName();
|
|
}
|
|
|
|
VTKM_CONT void SetGlobalGhostCellFieldName(const std::string& name) noexcept
|
|
{
|
|
GlobalGhostCellFieldName() = name;
|
|
}
|
|
|
|
void DataSet::Clear()
|
|
{
|
|
this->CoordSystemNames.clear();
|
|
this->Fields.Clear();
|
|
this->CellSet = this->CellSet.NewInstance();
|
|
}
|
|
|
|
void DataSet::AddField(const Field& field)
|
|
{
|
|
CheckFieldSize(this->CellSet, field);
|
|
this->Fields.AddField(field);
|
|
}
|
|
|
|
vtkm::Id DataSet::GetNumberOfCells() const
|
|
{
|
|
return this->CellSet.GetNumberOfCells();
|
|
}
|
|
|
|
vtkm::Id DataSet::GetNumberOfPoints() const
|
|
{
|
|
if (this->CellSet.IsValid())
|
|
{
|
|
return this->CellSet.GetNumberOfPoints();
|
|
}
|
|
|
|
// If there is no cell set, then try to use a coordinate system to get the number
|
|
// of points.
|
|
if (this->GetNumberOfCoordinateSystems() > 0)
|
|
{
|
|
return this->GetCoordinateSystem().GetNumberOfPoints();
|
|
}
|
|
|
|
// If there is no coordinate system either, we can try to guess the number of
|
|
// points by finding a point field.
|
|
for (vtkm::IdComponent fieldIdx = 0; fieldIdx < this->Fields.GetNumberOfFields(); ++fieldIdx)
|
|
{
|
|
const vtkm::cont::Field& field = this->Fields.GetField(fieldIdx);
|
|
if (field.GetAssociation() == vtkm::cont::Field::Association::Points)
|
|
{
|
|
return field.GetData().GetNumberOfValues();
|
|
}
|
|
}
|
|
|
|
// There are no point fields either.
|
|
return 0;
|
|
}
|
|
|
|
const std::string& DataSet::GetGhostCellFieldName() const
|
|
{
|
|
if (this->GhostCellName)
|
|
{
|
|
return *this->GhostCellName;
|
|
}
|
|
else
|
|
{
|
|
return GetGlobalGhostCellFieldName();
|
|
}
|
|
}
|
|
|
|
bool DataSet::HasGhostCellField() const
|
|
{
|
|
return this->HasCellField(this->GetGhostCellFieldName());
|
|
}
|
|
|
|
vtkm::cont::Field DataSet::GetGhostCellField() const
|
|
{
|
|
if (this->HasGhostCellField())
|
|
{
|
|
return this->GetCellField(this->GetGhostCellFieldName());
|
|
}
|
|
else
|
|
{
|
|
return make_FieldCell(
|
|
this->GetGhostCellFieldName(),
|
|
vtkm::cont::ArrayHandleConstant<vtkm::UInt8>(0, this->GetNumberOfCells()));
|
|
}
|
|
}
|
|
|
|
vtkm::IdComponent DataSet::AddCoordinateSystem(const vtkm::cont::CoordinateSystem& cs)
|
|
{
|
|
this->AddField(cs);
|
|
return this->AddCoordinateSystem(cs.GetName());
|
|
}
|
|
|
|
vtkm::IdComponent DataSet::AddCoordinateSystem(const std::string& pointFieldName)
|
|
{
|
|
// Check to see if we already have this coordinate system.
|
|
vtkm::IdComponent index = this->GetCoordinateSystemIndex(pointFieldName);
|
|
if (index >= 0)
|
|
{
|
|
return index;
|
|
}
|
|
|
|
// Check to make sure this is a valid point field.
|
|
if (!this->HasPointField(pointFieldName))
|
|
{
|
|
throw vtkm::cont::ErrorBadValue("Cannot set point field named `" + pointFieldName +
|
|
"` as a coordinate system because it does not exist.");
|
|
}
|
|
|
|
// Add the field to the list of coordinates.
|
|
this->CoordSystemNames.push_back(pointFieldName);
|
|
return static_cast<vtkm::IdComponent>(this->CoordSystemNames.size() - 1);
|
|
}
|
|
|
|
void DataSet::SetCellSetImpl(const vtkm::cont::UnknownCellSet& cellSet)
|
|
{
|
|
CheckFieldSizes(cellSet, this->Fields);
|
|
this->CellSet = cellSet;
|
|
}
|
|
|
|
void DataSet::SetGhostCellFieldName(const std::string& name)
|
|
{
|
|
this->GhostCellName.reset(new std::string(name));
|
|
}
|
|
|
|
void DataSet::SetGhostCellField(const std::string& name)
|
|
{
|
|
if (this->HasCellField(name))
|
|
{
|
|
this->SetGhostCellFieldName(name);
|
|
}
|
|
else
|
|
{
|
|
throw vtkm::cont::ErrorBadValue("No such cell field " + name);
|
|
}
|
|
}
|
|
|
|
void DataSet::SetGhostCellField(const vtkm::cont::Field& field)
|
|
{
|
|
if (field.GetAssociation() == vtkm::cont::Field::Association::Cells)
|
|
{
|
|
this->SetGhostCellField(field.GetName(), field.GetData());
|
|
}
|
|
else
|
|
{
|
|
throw vtkm::cont::ErrorBadValue("A ghost cell field must be a cell field.");
|
|
}
|
|
}
|
|
|
|
void DataSet::SetGhostCellField(const std::string& fieldName,
|
|
const vtkm::cont::UnknownArrayHandle& field)
|
|
{
|
|
this->AddCellField(fieldName, field);
|
|
this->SetGhostCellField(fieldName);
|
|
}
|
|
|
|
void DataSet::SetGhostCellField(const vtkm::cont::UnknownArrayHandle& field)
|
|
{
|
|
this->SetGhostCellField(GetGlobalGhostCellFieldName(), field);
|
|
}
|
|
|
|
void DataSet::CopyStructure(const vtkm::cont::DataSet& source)
|
|
{
|
|
// Copy the cells.
|
|
this->CellSet = source.CellSet;
|
|
|
|
// Copy the coordinate systems.
|
|
this->CoordSystemNames.clear();
|
|
vtkm::IdComponent numCoords = source.GetNumberOfCoordinateSystems();
|
|
for (vtkm::IdComponent coordIndex = 0; coordIndex < numCoords; ++coordIndex)
|
|
{
|
|
this->AddCoordinateSystem(source.GetCoordinateSystem(coordIndex));
|
|
}
|
|
|
|
// Copy the ghost cells.
|
|
// Note that we copy the GhostCellName separately from the field it points to
|
|
// to preserve (or remove) the case where the ghost cell name follows the
|
|
// global ghost cell name.
|
|
this->GhostCellName = source.GhostCellName;
|
|
if (source.HasGhostCellField())
|
|
{
|
|
this->AddField(source.GetGhostCellField());
|
|
}
|
|
|
|
CheckFieldSizes(this->CellSet, this->Fields);
|
|
}
|
|
|
|
vtkm::cont::CoordinateSystem DataSet::GetCoordinateSystem(vtkm::Id index) const
|
|
{
|
|
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfCoordinateSystems()));
|
|
return this->GetPointField(this->CoordSystemNames[static_cast<std::size_t>(index)]);
|
|
}
|
|
|
|
vtkm::IdComponent DataSet::GetCoordinateSystemIndex(const std::string& name) const
|
|
{
|
|
auto nameIter = std::find(this->CoordSystemNames.begin(), this->CoordSystemNames.end(), name);
|
|
if (nameIter != this->CoordSystemNames.end())
|
|
{
|
|
return static_cast<vtkm::IdComponent>(std::distance(this->CoordSystemNames.begin(), nameIter));
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
const std::string& DataSet::GetCoordinateSystemName(vtkm::Id index) const
|
|
{
|
|
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfCoordinateSystems()));
|
|
return this->CoordSystemNames[static_cast<std::size_t>(index)];
|
|
}
|
|
|
|
vtkm::cont::CoordinateSystem DataSet::GetCoordinateSystem(const std::string& name) const
|
|
{
|
|
vtkm::Id index = this->GetCoordinateSystemIndex(name);
|
|
if (index < 0)
|
|
{
|
|
std::string error_message("No coordinate system with the name " + name +
|
|
" valid names are: \n");
|
|
for (const auto& csn : this->CoordSystemNames)
|
|
{
|
|
error_message += csn + "\n";
|
|
}
|
|
throw vtkm::cont::ErrorBadValue(error_message);
|
|
}
|
|
return this->GetCoordinateSystem(index);
|
|
}
|
|
|
|
void DataSet::PrintSummary(std::ostream& out) const
|
|
{
|
|
out << "DataSet:\n";
|
|
out << " CoordSystems[" << this->CoordSystemNames.size() << "]\n";
|
|
out << " ";
|
|
for (const auto& csn : this->CoordSystemNames)
|
|
{
|
|
out << " " << csn;
|
|
}
|
|
out << "\n";
|
|
|
|
out << " CellSet \n";
|
|
this->GetCellSet().PrintSummary(out);
|
|
|
|
out << " Fields[" << this->GetNumberOfFields() << "]\n";
|
|
for (vtkm::Id index = 0; index < this->GetNumberOfFields(); index++)
|
|
{
|
|
this->GetField(index).PrintSummary(out);
|
|
}
|
|
|
|
out.flush();
|
|
}
|
|
|
|
void DataSet::ConvertToExpected()
|
|
{
|
|
for (vtkm::IdComponent coordIndex = 0; coordIndex < this->GetNumberOfCoordinateSystems();
|
|
++coordIndex)
|
|
{
|
|
this->GetCoordinateSystem(coordIndex).ConvertToExpected();
|
|
}
|
|
|
|
for (vtkm::IdComponent fieldIndex = 0; fieldIndex < this->GetNumberOfFields(); ++fieldIndex)
|
|
{
|
|
this->GetField(fieldIndex).ConvertToExpected();
|
|
}
|
|
}
|
|
|
|
} // namespace cont
|
|
} // namespace vtkm
|
|
|
|
|
|
namespace mangled_diy_namespace
|
|
{
|
|
|
|
using SerializedCellSetTypes = vtkm::ListAppend<VTKM_DEFAULT_CELL_SET_LIST,
|
|
vtkm::List<vtkm::cont::CellSetStructured<1>,
|
|
vtkm::cont::CellSetStructured<2>,
|
|
vtkm::cont::CellSetStructured<3>,
|
|
vtkm::cont::CellSetExplicit<>,
|
|
vtkm::cont::CellSetSingleType<>,
|
|
vtkm::cont::CellSetExtrude>>;
|
|
using DefaultDataSetWithCellTypes = vtkm::cont::DataSetWithCellSetTypes<SerializedCellSetTypes>;
|
|
|
|
void Serialization<vtkm::cont::DataSet>::save(BinaryBuffer& bb, const vtkm::cont::DataSet& obj)
|
|
{
|
|
vtkmdiy::save(bb, DefaultDataSetWithCellTypes{ obj });
|
|
}
|
|
|
|
void Serialization<vtkm::cont::DataSet>::load(BinaryBuffer& bb, vtkm::cont::DataSet& obj)
|
|
{
|
|
DefaultDataSetWithCellTypes data;
|
|
vtkmdiy::load(bb, data);
|
|
obj = data.DataSet;
|
|
}
|
|
|
|
} // namespace mangled_diy_namespace
|