VTK-m  2.0
UnknownCellSet.h
Go to the documentation of this file.
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_UnknownCellSet_h
11 #define vtk_m_cont_UnknownCellSet_h
12 
13 #include <vtkm/cont/CastAndCall.h>
14 #include <vtkm/cont/CellSet.h>
15 #include <vtkm/cont/DefaultTypes.h>
16 
17 #include <vtkm/cont/vtkm_cont_export.h>
18 
19 #include <memory>
20 
21 namespace vtkm
22 {
23 namespace cont
24 {
25 
26 // Forward declaration.
27 template <typename CellSetList>
28 class UncertainCellSet;
29 
48 class VTKM_CONT_EXPORT UnknownCellSet
49 {
50  std::shared_ptr<vtkm::cont::CellSet> Container;
51 
53  std::true_type vtkmNotUsed(isUnknownCellSet))
54  {
55  *this = cellSet;
56  }
57 
58  template <typename CellSetType>
59  void InitializeKnownOrUnknownCellSet(const CellSetType& cellSet,
60  std::false_type vtkmNotUsed(isUnknownCellSet))
61  {
62  VTKM_IS_CELL_SET(CellSetType);
63  this->Container = std::shared_ptr<vtkm::cont::CellSet>(new CellSetType(cellSet));
64  }
65 
66 public:
67  VTKM_CONT UnknownCellSet() = default;
68 
69  template <typename CellSetType>
70  VTKM_CONT UnknownCellSet(const CellSetType& cellSet)
71  {
72  this->InitializeKnownOrUnknownCellSet(
73  cellSet, typename std::is_base_of<UnknownCellSet, CellSetType>::type{});
74  }
75 
81  VTKM_CONT bool IsValid() const { return static_cast<bool>(this->Container); }
82 
85  VTKM_CONT vtkm::cont::CellSet* GetCellSetBase() { return this->Container.get(); }
86  VTKM_CONT const vtkm::cont::CellSet* GetCellSetBase() const { return this->Container.get(); }
87 
95  VTKM_CONT UnknownCellSet NewInstance() const;
96 
101  VTKM_CONT std::string GetCellSetName() const;
102 
105  template <typename CellSetType>
106  VTKM_CONT bool IsType() const
107  {
108  return (dynamic_cast<const CellSetType*>(this->Container.get()) != nullptr);
109  }
110 
112  {
113  return this->Container ? this->Container->GetNumberOfCells() : 0;
114  }
116  {
117  return this->Container ? this->Container->GetNumberOfFaces() : 0;
118  }
120  {
121  return this->Container ? this->Container->GetNumberOfEdges() : 0;
122  }
124  {
125  return this->Container ? this->Container->GetNumberOfPoints() : 0;
126  }
127 
129  {
130  return this->GetCellSetBase()->GetCellShape(id);
131  }
133  {
134  return this->GetCellSetBase()->GetNumberOfPointsInCell(id);
135  }
137  {
138  return this->GetCellSetBase()->GetCellPointIds(id, ptids);
139  }
140 
141  VTKM_CONT void DeepCopyFrom(const CellSet* src) { this->GetCellSetBase()->DeepCopy(src); }
142 
143  VTKM_CONT void PrintSummary(std::ostream& os) const;
144 
146  {
147  if (this->Container)
148  {
149  this->Container->ReleaseResourcesExecution();
150  }
151  }
152 
160  template <typename CellSetType>
161  VTKM_CONT bool CanConvert() const
162  {
163  // TODO: Currently, these are the same. But in the future we expect to support
164  // special CellSet types that can convert back and forth such as multiplexed
165  // cell sets or a cell set that can hold structured grids of any dimension.
166  return this->IsType<CellSetType>();
167  }
168 
177  template <typename CellSetType>
178  VTKM_CONT void AsCellSet(CellSetType& cellSet) const
179  {
180  VTKM_IS_CELL_SET(CellSetType);
181  CellSetType* cellSetPointer = dynamic_cast<CellSetType*>(this->Container.get());
182  if (cellSetPointer == nullptr)
183  {
184  VTKM_LOG_CAST_FAIL(*this, CellSetType);
185  throwFailedDynamicCast(this->GetCellSetName(), vtkm::cont::TypeToString(cellSet));
186  }
187  VTKM_LOG_CAST_SUCC(*this, *cellSetPointer);
188  cellSet = *cellSetPointer;
189  }
190 
191  template <typename CellSetType>
192  VTKM_CONT CellSetType AsCellSet() const
193  {
194  CellSetType cellSet;
195  this->AsCellSet(cellSet);
196  return cellSet;
197  }
199 
207  // Defined in UncertainCellSet.h
208  template <typename CellSetList>
209  VTKM_CONT vtkm::cont::UncertainCellSet<CellSetList> ResetCellSetList(CellSetList) const;
210  template <typename CellSetList>
211  VTKM_CONT vtkm::cont::UncertainCellSet<CellSetList> ResetCellSetList() const;
212 
222  template <typename CellSetList, typename Functor, typename... Args>
223  VTKM_CONT void CastAndCallForTypes(Functor&& functor, Args&&... args) const;
224 };
225 
226 //=============================================================================
227 // Free function casting helpers
228 // (Not sure if these should be deprecated.)
229 
232 template <typename CellSetType>
233 VTKM_CONT inline bool IsType(const vtkm::cont::UnknownCellSet& unknownCellSet)
234 {
235  return unknownCellSet.IsType<CellSetType>();
236 }
237 
242 template <typename CellSetType>
243 VTKM_CONT inline CellSetType Cast(const vtkm::cont::UnknownCellSet& unknownCellSet)
244 {
245  return unknownCellSet.AsCellSet<CellSetType>();
246 }
247 
248 namespace internal
249 {
250 
251 VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownCellSet&,
252  const std::type_info&);
253 
254 template <>
255 struct DynamicTransformTraits<vtkm::cont::UnknownCellSet>
256 {
257  using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
258 };
259 
260 } // namespace internal
261 
262 template <typename CellSetList, typename Functor, typename... Args>
263 VTKM_CONT void UnknownCellSet::CastAndCallForTypes(Functor&& functor, Args&&... args) const
264 {
265  VTKM_IS_LIST(CellSetList);
266  bool called = false;
268  [&](auto cellSet) {
269  if (!called && this->CanConvert<decltype(cellSet)>())
270  {
271  called = true;
272  this->AsCellSet(cellSet);
273  VTKM_LOG_CAST_SUCC(*this, cellSet);
274 
275  // If you get a compile error here, it means that you have called CastAndCall for a
276  // vtkm::cont::UnknownCellSet and the arguments of the functor do not match those
277  // being passed. This is often because it is calling the functor with a CellSet
278  // type that was not expected. Either add overloads to the functor to accept all
279  // possible cell set types or constrain the types tried for the CastAndCall.
280  functor(cellSet, args...);
281  }
282  },
283  CellSetList{});
284 
285  if (!called)
286  {
287  VTKM_LOG_CAST_FAIL(*this, CellSetList);
288  internal::ThrowCastAndCallException(*this, typeid(CellSetList));
289  }
290 }
291 
294 template <typename Functor, typename... Args>
295 void CastAndCall(const vtkm::cont::UnknownCellSet& cellSet, Functor&& f, Args&&... args)
296 {
297  cellSet.CastAndCallForTypes<VTKM_DEFAULT_CELL_SET_LIST>(std::forward<Functor>(f),
298  std::forward<Args>(args)...);
299 }
300 
301 namespace internal
302 {
303 
307 template <typename T>
308 using UnknownCellSetCheck = typename std::is_base_of<vtkm::cont::UnknownCellSet, T>::type;
309 
310 #define VTKM_IS_UNKNOWN_CELL_SET(T) \
311  VTKM_STATIC_ASSERT(::vtkm::cont::internal::UnknownCellSetCheck<T>::value)
312 
313 #define VTKM_IS_KNOWN_OR_UNKNOWN_CELL_SET(T) \
314  VTKM_STATIC_ASSERT(::vtkm::cont::internal::CellSetCheck<T>::type::value || \
315  ::vtkm::cont::internal::UnknownCellSetCheck<T>::value)
316 
317 } // namespace internal
318 
319 } // namespace vtkm::cont
320 } // namespace vtkm
321 
322 //=============================================================================
323 // Specializations of serialization related classes
325 
326 namespace vtkm
327 {
328 namespace cont
329 {
330 
331 template <>
332 struct VTKM_CONT_EXPORT SerializableTypeString<vtkm::cont::UnknownCellSet>
333 {
334  static VTKM_CONT std::string Get();
335 };
336 }
337 } // namespace vtkm::cont
338 
339 namespace mangled_diy_namespace
340 {
341 
342 template <>
343 struct VTKM_CONT_EXPORT Serialization<vtkm::cont::UnknownCellSet>
344 {
345 public:
346  static VTKM_CONT void save(BinaryBuffer& bb, const vtkm::cont::UnknownCellSet& obj);
347  static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::UnknownCellSet& obj);
348 };
349 
350 } // namespace mangled_diy_namespace
351 
353 
354 // Include the implementation of UncertainCellSet. This should be included because there
355 // are methods in UnknownCellSet that produce objects of this type. It has to be included
356 // at the end to resolve the circular dependency.
358 
359 #endif //vtk_m_cont_UnknownCellSet_h
vtkm::cont::UnknownCellSet::GetNumberOfEdges
VTKM_CONT vtkm::Id GetNumberOfEdges() const
Definition: UnknownCellSet.h:119
vtkm::cont::UnknownCellSet::DeepCopyFrom
VTKM_CONT void DeepCopyFrom(const CellSet *src)
Definition: UnknownCellSet.h:141
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::UnknownCellSet::GetCellShape
VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id id) const
Definition: UnknownCellSet.h:128
vtkm::cont::UnknownCellSet::CanConvert
VTKM_CONT bool CanConvert() const
Returns true if this cell set can be retrieved as the given type.
Definition: UnknownCellSet.h:161
VTKM_LOG_CAST_FAIL
#define VTKM_LOG_CAST_FAIL(inObj, outType)
Convenience macro for logging a failed cast of dynamic object.
Definition: Logging.h:269
vtkm::Get
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT auto Get(const vtkm::Tuple< Ts... > &tuple) -> decltype(tuple.template Get< Index >())
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:83
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::cont::UnknownCellSet::GetCellSetBase
VTKM_CONT vtkm::cont::CellSet * GetCellSetBase()
Returns a pointer to the CellSet base class.
Definition: UnknownCellSet.h:85
vtkm::cont::UncertainCellSet
A CellSet of an uncertain type.
Definition: UncertainCellSet.h:38
vtkm::ListForEach
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT void ListForEach(Functor &&f, vtkm::List< Ts... >, Args &&... args)
Definition: List.h:720
vtkm::cont::UnknownCellSet
A CellSet of an unknown type.
Definition: UnknownCellSet.h:48
UncertainCellSet.h
vtkm::cont::CastAndCall
void CastAndCall(const DynamicObject &dynamicObject, Functor &&f, Args &&... args)
A Generic interface to CastAndCall.
Definition: CastAndCall.h:47
mangled_diy_namespace
Definition: Particle.h:331
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::exec::arg::load
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC T load(const U &u, vtkm::Id v)
Definition: FetchTagArrayDirectIn.h:36
vtkm::cont::throwFailedDynamicCast
VTKM_SILENCE_WEAK_VTABLE_WARNING_END VTKM_CONT_EXPORT void throwFailedDynamicCast(const std::string &baseType, const std::string &derivedType)
Throws an ErrorBadType exception with the following message: Cast failed: baseType --> derivedType".
vtkm::cont::Cast
VTKM_CONT ArrayHandleType Cast(const vtkm::cont::UnknownArrayHandle &array)
Returns variant cast to the given ArrayHandle type.
Definition: UnknownArrayHandle.h:1099
vtkm::cont::UnknownCellSet::AsCellSet
VTKM_CONT void AsCellSet(CellSetType &cellSet) const
Get the cell set as a known type.
Definition: UnknownCellSet.h:178
CastAndCall.h
VTKM_LOG_CAST_SUCC
#define VTKM_LOG_CAST_SUCC(inObj, outObj)
Convenience macro for logging the successful cast of dynamic object.
Definition: Logging.h:268
vtkm::cont::UnknownCellSet::InitializeKnownOrUnknownCellSet
void InitializeKnownOrUnknownCellSet(const UnknownCellSet &cellSet, std::true_type vtkmNotUsed(isUnknownCellSet))
Definition: UnknownCellSet.h:52
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
CellSet.h
vtkm::cont::CellSet
Definition: CellSet.h:24
vtkm::cont::UnknownCellSet::Container
std::shared_ptr< vtkm::cont::CellSet > Container
Definition: UnknownCellSet.h:50
vtkm::UInt8
uint8_t UInt8
Definition: Types.h:157
vtkm::cont::UnknownCellSet::GetNumberOfFaces
VTKM_CONT vtkm::Id GetNumberOfFaces() const
Definition: UnknownCellSet.h:115
vtkmNotUsed
#define vtkmNotUsed(parameter_name)
Simple macro to identify a parameter as unused.
Definition: ExportMacros.h:128
vtkm::cont::UnknownCellSet::CastAndCallForTypes
VTKM_CONT void CastAndCallForTypes(Functor &&functor, Args &&... args) const
Call a functor using the underlying cell set type.
Definition: UnknownCellSet.h:263
vtkm::cont::UnknownCellSet::GetCellSetBase
const VTKM_CONT vtkm::cont::CellSet * GetCellSetBase() const
Definition: UnknownCellSet.h:86
VTKM_IS_LIST
#define VTKM_IS_LIST(type)
Checks that the argument is a proper list.
Definition: List.h:64
vtkm::cont::UnknownCellSet::GetNumberOfPointsInCell
VTKM_CONT vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id id) const
Definition: UnknownCellSet.h:132
vtkm::cont::IsType
VTKM_CONT bool IsType(const vtkm::cont::UnknownArrayHandle &array)
Returns true if variant matches the type of ArrayHandleType.
Definition: UnknownArrayHandle.h:1089
vtkm::cont::UnknownCellSet::UnknownCellSet
VTKM_CONT UnknownCellSet(const CellSetType &cellSet)
Definition: UnknownCellSet.h:70
vtkm::cont::UnknownCellSet::IsValid
VTKM_CONT bool IsValid() const
Returns whether a cell set is stored in this UnknownCellSet.
Definition: UnknownCellSet.h:81
vtkm::cont::UnknownCellSet::GetNumberOfPoints
VTKM_CONT vtkm::Id GetNumberOfPoints() const
Definition: UnknownCellSet.h:123
vtkm::cont::UnknownCellSet::InitializeKnownOrUnknownCellSet
void InitializeKnownOrUnknownCellSet(const CellSetType &cellSet, std::false_type vtkmNotUsed(isUnknownCellSet))
Definition: UnknownCellSet.h:59
vtkm::cont::UnknownCellSet::IsType
VTKM_CONT bool IsType() const
Returns true if this cell set matches the CellSetType template argument.
Definition: UnknownCellSet.h:106
vtkm::cont::TypeToString
VTKM_CONT_EXPORT VTKM_CONT std::string TypeToString(const std::type_info &t)
Use RTTI information to retrieve the name of the type T.
vtkm::cont::UnknownCellSet::AsCellSet
VTKM_CONT CellSetType AsCellSet() const
Get the cell set as a known type.
Definition: UnknownCellSet.h:192
vtkm::cont::UnknownCellSet::GetNumberOfCells
VTKM_CONT vtkm::Id GetNumberOfCells() const
Definition: UnknownCellSet.h:111
VTKM_IS_CELL_SET
#define VTKM_IS_CELL_SET(T)
Definition: CellSet.h:71
vtkm::cont::UnknownCellSet::GetCellPointIds
VTKM_CONT void GetCellPointIds(vtkm::Id id, vtkm::Id *ptids) const
Definition: UnknownCellSet.h:136
vtkm::cont::UnknownCellSet::ReleaseResourcesExecution
VTKM_CONT void ReleaseResourcesExecution()
Definition: UnknownCellSet.h:145