1 //============================================================================
2 //  Copyright (c) Kitware, Inc.
3 //  All rights reserved.
4 //  See LICENSE.txt for details.
5 //
6 //  This software is distributed WITHOUT ANY WARRANTY; without even
7 //  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 //  PURPOSE.  See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtkm_m_worklet_ExtractPoints_h
11 #define vtkm_m_worklet_ExtractPoints_h
12 
13 #include <vtkm/worklet/DispatcherMapTopology.h>
14 #include <vtkm/worklet/WorkletMapTopology.h>
15 
16 #include <vtkm/cont/Algorithm.h>
17 #include <vtkm/cont/ArrayCopy.h>
18 #include <vtkm/cont/ArrayHandle.h>
19 #include <vtkm/cont/CoordinateSystem.h>
20 #include <vtkm/cont/DataSet.h>
21 
22 #include <vtkm/ImplicitFunction.h>
23 
24 namespace vtkm
25 {
26 namespace worklet
27 {
28 
29 class ExtractPoints
30 {
31 public:
32   ////////////////////////////////////////////////////////////////////////////////////
33   // Worklet to identify points within volume of interest
34   class ExtractPointsByVOI : public vtkm::worklet::WorkletVisitPointsWithCells
35   {
36   public:
37     using ControlSignature = void(CellSetIn cellset,
38                                   FieldInPoint coordinates,
39                                   ExecObject function,
40                                   FieldOutPoint passFlags);
41     using ExecutionSignature = _4(_2, _3);
42 
43     VTKM_CONT
ExtractPointsByVOI(bool extractInside)44     ExtractPointsByVOI(bool extractInside)
45       : passValue(extractInside)
46       , failValue(!extractInside)
47     {
48     }
49 
50     template <typename ImplicitFunction>
operator()51     VTKM_EXEC bool operator()(const vtkm::Vec3f_64& coordinate,
52                               const ImplicitFunction& function) const
53     {
54       bool pass = passValue;
55       vtkm::Float64 value = function.Value(coordinate);
56       if (value > 0)
57       {
58         pass = failValue;
59       }
60       return pass;
61     }
62 
63   private:
64     bool passValue;
65     bool failValue;
66   };
67 
68   ////////////////////////////////////////////////////////////////////////////////////
69   // Extract points by id creates new cellset of vertex cells
70   template <typename CellSetType>
Run(const CellSetType & cellSet,const vtkm::cont::ArrayHandle<vtkm::Id> & pointIds)71   vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet,
72                                       const vtkm::cont::ArrayHandle<vtkm::Id>& pointIds)
73   {
74     vtkm::cont::ArrayCopy(pointIds, this->ValidPointIds);
75 
76     // Make CellSetSingleType with VERTEX at each point id
77     vtkm::cont::CellSetSingleType<> outCellSet;
78     outCellSet.Fill(
79       cellSet.GetNumberOfPoints(), vtkm::CellShapeTagVertex::Id, 1, this->ValidPointIds);
80 
81     return outCellSet;
82   }
83 
84   ////////////////////////////////////////////////////////////////////////////////////
85   // Extract points by implicit function
86   template <typename CellSetType, typename CoordinateType, typename ImplicitFunction>
Run(const CellSetType & cellSet,const CoordinateType & coordinates,const ImplicitFunction & implicitFunction,bool extractInside)87   vtkm::cont::CellSetSingleType<> Run(const CellSetType& cellSet,
88                                       const CoordinateType& coordinates,
89                                       const ImplicitFunction& implicitFunction,
90                                       bool extractInside)
91   {
92     // Worklet output will be a boolean passFlag array
93     vtkm::cont::ArrayHandle<bool> passFlags;
94 
95     ExtractPointsByVOI worklet(extractInside);
96     DispatcherMapTopology<ExtractPointsByVOI> dispatcher(worklet);
97     dispatcher.Invoke(cellSet, coordinates, implicitFunction, passFlags);
98 
99     vtkm::cont::ArrayHandleCounting<vtkm::Id> indices =
100       vtkm::cont::make_ArrayHandleCounting(vtkm::Id(0), vtkm::Id(1), passFlags.GetNumberOfValues());
101     vtkm::cont::Algorithm::CopyIf(indices, passFlags, this->ValidPointIds);
102 
103     // Make CellSetSingleType with VERTEX at each point id
104     vtkm::cont::CellSetSingleType<> outCellSet;
105     outCellSet.Fill(
106       cellSet.GetNumberOfPoints(), vtkm::CellShapeTagVertex::Id, 1, this->ValidPointIds);
107 
108     return outCellSet;
109   }
110 
111 private:
112   vtkm::cont::ArrayHandle<vtkm::Id> ValidPointIds;
113 };
114 }
115 } // namespace vtkm::worklet
116 
117 #endif // vtkm_m_worklet_ExtractPoints_h
118