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 vtk_m_cont_DataSet_h 11 #define vtk_m_cont_DataSet_h 12 13 #include <vtkm/cont/vtkm_cont_export.h> 14 15 #include <vtkm/cont/ArrayHandle.h> 16 #include <vtkm/cont/CoordinateSystem.h> 17 #include <vtkm/cont/DeviceAdapterAlgorithm.h> 18 #include <vtkm/cont/DynamicCellSet.h> 19 #include <vtkm/cont/ErrorBadValue.h> 20 #include <vtkm/cont/Field.h> 21 #include <vtkm/cont/UnknownArrayHandle.h> 22 23 namespace vtkm 24 { 25 namespace cont 26 { 27 28 class VTKM_CONT_EXPORT DataSet 29 { 30 public: 31 VTKM_CONT void Clear(); 32 33 /// Get the number of cells contained in this DataSet 34 VTKM_CONT vtkm::Id GetNumberOfCells() const; 35 36 /// Get the number of points contained in this DataSet 37 /// 38 /// Note: All coordinate systems for a DataSet are expected 39 /// to have the same number of points. 40 VTKM_CONT vtkm::Id GetNumberOfPoints() const; 41 42 VTKM_CONT void AddField(const Field& field); 43 44 VTKM_CONT 45 const vtkm::cont::Field& GetField(vtkm::Id index) const; 46 47 VTKM_CONT 48 vtkm::cont::Field& GetField(vtkm::Id index); 49 50 VTKM_CONT 51 bool HasField(const std::string& name, 52 vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY) const 53 { 54 bool found = false; 55 this->FindFieldIndex(name, assoc, found); 56 return found; 57 } 58 59 VTKM_CONT HasCellField(const std::string & name)60 bool HasCellField(const std::string& name) const 61 { 62 bool found = false; 63 this->FindFieldIndex(name, vtkm::cont::Field::Association::CELL_SET, found); 64 return found; 65 } 66 67 VTKM_CONT HasPointField(const std::string & name)68 bool HasPointField(const std::string& name) const 69 { 70 bool found = false; 71 this->FindFieldIndex(name, vtkm::cont::Field::Association::POINTS, found); 72 return found; 73 } 74 75 76 /// Returns the field that matches the provided name and association 77 /// Will return -1 if no match is found 78 VTKM_CONT 79 vtkm::Id GetFieldIndex( 80 const std::string& name, 81 vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY) const; 82 83 /// Returns the field that matches the provided name and association 84 /// Will throw an exception if no match is found 85 //@{ 86 VTKM_CONT 87 const vtkm::cont::Field& GetField( 88 const std::string& name, 89 vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY) const 90 { 91 return this->GetField(this->GetFieldIndex(name, assoc)); 92 } 93 94 VTKM_CONT 95 vtkm::cont::Field& GetField( 96 const std::string& name, 97 vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY) 98 { 99 return this->GetField(this->GetFieldIndex(name, assoc)); 100 } 101 //@} 102 103 /// Returns the first cell field that matches the provided name. 104 /// Will throw an exception if no match is found 105 //@{ 106 VTKM_CONT GetCellField(const std::string & name)107 const vtkm::cont::Field& GetCellField(const std::string& name) const 108 { 109 return this->GetField(name, vtkm::cont::Field::Association::CELL_SET); 110 } 111 112 VTKM_CONT GetCellField(const std::string & name)113 vtkm::cont::Field& GetCellField(const std::string& name) 114 { 115 return this->GetField(name, vtkm::cont::Field::Association::CELL_SET); 116 } 117 //@} 118 119 /// Returns the first point field that matches the provided name. 120 /// Will throw an exception if no match is found 121 //@{ 122 VTKM_CONT GetPointField(const std::string & name)123 const vtkm::cont::Field& GetPointField(const std::string& name) const 124 { 125 return this->GetField(name, vtkm::cont::Field::Association::POINTS); 126 } 127 128 VTKM_CONT GetPointField(const std::string & name)129 vtkm::cont::Field& GetPointField(const std::string& name) 130 { 131 return this->GetField(name, vtkm::cont::Field::Association::POINTS); 132 } 133 //@} 134 135 VTKM_CONT AddPointField(const std::string & fieldName,const vtkm::cont::UnknownArrayHandle & field)136 void AddPointField(const std::string& fieldName, const vtkm::cont::UnknownArrayHandle& field) 137 { 138 this->AddField(make_FieldPoint(fieldName, field)); 139 } 140 141 template <typename T, typename Storage> AddPointField(const std::string & fieldName,const vtkm::cont::ArrayHandle<T,Storage> & field)142 VTKM_CONT void AddPointField(const std::string& fieldName, 143 const vtkm::cont::ArrayHandle<T, Storage>& field) 144 { 145 this->AddField(make_FieldPoint(fieldName, field)); 146 } 147 148 template <typename T> AddPointField(const std::string & fieldName,const std::vector<T> & field)149 VTKM_CONT void AddPointField(const std::string& fieldName, const std::vector<T>& field) 150 { 151 this->AddField( 152 make_Field(fieldName, vtkm::cont::Field::Association::POINTS, field, vtkm::CopyFlag::On)); 153 } 154 155 template <typename T> AddPointField(const std::string & fieldName,const T * field,const vtkm::Id & n)156 VTKM_CONT void AddPointField(const std::string& fieldName, const T* field, const vtkm::Id& n) 157 { 158 this->AddField( 159 make_Field(fieldName, vtkm::cont::Field::Association::POINTS, field, n, vtkm::CopyFlag::On)); 160 } 161 162 //Cell centered field 163 VTKM_CONT AddCellField(const std::string & fieldName,const vtkm::cont::UnknownArrayHandle & field)164 void AddCellField(const std::string& fieldName, const vtkm::cont::UnknownArrayHandle& field) 165 { 166 this->AddField(make_FieldCell(fieldName, field)); 167 } 168 169 template <typename T, typename Storage> AddCellField(const std::string & fieldName,const vtkm::cont::ArrayHandle<T,Storage> & field)170 VTKM_CONT void AddCellField(const std::string& fieldName, 171 const vtkm::cont::ArrayHandle<T, Storage>& field) 172 { 173 this->AddField(make_FieldCell(fieldName, field)); 174 } 175 176 template <typename T> AddCellField(const std::string & fieldName,const std::vector<T> & field)177 VTKM_CONT void AddCellField(const std::string& fieldName, const std::vector<T>& field) 178 { 179 this->AddField( 180 make_Field(fieldName, vtkm::cont::Field::Association::CELL_SET, field, vtkm::CopyFlag::On)); 181 } 182 183 template <typename T> AddCellField(const std::string & fieldName,const T * field,const vtkm::Id & n)184 VTKM_CONT void AddCellField(const std::string& fieldName, const T* field, const vtkm::Id& n) 185 { 186 this->AddField(make_Field( 187 fieldName, vtkm::cont::Field::Association::CELL_SET, field, n, vtkm::CopyFlag::On)); 188 } 189 190 191 VTKM_CONT AddCoordinateSystem(const vtkm::cont::CoordinateSystem & cs)192 void AddCoordinateSystem(const vtkm::cont::CoordinateSystem& cs) 193 { 194 this->CoordSystems.push_back(cs); 195 } 196 197 VTKM_CONT HasCoordinateSystem(const std::string & name)198 bool HasCoordinateSystem(const std::string& name) const 199 { 200 return this->GetCoordinateSystemIndex(name) >= 0; 201 } 202 203 VTKM_CONT 204 const vtkm::cont::CoordinateSystem& GetCoordinateSystem(vtkm::Id index = 0) const; 205 206 VTKM_CONT 207 vtkm::cont::CoordinateSystem& GetCoordinateSystem(vtkm::Id index = 0); 208 209 /// Returns the index for the first CoordinateSystem whose 210 /// name matches the provided string. 211 /// Will return -1 if no match is found 212 VTKM_CONT 213 vtkm::Id GetCoordinateSystemIndex(const std::string& name) const; 214 215 /// Returns the first CoordinateSystem that matches the provided name. 216 /// Will throw an exception if no match is found 217 //@{ 218 VTKM_CONT 219 const vtkm::cont::CoordinateSystem& GetCoordinateSystem(const std::string& name) const; 220 221 VTKM_CONT 222 vtkm::cont::CoordinateSystem& GetCoordinateSystem(const std::string& name); 223 //@} 224 225 VTKM_CONT SetCellSet(const vtkm::cont::DynamicCellSet & cellSet)226 void SetCellSet(const vtkm::cont::DynamicCellSet& cellSet) { this->CellSet = cellSet; } 227 228 template <typename CellSetType> SetCellSet(const CellSetType & cellSet)229 VTKM_CONT void SetCellSet(const CellSetType& cellSet) 230 { 231 VTKM_IS_CELL_SET(CellSetType); 232 this->CellSet = vtkm::cont::DynamicCellSet(cellSet); 233 } 234 235 VTKM_CONT GetCellSet()236 const vtkm::cont::DynamicCellSet& GetCellSet() const { return this->CellSet; } 237 238 VTKM_CONT GetCellSet()239 vtkm::cont::DynamicCellSet& GetCellSet() { return this->CellSet; } 240 241 VTKM_CONT GetNumberOfFields()242 vtkm::IdComponent GetNumberOfFields() const 243 { 244 return static_cast<vtkm::IdComponent>(this->Fields.size()); 245 } 246 247 VTKM_CONT GetNumberOfCoordinateSystems()248 vtkm::IdComponent GetNumberOfCoordinateSystems() const 249 { 250 return static_cast<vtkm::IdComponent>(this->CoordSystems.size()); 251 } 252 253 /// Copies the structure i.e. coordinates systems and cellset from the source 254 /// dataset. The fields are left unchanged. 255 VTKM_CONT 256 void CopyStructure(const vtkm::cont::DataSet& source); 257 258 VTKM_CONT 259 void PrintSummary(std::ostream& out) const; 260 261 private: 262 struct FieldCompare 263 { 264 using Key = std::pair<std::string, vtkm::cont::Field::Association>; 265 266 template <typename T> operatorFieldCompare267 bool operator()(const T& a, const T& b) const 268 { 269 if (a.first == b.first) 270 return a.second < b.second && a.second != vtkm::cont::Field::Association::ANY && 271 b.second != vtkm::cont::Field::Association::ANY; 272 273 return a.first < b.first; 274 } 275 }; 276 277 std::vector<vtkm::cont::CoordinateSystem> CoordSystems; 278 std::map<FieldCompare::Key, vtkm::cont::Field, FieldCompare> Fields; 279 vtkm::cont::DynamicCellSet CellSet; 280 281 VTKM_CONT 282 vtkm::Id FindFieldIndex(const std::string& name, 283 vtkm::cont::Field::Association association, 284 bool& found) const; 285 }; 286 287 } // namespace cont 288 } // namespace vtkm 289 290 //============================================================================= 291 // Specializations of serialization related classes 292 /// @cond SERIALIZATION 293 namespace vtkm 294 { 295 namespace cont 296 { 297 298 template <typename FieldTypeList = VTKM_DEFAULT_TYPE_LIST, 299 typename CellSetTypesList = VTKM_DEFAULT_CELL_SET_LIST> 300 struct SerializableDataSet 301 { 302 SerializableDataSet() = default; 303 SerializableDataSetSerializableDataSet304 explicit SerializableDataSet(const vtkm::cont::DataSet& dataset) 305 : DataSet(dataset) 306 { 307 } 308 309 vtkm::cont::DataSet DataSet; 310 }; 311 } 312 } // vtkm::cont 313 314 namespace mangled_diy_namespace 315 { 316 317 template <typename FieldTypeList, typename CellSetTypesList> 318 struct Serialization<vtkm::cont::SerializableDataSet<FieldTypeList, CellSetTypesList>> 319 { 320 private: 321 using Type = vtkm::cont::SerializableDataSet<FieldTypeList, CellSetTypesList>; 322 323 public: 324 static VTKM_CONT void save(BinaryBuffer& bb, const Type& serializable) 325 { 326 const auto& dataset = serializable.DataSet; 327 328 vtkm::IdComponent numberOfCoordinateSystems = dataset.GetNumberOfCoordinateSystems(); 329 vtkmdiy::save(bb, numberOfCoordinateSystems); 330 for (vtkm::IdComponent i = 0; i < numberOfCoordinateSystems; ++i) 331 { 332 vtkmdiy::save(bb, dataset.GetCoordinateSystem(i)); 333 } 334 335 vtkmdiy::save(bb, dataset.GetCellSet().ResetCellSetList(CellSetTypesList{})); 336 337 vtkm::IdComponent numberOfFields = dataset.GetNumberOfFields(); 338 vtkmdiy::save(bb, numberOfFields); 339 for (vtkm::IdComponent i = 0; i < numberOfFields; ++i) 340 { 341 vtkmdiy::save(bb, dataset.GetField(i)); 342 } 343 } 344 345 static VTKM_CONT void load(BinaryBuffer& bb, Type& serializable) 346 { 347 auto& dataset = serializable.DataSet; 348 dataset = {}; // clear 349 350 vtkm::IdComponent numberOfCoordinateSystems = 0; 351 vtkmdiy::load(bb, numberOfCoordinateSystems); 352 for (vtkm::IdComponent i = 0; i < numberOfCoordinateSystems; ++i) 353 { 354 vtkm::cont::CoordinateSystem coords; 355 vtkmdiy::load(bb, coords); 356 dataset.AddCoordinateSystem(coords); 357 } 358 359 vtkm::cont::DynamicCellSetBase<CellSetTypesList> cells; 360 vtkmdiy::load(bb, cells); 361 dataset.SetCellSet(vtkm::cont::DynamicCellSet(cells)); 362 363 vtkm::IdComponent numberOfFields = 0; 364 vtkmdiy::load(bb, numberOfFields); 365 for (vtkm::IdComponent i = 0; i < numberOfFields; ++i) 366 { 367 vtkm::cont::Field field; 368 vtkmdiy::load(bb, field); 369 dataset.AddField(field); 370 } 371 } 372 }; 373 374 } // diy 375 /// @endcond SERIALIZATION 376 377 #endif //vtk_m_cont_DataSet_h 378