VTK-m  2.2
ParametricCoordinates.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_exec_ParametricCoordinates_h
11 #define vtk_m_exec_ParametricCoordinates_h
12 
13 #include <vtkm/Assert.h>
14 #include <vtkm/CellShape.h>
17 #include <vtkm/exec/FunctorBase.h>
19 #include <vtkm/internal/Assume.h>
20 
21 #include <lcl/lcl.h>
22 
23 namespace vtkm
24 {
25 namespace exec
26 {
27 
28 //-----------------------------------------------------------------------------
29 template <typename ParametricCoordType, typename CellShapeTag>
30 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesCenter(
31  vtkm::IdComponent numPoints,
32  CellShapeTag,
34 {
35  auto lclTag = typename vtkm::internal::CellShapeTagVtkmToVtkc<CellShapeTag>::Type{};
36 
37  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
38  if (numPoints != lclTag.numberOfPoints())
39  {
41  }
42 
43  return vtkm::internal::LclErrorToVtkmError(lcl::parametricCenter(lclTag, pcoords));
44 }
45 
46 template <typename ParametricCoordType>
47 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesCenter(
48  vtkm::IdComponent numPoints,
51 {
52  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
53  if (numPoints != 0)
54  {
56  }
58 }
59 
60 template <typename ParametricCoordType>
61 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesCenter(
62  vtkm::IdComponent numPoints,
65 {
66  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
67  if (numPoints != 1)
68  {
70  }
72 }
73 
74 template <typename ParametricCoordType>
75 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesCenter(
76  vtkm::IdComponent numPoints,
79 {
80  switch (numPoints)
81  {
82  case 1:
83  return ParametricCoordinatesCenter(numPoints, vtkm::CellShapeTagVertex(), pcoords);
84  case 2:
85  return ParametricCoordinatesCenter(numPoints, vtkm::CellShapeTagLine(), pcoords);
86  }
87  pcoords[0] = 0.5;
88  pcoords[1] = 0;
89  pcoords[2] = 0;
91 }
92 
93 template <typename ParametricCoordType>
94 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesCenter(
95  vtkm::IdComponent numPoints,
98 {
99  if (numPoints < 1)
100  {
101  pcoords = { 0 };
103  }
104  switch (numPoints)
105  {
106  case 1:
107  return ParametricCoordinatesCenter(numPoints, vtkm::CellShapeTagVertex(), pcoords);
108  case 2:
109  return ParametricCoordinatesCenter(numPoints, vtkm::CellShapeTagLine(), pcoords);
110  default:
111  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
112  return vtkm::internal::LclErrorToVtkmError(
113  lcl::parametricCenter(lcl::Polygon(numPoints), pcoords));
114  }
115 }
116 
117 //-----------------------------------------------------------------------------
125 template <typename ParametricCoordType>
126 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesCenter(
127  vtkm::IdComponent numPoints,
130 {
131  vtkm::ErrorCode status;
132  switch (shape.Id)
133  {
135  ParametricCoordinatesCenter(numPoints, CellShapeTag(), pcoords));
136  default:
137  pcoords = { 0 };
139  }
140  return status;
141 }
142 
143 //-----------------------------------------------------------------------------
144 template <typename ParametricCoordType, typename CellShapeTag>
145 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
146  vtkm::IdComponent numPoints,
147  vtkm::IdComponent pointIndex,
148  CellShapeTag,
150 {
151  auto lclTag = typename vtkm::internal::CellShapeTagVtkmToVtkc<CellShapeTag>::Type{};
152 
153  if (numPoints != lclTag.numberOfPoints())
154  {
155  pcoords = { 0 };
157  }
158  if ((pointIndex < 0) || (pointIndex >= numPoints))
159  {
160  pcoords = { 0 };
162  }
163 
164  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
165  return vtkm::internal::LclErrorToVtkmError(lcl::parametricPoint(lclTag, pointIndex, pcoords));
166 }
167 
168 template <typename ParametricCoordType>
169 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
174 {
175  pcoords[0] = pcoords[1] = pcoords[2] = 0;
177 }
178 
179 template <typename ParametricCoordType>
180 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
181  vtkm::IdComponent numPoints,
182  vtkm::IdComponent pointIndex,
185 {
186  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
187  if (numPoints != 1)
188  {
190  }
191  if (pointIndex != 0)
192  {
194  }
196 }
197 
198 template <typename ParametricCoordType>
199 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
200  vtkm::IdComponent numPoints,
201  vtkm::IdComponent pointIndex,
204 {
205  if (numPoints < 1)
206  {
207  pcoords = { 0 };
209  }
210  switch (numPoints)
211  {
212  case 1:
213  return ParametricCoordinatesPoint(numPoints, pointIndex, vtkm::CellShapeTagVertex(), pcoords);
214  case 2:
215  return ParametricCoordinatesPoint(numPoints, pointIndex, vtkm::CellShapeTagLine(), pcoords);
216  }
217  pcoords[0] =
218  static_cast<ParametricCoordType>(pointIndex) / static_cast<ParametricCoordType>(numPoints - 1);
219  pcoords[1] = 0;
220  pcoords[2] = 0;
222 }
223 
224 template <typename ParametricCoordType>
225 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
226  vtkm::IdComponent numPoints,
227  vtkm::IdComponent pointIndex,
230 {
231  switch (numPoints)
232  {
233  case 1:
234  return ParametricCoordinatesPoint(numPoints, pointIndex, vtkm::CellShapeTagVertex(), pcoords);
235  case 2:
236  return ParametricCoordinatesPoint(numPoints, pointIndex, vtkm::CellShapeTagLine(), pcoords);
237  default:
238  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
239  return vtkm::internal::LclErrorToVtkmError(
240  lcl::parametricPoint(lcl::Polygon(numPoints), pointIndex, pcoords));
241  }
242 }
243 
244 //-----------------------------------------------------------------------------
254 template <typename ParametricCoordType>
255 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
256  vtkm::IdComponent numPoints,
257  vtkm::IdComponent pointIndex,
260 {
261  vtkm::ErrorCode status;
262  switch (shape.Id)
263  {
265  status = ParametricCoordinatesPoint(numPoints, pointIndex, CellShapeTag(), pcoords));
266  default:
267  pcoords[0] = pcoords[1] = pcoords[2] = 0;
269  }
270  return status;
271 }
272 
273 //-----------------------------------------------------------------------------
274 namespace internal
275 {
276 
277 template <typename LclCellShapeTag, typename WorldCoordVector, typename PCoordType>
278 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinatesImpl(
279  LclCellShapeTag tag,
280  const WorldCoordVector& pointWCoords,
281  const PCoordType& pcoords,
282  typename WorldCoordVector::ComponentType& wcoords)
283 {
284  return vtkm::internal::LclErrorToVtkmError(lcl::parametricToWorld(
285  tag, lcl::makeFieldAccessorNestedSOA(pointWCoords, 3), pcoords, wcoords));
286 }
287 
288 } // namespace internal
289 
290 template <typename WorldCoordVector, typename PCoordType, typename CellShapeTag>
291 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
292  const WorldCoordVector& pointWCoords,
293  const vtkm::Vec<PCoordType, 3>& pcoords,
294  CellShapeTag shape,
295  typename WorldCoordVector::ComponentType& result)
296 {
297  auto numPoints = pointWCoords.GetNumberOfComponents();
298  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
299  vtkm::internal::make_LclCellShapeTag(shape, numPoints), pointWCoords, pcoords, result);
300 }
301 
302 template <typename WorldCoordVector, typename PCoordType>
303 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
304  const WorldCoordVector& pointWCoords,
305  const vtkm::Vec<PCoordType, 3>& pcoords,
307  typename WorldCoordVector::ComponentType& result)
308 {
309  return vtkm::exec::CellInterpolate(pointWCoords, pcoords, empty, result);
310 }
311 
312 template <typename WorldCoordVector, typename PCoordType>
313 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
314  const WorldCoordVector& pointWCoords,
315  const vtkm::Vec<PCoordType, 3>& pcoords,
317  typename WorldCoordVector::ComponentType& result)
318 {
319  return vtkm::exec::CellInterpolate(pointWCoords, pcoords, polyLine, result);
320 }
321 
322 template <typename WorldCoordVector, typename PCoordType>
323 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
324  const WorldCoordVector& pointWCoords,
325  const vtkm::Vec<PCoordType, 3>& pcoords,
327  typename WorldCoordVector::ComponentType& result)
328 {
329  auto numPoints = pointWCoords.GetNumberOfComponents();
330  switch (numPoints)
331  {
332  case 1:
333  return ParametricCoordinatesToWorldCoordinates(
334  pointWCoords, pcoords, vtkm::CellShapeTagVertex{}, result);
335  case 2:
336  return ParametricCoordinatesToWorldCoordinates(
337  pointWCoords, pcoords, vtkm::CellShapeTagLine{}, result);
338  default:
339  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
340  lcl::Polygon(numPoints), pointWCoords, pcoords, result);
341  }
342 }
343 
344 template <typename WorldCoordVector, typename PCoordType>
345 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
346  const vtkm::VecAxisAlignedPointCoordinates<2>& pointWCoords,
347  const vtkm::Vec<PCoordType, 3>& pcoords,
349  typename WorldCoordVector::ComponentType& result)
350 {
351  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
352  lcl::Pixel{}, pointWCoords, pcoords, result);
353 }
354 
355 template <typename WorldCoordVector, typename PCoordType>
356 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
357  const vtkm::VecAxisAlignedPointCoordinates<3>& pointWCoords,
358  const vtkm::Vec<PCoordType, 3>& pcoords,
360  typename WorldCoordVector::ComponentType& result)
361 {
362  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
363  lcl::Voxel{}, pointWCoords, pcoords, result);
364 }
365 
366 //-----------------------------------------------------------------------------
378 template <typename WorldCoordVector, typename PCoordType>
379 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
380  const WorldCoordVector& pointWCoords,
381  const vtkm::Vec<PCoordType, 3>& pcoords,
383  typename WorldCoordVector::ComponentType& result)
384 {
385  vtkm::ErrorCode status;
386  switch (shape.Id)
387  {
388  vtkmGenericCellShapeMacro(status = ParametricCoordinatesToWorldCoordinates(
389  pointWCoords, pcoords, CellShapeTag(), result));
390  default:
391  result = { 0 };
393  }
394  return status;
395 }
396 
397 //-----------------------------------------------------------------------------
398 namespace internal
399 {
400 
401 template <typename LclCellShapeTag, typename WorldCoordVector>
402 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinatesImpl(
403  LclCellShapeTag tag,
404  const WorldCoordVector& pointWCoords,
405  const typename WorldCoordVector::ComponentType& wcoords,
406  typename WorldCoordVector::ComponentType& result)
407 {
408  if (pointWCoords.GetNumberOfComponents() != tag.numberOfPoints())
409  {
410  result = { 0 };
412  }
413 
415  return vtkm::internal::LclErrorToVtkmError(
416  lcl::worldToParametric(tag, lcl::makeFieldAccessorNestedSOA(pointWCoords, 3), wcoords, result));
417 }
418 
419 } // namespace internal
420 
421 template <typename WorldCoordVector, typename CellShapeTag>
422 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
423  const WorldCoordVector& pointWCoords,
424  const typename WorldCoordVector::ComponentType& wcoords,
425  CellShapeTag shape,
426  typename WorldCoordVector::ComponentType& result)
427 {
428  auto numPoints = pointWCoords.GetNumberOfComponents();
429  return internal::WorldCoordinatesToParametricCoordinatesImpl(
430  vtkm::internal::make_LclCellShapeTag(shape, numPoints), pointWCoords, wcoords, result);
431 }
432 
433 template <typename WorldCoordVector>
434 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
435  const WorldCoordVector&,
436  const typename WorldCoordVector::ComponentType&,
438  typename WorldCoordVector::ComponentType& result)
439 {
440  result = { 0 };
442 }
443 
444 template <typename WorldCoordVector>
445 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
446  const WorldCoordVector& pointWCoords,
447  const typename WorldCoordVector::ComponentType&,
449  typename WorldCoordVector::ComponentType& result)
450 {
451  if (pointWCoords.GetNumberOfComponents() != 1)
452  {
453  result = { 0 };
455  }
456  result = typename WorldCoordVector::ComponentType(0, 0, 0);
458 }
459 
460 template <typename WorldCoordVector>
461 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
462  const WorldCoordVector& pointWCoords,
463  const typename WorldCoordVector::ComponentType& wcoords,
465  typename WorldCoordVector::ComponentType& result)
466 {
467  vtkm::IdComponent numPoints = pointWCoords.GetNumberOfComponents();
468  if (numPoints < 1)
469  {
470  result = { 0 };
472  }
473 
474  if (numPoints == 1)
475  {
476  return WorldCoordinatesToParametricCoordinates(
477  pointWCoords, wcoords, vtkm::CellShapeTagVertex(), result);
478  }
479 
480  using Vector3 = typename WorldCoordVector::ComponentType;
481  using T = typename Vector3::ComponentType;
482 
483  //Find the closest vertex to the point.
484  vtkm::IdComponent idx = 0;
485  Vector3 vec = pointWCoords[0] - wcoords;
486  T minDistSq = vtkm::Dot(vec, vec);
487  for (vtkm::IdComponent i = 1; i < numPoints; i++)
488  {
489  vec = pointWCoords[i] - wcoords;
490  T d = vtkm::Dot(vec, vec);
491 
492  if (d < minDistSq)
493  {
494  idx = i;
495  minDistSq = d;
496  }
497  }
498 
499  //Find the right segment, and the parameterization along that segment.
500  //Closest to 0, so segment is (0,1)
501  if (idx == 0)
502  {
503  idx = 1;
504  }
505 
506  vtkm::Vec<Vector3, 2> line(pointWCoords[idx - 1], pointWCoords[idx]);
507  Vector3 lpc;
509  WorldCoordinatesToParametricCoordinates(line, wcoords, vtkm::CellShapeTagLine{}, lpc));
510 
511  //Segment param is [0,1] on that segment.
512  //Map that onto the param for the entire segment.
513  T dParam = static_cast<T>(1) / static_cast<T>(numPoints - 1);
514  T polyLineParam = static_cast<T>(idx - 1) * dParam + lpc[0] * dParam;
515 
516  result = Vector3(polyLineParam, 0, 0);
518 }
519 
520 template <typename WorldCoordVector>
521 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
522  const WorldCoordVector& pointWCoords,
523  const typename WorldCoordVector::ComponentType& wcoords,
525  typename WorldCoordVector::ComponentType& result)
526 {
527  auto numPoints = pointWCoords.GetNumberOfComponents();
528  switch (numPoints)
529  {
530  case 1:
531  return WorldCoordinatesToParametricCoordinates(
532  pointWCoords, wcoords, vtkm::CellShapeTagVertex{}, result);
533  case 2:
534  return WorldCoordinatesToParametricCoordinates(
535  pointWCoords, wcoords, vtkm::CellShapeTagLine{}, result);
536  default:
537  return internal::WorldCoordinatesToParametricCoordinatesImpl(
538  lcl::Polygon(numPoints), pointWCoords, wcoords, result);
539  }
540 }
541 
542 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
543  const vtkm::VecAxisAlignedPointCoordinates<2>& pointWCoords,
544  const vtkm::Vec3f& wcoords,
546  vtkm::Vec3f& result)
547 {
548  return internal::WorldCoordinatesToParametricCoordinatesImpl(
549  lcl::Pixel{}, pointWCoords, wcoords, result);
550 }
551 
552 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
553  const vtkm::VecAxisAlignedPointCoordinates<3>& pointWCoords,
554  const vtkm::Vec3f& wcoords,
556  vtkm::Vec3f& result)
557 {
558  return internal::WorldCoordinatesToParametricCoordinatesImpl(
559  lcl::Voxel{}, pointWCoords, wcoords, result);
560 }
561 
562 //-----------------------------------------------------------------------------
575 template <typename WorldCoordVector>
576 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
577  const WorldCoordVector& pointWCoords,
578  const typename WorldCoordVector::ComponentType& wcoords,
580  typename WorldCoordVector::ComponentType& result)
581 {
582  vtkm::ErrorCode status;
583  switch (shape.Id)
584  {
585  vtkmGenericCellShapeMacro(status = WorldCoordinatesToParametricCoordinates(
586  pointWCoords, wcoords, CellShapeTag(), result));
587  default:
588  result = { 0 };
590  }
591  return status;
592 }
593 
594 }
595 } // namespace vtkm::exec
596 
597 #endif //vtk_m_exec_ParametricCoordinates_h
vtkm::CellShapeTagQuad
Definition: CellShape.h:156
vtkm::ErrorCode
ErrorCode
Identifies whether an operation was successful or what type of error it had.
Definition: ErrorCode.h:28
vtkm::exec::CellInterpolate
vtkm::ErrorCode CellInterpolate(const FieldVecType &pointFieldValues, const vtkm::Vec< ParametricCoordType, 3 > &pcoords, CellShapeTag tag, typename FieldVecType::ComponentType &result)
Definition: CellInterpolate.h:58
vtkm::VecAxisAlignedPointCoordinates
An implicit vector for point coordinates in axis aligned cells.
Definition: VecAxisAlignedPointCoordinates.h:78
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::TypeTraits
The TypeTraits class provides helpful compile-time information about the basic types used in VTKm (an...
Definition: TypeTraits.h:61
vtkm::IdComponent
vtkm::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:194
FastVec.h
vtkm::ErrorCode::Success
@ Success
A successful operation.
Assert.h
CellInterpolate.h
CellShape.h
vtkm::CellShapeTagPolygon
Definition: CellShape.h:154
Assume.h
vtkmGenericCellShapeMacro
#define vtkmGenericCellShapeMacro(call)
A macro used in a switch statement to determine cell shape.
Definition: CellShape.h:250
vtkm::CellShapeTagVertex
Definition: CellShape.h:148
vtkm::CellShapeTagPolyLine
Definition: CellShape.h:151
FunctorBase.h
vtkm::CellShapeTagLine
Definition: CellShape.h:150
vtkm::ErrorCode::InvalidPointId
@ InvalidPointId
A bad point identifier was detected while operating on a cell.
vtkm::CellShapeTagEmpty
Definition: CellShape.h:147
vtkm::CellShapeTagHexahedron
Definition: CellShape.h:159
vtkm::Vec
A short fixed-length array.
Definition: Types.h:357
vtkm::CellShapeTagGeneric::Id
vtkm::UInt8 Id
An identifier that corresponds to one of the CELL_SHAPE_* identifiers.
Definition: CellShape.h:180
vtkm::ErrorCode::OperationOnEmptyCell
@ OperationOnEmptyCell
An operation was attempted on a cell with an empty shape.
VTKM_RETURN_ON_ERROR
#define VTKM_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:202
vtkm::TypeTraits::ZeroInitialization
static T ZeroInitialization()
A static function that returns 0 (or the closest equivalent to it) for the given type.
Definition: TypeTraits.h:77
vtkm::CellShapeTagGeneric
A special cell shape tag that holds a cell shape that is not known at compile time.
Definition: CellShape.h:170
VecAxisAlignedPointCoordinates.h
vtkm::ErrorCode::InvalidNumberOfPoints
@ InvalidNumberOfPoints
The wrong number of points was provided for a given cell type.
vtkm::ErrorCode::InvalidShapeId
@ InvalidShapeId
A unknown shape identifier was encountered.