1 //=============================================================================
2 //
3 //  Copyright (c) Kitware, Inc.
4 //  All rights reserved.
5 //  See LICENSE.txt for details.
6 //
7 //  This software is distributed WITHOUT ANY WARRANTY; without even
8 //  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9 //  PURPOSE.  See the above copyright notice for more information.
10 //
11 //  Copyright 2012 Sandia Corporation.
12 //  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
13 //  the U.S. Government retains certain rights in this software.
14 //
15 //=============================================================================
16 
17 #ifndef vtkToDax_Contour_h
18 #define vtkToDax_Contour_h
19 
20 #include "vtkDispatcher.h"
21 #include "vtkPolyData.h"
22 
23 #include "vtkToDax/CellTypeToType.h"
24 #include "vtkToDax/CompactPointField.h"
25 #include "vtkToDax/DataSetTypeToType.h"
26 #include "vtkToDax/DataSetConverters.h"
27 
28 #include "daxToVtk/CellTypeToType.h"
29 #include "daxToVtk/DataSetConverters.h"
30 
31 #include <dax/cont/DispatcherGenerateInterpolatedCells.h>
32 #include <dax/cont/DispatcherMapCell.h>
33 #include <dax/worklet/MarchingCubes.h>
34 #include <dax/worklet/MarchingTetrahedra.h>
35 
36 namespace
37 {
38 template <typename T> struct MarchingCubesOuputType
39 {
40   typedef dax::CellTagTriangle type;
41 };
42 
43 }
44 
45 namespace vtkToDax
46 {
47 
48 template<int B>
49 struct DoContour
50 {
51   template<class InGridType,
52            class OutGridType,
53            typename ValueType,
54            class Container1,
55            class Adapter>
operatorDoContour56   int operator()(const InGridType &,
57                  vtkDataSet *,
58                  OutGridType &,
59                  vtkPolyData *,
60                  ValueType,
61                  const dax::cont::ArrayHandle<ValueType,Container1,Adapter> &,
62                  bool)
63   {
64     vtkGenericWarningMacro(
65           << "Not calling Dax, GridType-CellType combination not supported");
66     return 0;
67   }
68 };
69 template<>
70 struct DoContour<1>
71 {
72   template<class InGridType,
73            class OutGridType,
74            typename ValueType,
75            class Container1,
76            class Adapter>
77   int operator()(
78       const InGridType &inDaxGrid,
79       vtkDataSet *inVTKGrid,
80       OutGridType &outDaxGeom,
81       vtkPolyData *outVTKGrid,
82       ValueType isoValue,
83       const dax::cont::ArrayHandle<ValueType,Container1,Adapter> &mcHandle,
84       bool computeScalars)
85   {
86     dax::Scalar isoValueT(isoValue);
87 
88     dax::worklet::MarchingCubesCount countWorklet(isoValueT);
89     dax::worklet::MarchingCubesGenerate generateWorklet(isoValueT);
90 
91     return this->DispatchWork(inDaxGrid,
92                               inVTKGrid,
93                               outDaxGeom,
94                               outVTKGrid,
95                               countWorklet,
96                               generateWorklet,
97                               mcHandle,
98                               computeScalars);
99   }
100 
101   template<class GridCellContainer,
102            class GridPointContainer,
103            class OutGridType,
104            typename ValueType,
105            class Container1,
106            class Adapter>
107   int operator()(
108       const dax::cont::UnstructuredGrid<
109         dax::CellTagTetrahedron,GridCellContainer,GridPointContainer,Adapter>
110         &inDaxGrid,
111       vtkDataSet *inVTKGrid,
112       OutGridType &outDaxGeom,
113       vtkPolyData *outVTKGrid,
114       ValueType isoValue,
115       const dax::cont::ArrayHandle<ValueType,Container1,Adapter> &mcHandle,
116       bool computeScalars)
117   {
118     dax::Scalar isoValueT(isoValue);
119 
120     dax::worklet::MarchingTetrahedraCount countWorklet(isoValueT);
121     dax::worklet::MarchingTetrahedraGenerate generateWorklet(isoValueT);
122 
123     return this->DispatchWork(inDaxGrid,
124                               inVTKGrid,
125                               outDaxGeom,
126                               outVTKGrid,
127                               countWorklet,
128                               generateWorklet,
129                               mcHandle,
130                               computeScalars);
131   }
132 
133   template<class InGridType,
134            class OutGridType,
135            typename ValueType,
136            class Container1,
137            class Adapter,
138            class CountWorkletType,
139            class GenerateWorkletType>
140   int DispatchWork(
141       const InGridType &inDaxGrid,
142       vtkDataSet *inVTKGrid,
143       OutGridType &outDaxGeom,
144       vtkPolyData *outVTKGrid,
145       CountWorkletType &countWorklet,
146       GenerateWorkletType &generateWorklet,
147       const dax::cont::ArrayHandle<ValueType,Container1,Adapter> &mcHandle,
148       bool computeScalars)
149   {
150     int result=1;
151 
152     try
153       {
154 
155       typedef dax::cont::DispatcherGenerateInterpolatedCells<
156                   GenerateWorkletType,
157                   dax::cont::ArrayHandle< dax::Id >,
158                   Adapter >                             DispatchIC;
159 
160       typedef typename DispatchIC::CountHandleType CountHandleType;
161 
162       dax::cont::DispatcherMapCell<CountWorkletType,Adapter>
163           dispatchCount( countWorklet );
164 
165       CountHandleType count;
166       dispatchCount.Invoke(inDaxGrid, mcHandle, count);
167 
168 
169       DispatchIC generateSurface(count, generateWorklet);
170       generateSurface.SetRemoveDuplicatePoints(true);
171       generateSurface.Invoke(inDaxGrid,outDaxGeom,mcHandle);
172 
173       // Convert output geometry to VTK.
174       daxToVtk::dataSetConverter(outDaxGeom, outVTKGrid);
175 
176       // Interpolate arrays where possible.
177       if (computeScalars)
178         {
179         vtkToDax::CompactPointField<DispatchIC> compact(generateSurface,
180                                                         outVTKGrid);
181         vtkDispatcher<vtkAbstractArray,int> compactDispatcher;
182         compactDispatcher.Add<vtkFloatArray>(compact);
183         compactDispatcher.Add<vtkDoubleArray>(compact);
184 
185         vtkPointData *pd = inVTKGrid->GetPointData();
186         for (int arrayIndex = 0;
187              arrayIndex < pd->GetNumberOfArrays();
188              arrayIndex++)
189           {
190           vtkDataArray *array = pd->GetArray(arrayIndex);
191           if (array == NULL) { continue; }
192 
193           compactDispatcher.Go(array);
194           }
195 
196         // Pass information about attributes.
197         for (int attributeType = 0;
198              attributeType < vtkDataSetAttributes::NUM_ATTRIBUTES;
199              attributeType++)
200           {
201           vtkDataArray *attribute = pd->GetAttribute(attributeType);
202           if (attribute == NULL) { continue; }
203           outVTKGrid->GetPointData()->SetActiveAttribute(attribute->GetName(),
204                                                          attributeType);
205           }
206         } //computeScalars
207       }
208     catch(dax::cont::ErrorControlOutOfMemory error)
209       {
210       std::cerr << "Ran out of memory trying to use the GPU" << std::endl;
211       std::cerr << error.GetMessage() << std::endl;
212       result = 0;
213       }
214     catch(dax::cont::ErrorExecution error)
215       {
216       std::cerr << "Got ErrorExecution from Dax." << std::endl;
217       std::cerr << error.GetMessage() << std::endl;
218       result = 0;
219       }
220     return result;
221   }
222 };
223 
224   template<typename FieldType_>
225   struct Contour
226   {
227     public:
228     typedef FieldType_ FieldType;
229     //we expect FieldType_ to be an dax::cont::ArrayHandle
230     typedef typename FieldType::ValueType T;
231 
232     Contour(const FieldType& f, T value, bool computeScalars):
233       Result(NULL),
234       Field(f),
235       Value(value),
236       ComputeScalars(computeScalars),
237       Name()
238       {
239       }
240 
241     void setOutputGrid(vtkPolyData* grid)
242       {
243       this->Result=grid;
244       }
245 
246     void setFieldName(const char* name)
247       {
248       this->Name=std::string(name);
249       }
250 
251     template<typename LHS, typename RHS>
252     int operator()(LHS &dataSet, const RHS&) const
253       {
254       typedef CellTypeToType<RHS> VTKCellTypeStruct;
255       typedef DataSetTypeToType<CellTypeToType<RHS>,LHS> DataSetTypeToTypeStruct;
256 
257       //get the mapped output type of this operation(MarchingCubes)
258       //todo make this a typedef on the MarchingCubes
259       typedef typename MarchingCubesOuputType< typename VTKCellTypeStruct::DaxCellType >::type OutCellType;
260 
261       //get the input dataset type
262       typedef typename DataSetTypeToTypeStruct::DaxDataSetType InputDataSetType;
263 
264       //construct the output grid type to use the vtk containers
265       //as we know we are going back to vtk. In a more general framework
266       //we would want a tag to say what the destination container tag types
267       //are. We don't need the points container be
268       typedef daxToVtk::CellTypeToType<OutCellType> VTKCellType;
269       dax::cont::UnstructuredGrid<OutCellType,
270                  vtkToDax::vtkTopologyContainerTag<VTKCellType>,
271                  vtkToDax::vtkPointsContainerTag > resultGrid;
272 
273       InputDataSetType inputDaxData = vtkToDax::dataSetConverter(&dataSet,
274                                                      DataSetTypeToTypeStruct());
275 
276       vtkToDax::DoContour<DataSetTypeToTypeStruct::Valid> mc;
277       int result = mc(inputDaxData,
278                       &dataSet,
279                       resultGrid,
280                       this->Result,
281                       this->Value,
282                       this->Field,
283                       this->ComputeScalars);
284 
285       return result;
286       }
287   private:
288     vtkPolyData* Result;
289     FieldType Field;
290     T Value;
291     bool ComputeScalars;
292     std::string Name;
293 
294   };
295 }
296 
297 #endif //vtkToDax_Contour_h
298