mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 10:35:42 +00:00
be7f06bbe7
`CoordinateSystem` differed from `Field` in that its `GetData` method returned an `ArrayHandleVirtualCoordinates` instead of a `VariantArrayHandle`. This is probably confusing since `CoordianteSystem` inherits `Field` and has a pretty dramatic difference in this behavior. In preparation to deprecate `ArrayHandleVirtualCoordinates`, this changes `CoordiantSystem` to be much more like `Field`. (In the future, we may change the `CoordinateSystem` to point to a `Field` rather than be a special `Field`.) A method named `GetDataAsMultiplexer` has been added to `CoordinateSystem`. This method allows you to get data from `CoordinateSystem` as a single array type without worrying about creating functors to handle different types and without needing virtual methods.
157 lines
4.1 KiB
C++
157 lines
4.1 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_SurfaceNormals_hxx
|
|
#define vtk_m_filter_SurfaceNormals_hxx
|
|
|
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
|
|
|
#include <vtkm/worklet/OrientNormals.h>
|
|
#include <vtkm/worklet/SurfaceNormals.h>
|
|
#include <vtkm/worklet/TriangleWinding.h>
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace filter
|
|
{
|
|
|
|
namespace internal
|
|
{
|
|
|
|
inline std::string ComputePointNormalsName(const SurfaceNormals* filter)
|
|
{
|
|
if (!filter->GetPointNormalsName().empty())
|
|
{
|
|
return filter->GetPointNormalsName();
|
|
}
|
|
else if (!filter->GetOutputFieldName().empty())
|
|
{
|
|
return filter->GetOutputFieldName();
|
|
}
|
|
else
|
|
{
|
|
return "Normals";
|
|
}
|
|
}
|
|
|
|
inline std::string ComputeCellNormalsName(const SurfaceNormals* filter)
|
|
{
|
|
if (!filter->GetCellNormalsName().empty())
|
|
{
|
|
return filter->GetCellNormalsName();
|
|
}
|
|
else if (!filter->GetGeneratePointNormals() && !filter->GetOutputFieldName().empty())
|
|
{
|
|
return filter->GetOutputFieldName();
|
|
}
|
|
else
|
|
{
|
|
return "Normals";
|
|
}
|
|
}
|
|
|
|
} // internal
|
|
|
|
inline SurfaceNormals::SurfaceNormals()
|
|
: GenerateCellNormals(false)
|
|
, NormalizeCellNormals(true)
|
|
, GeneratePointNormals(true)
|
|
, AutoOrientNormals(false)
|
|
, FlipNormals(false)
|
|
, Consistency(true)
|
|
{
|
|
this->SetUseCoordinateSystemAsField(true);
|
|
}
|
|
|
|
template <typename T, typename StorageType, typename DerivedPolicy>
|
|
inline vtkm::cont::DataSet SurfaceNormals::DoExecute(
|
|
const vtkm::cont::DataSet& input,
|
|
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>& points,
|
|
const vtkm::filter::FieldMetadata& fieldMeta,
|
|
vtkm::filter::PolicyBase<DerivedPolicy> policy)
|
|
{
|
|
VTKM_ASSERT(fieldMeta.IsPointField());
|
|
|
|
if (!this->GenerateCellNormals && !this->GeneratePointNormals)
|
|
{
|
|
throw vtkm::cont::ErrorFilterExecution("No normals selected.");
|
|
}
|
|
|
|
const auto cellset =
|
|
vtkm::filter::ApplyPolicyCellSetUnstructured(input.GetCellSet(), policy, *this);
|
|
const auto coords =
|
|
input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()).GetDataAsMultiplexer();
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> faceNormals;
|
|
vtkm::worklet::FacetedSurfaceNormals faceted;
|
|
faceted.SetNormalize(this->NormalizeCellNormals);
|
|
faceted.Run(cellset, points, faceNormals);
|
|
|
|
vtkm::cont::DataSet result;
|
|
vtkm::cont::ArrayHandle<vtkm::Vec3f> pointNormals;
|
|
if (this->GeneratePointNormals)
|
|
{
|
|
vtkm::worklet::SmoothSurfaceNormals smooth;
|
|
smooth.Run(cellset, faceNormals, pointNormals);
|
|
|
|
|
|
result = CreateResultFieldPoint(input, pointNormals, internal::ComputePointNormalsName(this));
|
|
if (this->GenerateCellNormals)
|
|
{
|
|
result.AddField(
|
|
vtkm::cont::make_FieldCell(internal::ComputeCellNormalsName(this), faceNormals));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = CreateResultFieldCell(input, faceNormals, internal::ComputeCellNormalsName(this));
|
|
}
|
|
|
|
if (this->AutoOrientNormals)
|
|
{
|
|
using Orient = vtkm::worklet::OrientNormals;
|
|
|
|
if (this->GenerateCellNormals && this->GeneratePointNormals)
|
|
{
|
|
Orient::RunPointAndCellNormals(cellset, coords, pointNormals, faceNormals);
|
|
}
|
|
else if (this->GenerateCellNormals)
|
|
{
|
|
Orient::RunCellNormals(cellset, coords, faceNormals);
|
|
}
|
|
else if (this->GeneratePointNormals)
|
|
{
|
|
Orient::RunPointNormals(cellset, coords, pointNormals);
|
|
}
|
|
|
|
if (this->FlipNormals)
|
|
{
|
|
if (this->GenerateCellNormals)
|
|
{
|
|
Orient::RunFlipNormals(faceNormals);
|
|
}
|
|
if (this->GeneratePointNormals)
|
|
{
|
|
Orient::RunFlipNormals(pointNormals);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this->Consistency && this->GenerateCellNormals)
|
|
{
|
|
auto newCells = vtkm::worklet::TriangleWinding::Run(cellset, coords, faceNormals);
|
|
result.SetCellSet(newCells); // Overwrite the cellset in the result
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
} // vtkm::filter
|
|
#endif
|