vtk-m/vtkm/filter/CleanGrid.hxx

200 lines
6.6 KiB
C++
Raw Normal View History

2016-11-06 22:15:22 +00:00
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
2019-04-15 23:24:21 +00:00
//
2016-11-06 22:15:22 +00:00
// 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/filter/CleanGrid.h>
2016-11-06 22:15:22 +00:00
#include <vtkm/worklet/CellDeepCopy.h>
#include <vtkm/worklet/RemoveUnusedPoints.h>
#include <vector>
2017-05-18 14:29:41 +00:00
namespace vtkm
{
namespace filter
{
2016-11-06 22:15:22 +00:00
2017-05-18 14:29:41 +00:00
inline VTKM_CONT CleanGrid::CleanGrid()
2016-11-06 22:15:22 +00:00
: CompactPointFields(true)
, MergePoints(true)
, Tolerance(1.0e-6)
, ToleranceIsAbsolute(false)
, RemoveDegenerateCells(true)
, FastMerge(true)
2017-05-18 14:29:41 +00:00
{
}
template <typename Policy>
inline VTKM_CONT vtkm::cont::DataSet CleanGrid::DoExecute(const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> policy)
2016-11-06 22:15:22 +00:00
{
using CellSetType = vtkm::cont::CellSetExplicit<>;
using VecId = std::size_t;
2016-11-06 22:15:22 +00:00
VecId activeCoordIndex = static_cast<VecId>(this->GetActiveCoordinateSystemIndex());
CellSetType outputCellSet;
2016-11-06 22:15:22 +00:00
// Do a deep copy of the cells to new CellSetExplicit structures
const vtkm::cont::DynamicCellSet& inCellSet = inData.GetCellSet();
if (inCellSet.IsType<CellSetType>())
2016-11-06 22:15:22 +00:00
{
// Is expected type, do a shallow copy
outputCellSet = inCellSet.Cast<CellSetType>();
2016-11-06 22:15:22 +00:00
}
else
{ // Clean the grid
auto deducedCellSet = vtkm::filter::ApplyPolicyCellSet(inCellSet, policy);
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
this->Invoke(worklet::CellDeepCopy::CountCellPoints{}, deducedCellSet, numIndices);
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
vtkm::Id connectivitySize;
vtkm::cont::ConvertNumComponentsToOffsets(numIndices, offsets, connectivitySize);
numIndices.ReleaseResourcesExecution();
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
connectivity.Allocate(connectivitySize);
this->Invoke(worklet::CellDeepCopy::PassCellStructure{},
deducedCellSet,
shapes,
vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, offsets));
shapes.ReleaseResourcesExecution();
offsets.ReleaseResourcesExecution();
connectivity.ReleaseResourcesExecution();
outputCellSet.Fill(
deducedCellSet.GetNumberOfPoints(), shapes, numIndices, connectivity, offsets);
//Release the input grid from the execution space
deducedCellSet.ReleaseResourcesExecution();
}
2016-11-06 22:15:22 +00:00
VecId numCoordSystems = static_cast<VecId>(inData.GetNumberOfCoordinateSystems());
std::vector<vtkm::cont::CoordinateSystem> outputCoordinateSystems(numCoordSystems);
// Start with a shallow copy of the coordinate systems
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
outputCoordinateSystems[coordSystemIndex] =
inData.GetCoordinateSystem(static_cast<vtkm::IdComponent>(coordSystemIndex));
}
2016-11-06 22:15:22 +00:00
// Optionally adjust the cell set indices to remove all unused points
if (this->GetCompactPointFields())
{
this->PointCompactor.FindPointsStart();
this->PointCompactor.FindPoints(outputCellSet);
this->PointCompactor.FindPointsEnd();
2016-11-06 22:15:22 +00:00
outputCellSet = this->PointCompactor.MapCellSet(outputCellSet);
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
outputCoordinateSystems[coordSystemIndex] =
vtkm::cont::CoordinateSystem(outputCoordinateSystems[coordSystemIndex].GetName(),
this->PointCompactor.MapPointFieldDeep(
outputCoordinateSystems[coordSystemIndex].GetData()));
}
}
// Optionally find and merge coincident points
if (this->GetMergePoints())
{
vtkm::cont::CoordinateSystem activeCoordSystem = outputCoordinateSystems[activeCoordIndex];
vtkm::Bounds bounds = activeCoordSystem.GetBounds();
vtkm::Float64 delta = this->GetTolerance();
if (!this->GetToleranceIsAbsolute())
{
delta *=
vtkm::Magnitude(vtkm::make_Vec(bounds.X.Length(), bounds.Y.Length(), bounds.Z.Length()));
}
auto coordArray = activeCoordSystem.GetData();
this->PointMerger.Run(delta, this->GetFastMerge(), bounds, coordArray);
activeCoordSystem = vtkm::cont::CoordinateSystem(activeCoordSystem.GetName(), coordArray);
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
{
if (coordSystemIndex == activeCoordIndex)
{
outputCoordinateSystems[coordSystemIndex] = activeCoordSystem;
}
else
{
outputCoordinateSystems[coordSystemIndex] = vtkm::cont::CoordinateSystem(
outputCoordinateSystems[coordSystemIndex].GetName(),
this->PointMerger.MapPointField(outputCoordinateSystems[coordSystemIndex].GetData()));
}
}
outputCellSet = this->PointMerger.MapCellSet(outputCellSet);
2016-11-06 22:15:22 +00:00
}
// Optionally remove degenerate cells
if (this->GetRemoveDegenerateCells())
{
outputCellSet = this->CellCompactor.Run(outputCellSet);
}
2016-11-06 22:15:22 +00:00
// Construct resulting data set with new cell sets
vtkm::cont::DataSet outData;
outData.SetCellSet(outputCellSet);
2016-11-06 22:15:22 +00:00
// Pass the coordinate systems
for (VecId coordSystemIndex = 0; coordSystemIndex < numCoordSystems; ++coordSystemIndex)
2016-11-06 22:15:22 +00:00
{
outData.AddCoordinateSystem(outputCoordinateSystems[coordSystemIndex]);
2016-11-06 22:15:22 +00:00
}
return outData;
2016-11-06 22:15:22 +00:00
}
template <typename ValueType, typename Storage, typename Policy>
2017-05-18 14:29:41 +00:00
inline VTKM_CONT bool CleanGrid::DoMapField(
vtkm::cont::DataSet& result,
const vtkm::cont::ArrayHandle<ValueType, Storage>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<Policy>)
2016-11-06 22:15:22 +00:00
{
if (fieldMeta.IsPointField() && (this->GetCompactPointFields() || this->GetMergePoints()))
2016-11-06 22:15:22 +00:00
{
vtkm::cont::ArrayHandle<ValueType> compactedArray;
if (this->GetCompactPointFields())
{
compactedArray = this->PointCompactor.MapPointFieldDeep(input);
if (this->GetMergePoints())
{
compactedArray = this->PointMerger.MapPointField(compactedArray);
}
}
else if (this->GetMergePoints())
{
compactedArray = this->PointMerger.MapPointField(input);
}
result.AddField(fieldMeta.AsField(compactedArray));
2016-11-06 22:15:22 +00:00
}
else if (fieldMeta.IsCellField() && this->GetRemoveDegenerateCells())
{
result.AddField(fieldMeta.AsField(this->CellCompactor.ProcessCellField(input)));
}
2016-11-06 22:15:22 +00:00
else
{
result.AddField(fieldMeta.AsField(input));
2016-11-06 22:15:22 +00:00
}
return true;
}
}
}