//============================================================================ // 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_worklet_SurfaceNormals_h #define vtk_m_worklet_SurfaceNormals_h #include #include #include #include #include #include namespace vtkm { namespace worklet { namespace detail { struct PassThrough { template VTKM_EXEC vtkm::Vec operator()(const vtkm::Vec& in) const { return in; } }; struct Normal { template VTKM_EXEC vtkm::Vec operator()(const vtkm::Vec& in) const { return vtkm::Normal(in); } }; } // detail class FacetedSurfaceNormals { public: template class Worklet : public vtkm::worklet::WorkletVisitCellsWithPoints { public: using ControlSignature = void(CellSetIn cellset, FieldInPoint points, FieldOutCell normals); using ExecutionSignature = void(CellShape, _2, _3); using InputDomain = _1; template VTKM_EXEC void operator()(CellShapeTag, const PointsVecType& points, vtkm::Vec& normal) const { using CTraits = vtkm::CellTraits; const auto tag = typename CTraits::TopologicalDimensionsTag(); this->Compute(tag, points, normal); } template VTKM_EXEC void Compute(vtkm::CellTopologicalDimensionsTag, const PointsVecType&, vtkm::Vec& normal) const { normal = vtkm::TypeTraits>::ZeroInitialization(); } template VTKM_EXEC void Compute(vtkm::CellTopologicalDimensionsTag<2>, const PointsVecType& points, vtkm::Vec& normal) const { normal = this->Normal(vtkm::Cross(points[2] - points[1], points[0] - points[1])); } template VTKM_EXEC void operator()(vtkm::CellShapeTagGeneric shape, const PointsVecType& points, vtkm::Vec& normal) const { switch (shape.Id) { vtkmGenericCellShapeMacro(this->operator()(CellShapeTag(), points, normal)); default: this->RaiseError("unknown cell type"); break; } } private: NormalFnctr Normal; }; FacetedSurfaceNormals() : Normalize(true) { } /// Set/Get if the results should be normalized void SetNormalize(bool value) { this->Normalize = value; } bool GetNormalize() const { return this->Normalize; } template void Run(const CellSetType& cellset, const vtkm::cont::ArrayHandle, CoordsStorageType>& points, vtkm::cont::ArrayHandle>& normals) { if (this->Normalize) { vtkm::worklet::DispatcherMapTopology>().Invoke(cellset, points, normals); } else { vtkm::worklet::DispatcherMapTopology>().Invoke( cellset, points, normals); } } template void Run(const CellSetType& cellset, const PointsType& points, vtkm::cont::ArrayHandle>& normals) { if (this->Normalize) { vtkm::worklet::DispatcherMapTopology>().Invoke(cellset, points, normals); } else { vtkm::worklet::DispatcherMapTopology>().Invoke( cellset, points, normals); } } private: bool Normalize; }; class SmoothSurfaceNormals { public: class Worklet : public vtkm::worklet::WorkletVisitPointsWithCells { public: using ControlSignature = void(CellSetIn cellset, FieldInCell faceNormals, FieldOutPoint pointNormals); using ExecutionSignature = void(CellCount, _2, _3); using InputDomain = _1; template VTKM_EXEC void operator()(vtkm::IdComponent numCells, const FaceNormalsVecType& faceNormals, vtkm::Vec& pointNormal) const { if (numCells == 0) { pointNormal = vtkm::TypeTraits>::ZeroInitialization(); } else { auto result = faceNormals[0]; for (vtkm::IdComponent i = 1; i < numCells; ++i) { result += faceNormals[i]; } pointNormal = vtkm::Normal(result); } } }; template void Run( const CellSetType& cellset, const vtkm::cont::ArrayHandle, FaceNormalStorageType>& faceNormals, vtkm::cont::ArrayHandle>& pointNormals) { vtkm::worklet::DispatcherMapTopology().Invoke(cellset, faceNormals, pointNormals); } template void Run(const CellSetType& cellset, const vtkm::cont::VariantArrayHandleBase& faceNormals, vtkm::cont::ArrayHandle>& pointNormals) { vtkm::worklet::DispatcherMapTopology().Invoke(cellset, faceNormals, pointNormals); } }; } } // vtkm::worklet #endif // vtk_m_worklet_SurfaceNormals_h