VTK-m  2.0
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,
49  vtkm::CellShapeTagEmpty,
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,
63  vtkm::CellShapeTagVertex,
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,
77  vtkm::CellShapeTagPolyLine,
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,
96  vtkm::CellShapeTagPolygon,
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 //-----------------------------------------------------------------------------
121 template <typename ParametricCoordType>
122 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesCenter(
123  vtkm::IdComponent numPoints,
126 {
127  vtkm::ErrorCode status;
128  switch (shape.Id)
129  {
131  ParametricCoordinatesCenter(numPoints, CellShapeTag(), pcoords));
132  default:
133  pcoords = { 0 };
135  }
136  return status;
137 }
138 
139 //-----------------------------------------------------------------------------
140 template <typename ParametricCoordType, typename CellShapeTag>
141 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
142  vtkm::IdComponent numPoints,
143  vtkm::IdComponent pointIndex,
144  CellShapeTag,
146 {
147  auto lclTag = typename vtkm::internal::CellShapeTagVtkmToVtkc<CellShapeTag>::Type{};
148 
149  if (numPoints != lclTag.numberOfPoints())
150  {
151  pcoords = { 0 };
153  }
154  if ((pointIndex < 0) || (pointIndex >= numPoints))
155  {
156  pcoords = { 0 };
158  }
159 
160  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
161  return vtkm::internal::LclErrorToVtkmError(lcl::parametricPoint(lclTag, pointIndex, pcoords));
162 }
163 
164 template <typename ParametricCoordType>
165 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
168  vtkm::CellShapeTagEmpty,
170 {
171  pcoords[0] = pcoords[1] = pcoords[2] = 0;
173 }
174 
175 template <typename ParametricCoordType>
176 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
177  vtkm::IdComponent numPoints,
178  vtkm::IdComponent pointIndex,
179  vtkm::CellShapeTagVertex,
181 {
182  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
183  if (numPoints != 1)
184  {
186  }
187  if (pointIndex != 0)
188  {
190  }
192 }
193 
194 template <typename ParametricCoordType>
195 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
196  vtkm::IdComponent numPoints,
197  vtkm::IdComponent pointIndex,
198  vtkm::CellShapeTagPolyLine,
200 {
201  if (numPoints < 1)
202  {
203  pcoords = { 0 };
205  }
206  switch (numPoints)
207  {
208  case 1:
209  return ParametricCoordinatesPoint(numPoints, pointIndex, vtkm::CellShapeTagVertex(), pcoords);
210  case 2:
211  return ParametricCoordinatesPoint(numPoints, pointIndex, vtkm::CellShapeTagLine(), pcoords);
212  }
213  pcoords[0] =
214  static_cast<ParametricCoordType>(pointIndex) / static_cast<ParametricCoordType>(numPoints - 1);
215  pcoords[1] = 0;
216  pcoords[2] = 0;
218 }
219 
220 template <typename ParametricCoordType>
221 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
222  vtkm::IdComponent numPoints,
223  vtkm::IdComponent pointIndex,
224  vtkm::CellShapeTagPolygon,
226 {
227  switch (numPoints)
228  {
229  case 1:
230  return ParametricCoordinatesPoint(numPoints, pointIndex, vtkm::CellShapeTagVertex(), pcoords);
231  case 2:
232  return ParametricCoordinatesPoint(numPoints, pointIndex, vtkm::CellShapeTagLine(), pcoords);
233  default:
234  pcoords = vtkm::TypeTraits<vtkm::Vec<ParametricCoordType, 3>>::ZeroInitialization();
235  return vtkm::internal::LclErrorToVtkmError(
236  lcl::parametricPoint(lcl::Polygon(numPoints), pointIndex, pcoords));
237  }
238 }
239 
240 //-----------------------------------------------------------------------------
244 template <typename ParametricCoordType>
245 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint(
246  vtkm::IdComponent numPoints,
247  vtkm::IdComponent pointIndex,
250 {
251  vtkm::ErrorCode status;
252  switch (shape.Id)
253  {
255  status = ParametricCoordinatesPoint(numPoints, pointIndex, CellShapeTag(), pcoords));
256  default:
257  pcoords[0] = pcoords[1] = pcoords[2] = 0;
259  }
260  return status;
261 }
262 
263 //-----------------------------------------------------------------------------
264 namespace internal
265 {
266 
267 template <typename LclCellShapeTag, typename WorldCoordVector, typename PCoordType>
268 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinatesImpl(
269  LclCellShapeTag tag,
270  const WorldCoordVector& pointWCoords,
271  const PCoordType& pcoords,
272  typename WorldCoordVector::ComponentType& wcoords)
273 {
274  return vtkm::internal::LclErrorToVtkmError(lcl::parametricToWorld(
275  tag, lcl::makeFieldAccessorNestedSOA(pointWCoords, 3), pcoords, wcoords));
276 }
277 
278 } // namespace internal
279 
280 template <typename WorldCoordVector, typename PCoordType, typename CellShapeTag>
281 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
282  const WorldCoordVector& pointWCoords,
283  const vtkm::Vec<PCoordType, 3>& pcoords,
284  CellShapeTag shape,
285  typename WorldCoordVector::ComponentType& result)
286 {
287  auto numPoints = pointWCoords.GetNumberOfComponents();
288  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
289  vtkm::internal::make_LclCellShapeTag(shape, numPoints), pointWCoords, pcoords, result);
290 }
291 
292 template <typename WorldCoordVector, typename PCoordType>
293 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
294  const WorldCoordVector& pointWCoords,
295  const vtkm::Vec<PCoordType, 3>& pcoords,
296  vtkm::CellShapeTagEmpty empty,
297  typename WorldCoordVector::ComponentType& result)
298 {
299  return vtkm::exec::CellInterpolate(pointWCoords, pcoords, empty, 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,
306  vtkm::CellShapeTagPolyLine polyLine,
307  typename WorldCoordVector::ComponentType& result)
308 {
309  return vtkm::exec::CellInterpolate(pointWCoords, pcoords, polyLine, 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,
316  vtkm::CellShapeTagPolygon,
317  typename WorldCoordVector::ComponentType& result)
318 {
319  auto numPoints = pointWCoords.GetNumberOfComponents();
320  switch (numPoints)
321  {
322  case 1:
323  return ParametricCoordinatesToWorldCoordinates(
324  pointWCoords, pcoords, vtkm::CellShapeTagVertex{}, result);
325  case 2:
326  return ParametricCoordinatesToWorldCoordinates(
327  pointWCoords, pcoords, vtkm::CellShapeTagLine{}, result);
328  default:
329  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
330  lcl::Polygon(numPoints), pointWCoords, pcoords, result);
331  }
332 }
333 
334 template <typename WorldCoordVector, typename PCoordType>
335 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
336  const vtkm::VecAxisAlignedPointCoordinates<2>& pointWCoords,
337  const vtkm::Vec<PCoordType, 3>& pcoords,
338  vtkm::CellShapeTagQuad,
339  typename WorldCoordVector::ComponentType& result)
340 {
341  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
342  lcl::Pixel{}, pointWCoords, pcoords, result);
343 }
344 
345 template <typename WorldCoordVector, typename PCoordType>
346 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
347  const vtkm::VecAxisAlignedPointCoordinates<3>& pointWCoords,
348  const vtkm::Vec<PCoordType, 3>& pcoords,
349  vtkm::CellShapeTagHexahedron,
350  typename WorldCoordVector::ComponentType& result)
351 {
352  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
353  lcl::Voxel{}, pointWCoords, pcoords, result);
354 }
355 
356 //-----------------------------------------------------------------------------
359 template <typename WorldCoordVector, typename PCoordType>
360 static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates(
361  const WorldCoordVector& pointWCoords,
362  const vtkm::Vec<PCoordType, 3>& pcoords,
364  typename WorldCoordVector::ComponentType& result)
365 {
366  vtkm::ErrorCode status;
367  switch (shape.Id)
368  {
369  vtkmGenericCellShapeMacro(status = ParametricCoordinatesToWorldCoordinates(
370  pointWCoords, pcoords, CellShapeTag(), result));
371  default:
372  result = { 0 };
374  }
375  return status;
376 }
377 
378 //-----------------------------------------------------------------------------
379 namespace internal
380 {
381 
382 template <typename LclCellShapeTag, typename WorldCoordVector>
383 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinatesImpl(
384  LclCellShapeTag tag,
385  const WorldCoordVector& pointWCoords,
386  const typename WorldCoordVector::ComponentType& wcoords,
387  typename WorldCoordVector::ComponentType& result)
388 {
389  if (pointWCoords.GetNumberOfComponents() != tag.numberOfPoints())
390  {
391  result = { 0 };
393  }
394 
396  return vtkm::internal::LclErrorToVtkmError(
397  lcl::worldToParametric(tag, lcl::makeFieldAccessorNestedSOA(pointWCoords, 3), wcoords, result));
398 }
399 
400 } // namespace internal
401 
402 template <typename WorldCoordVector, typename CellShapeTag>
403 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
404  const WorldCoordVector& pointWCoords,
405  const typename WorldCoordVector::ComponentType& wcoords,
406  CellShapeTag shape,
407  typename WorldCoordVector::ComponentType& result)
408 {
409  auto numPoints = pointWCoords.GetNumberOfComponents();
410  return internal::WorldCoordinatesToParametricCoordinatesImpl(
411  vtkm::internal::make_LclCellShapeTag(shape, numPoints), pointWCoords, wcoords, result);
412 }
413 
414 template <typename WorldCoordVector>
415 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
416  const WorldCoordVector&,
417  const typename WorldCoordVector::ComponentType&,
418  vtkm::CellShapeTagEmpty,
419  typename WorldCoordVector::ComponentType& result)
420 {
421  result = { 0 };
423 }
424 
425 template <typename WorldCoordVector>
426 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
427  const WorldCoordVector& pointWCoords,
428  const typename WorldCoordVector::ComponentType&,
429  vtkm::CellShapeTagVertex,
430  typename WorldCoordVector::ComponentType& result)
431 {
432  if (pointWCoords.GetNumberOfComponents() != 1)
433  {
434  result = { 0 };
436  }
437  result = typename WorldCoordVector::ComponentType(0, 0, 0);
439 }
440 
441 template <typename WorldCoordVector>
442 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
443  const WorldCoordVector& pointWCoords,
444  const typename WorldCoordVector::ComponentType& wcoords,
445  vtkm::CellShapeTagPolyLine,
446  typename WorldCoordVector::ComponentType& result)
447 {
448  vtkm::IdComponent numPoints = pointWCoords.GetNumberOfComponents();
449  if (numPoints < 1)
450  {
451  result = { 0 };
453  }
454 
455  if (numPoints == 1)
456  {
457  return WorldCoordinatesToParametricCoordinates(
458  pointWCoords, wcoords, vtkm::CellShapeTagVertex(), result);
459  }
460 
461  using Vector3 = typename WorldCoordVector::ComponentType;
462  using T = typename Vector3::ComponentType;
463 
464  //Find the closest vertex to the point.
465  vtkm::IdComponent idx = 0;
466  Vector3 vec = pointWCoords[0] - wcoords;
467  T minDistSq = vtkm::Dot(vec, vec);
468  for (vtkm::IdComponent i = 1; i < numPoints; i++)
469  {
470  vec = pointWCoords[i] - wcoords;
471  T d = vtkm::Dot(vec, vec);
472 
473  if (d < minDistSq)
474  {
475  idx = i;
476  minDistSq = d;
477  }
478  }
479 
480  //Find the right segment, and the parameterization along that segment.
481  //Closest to 0, so segment is (0,1)
482  if (idx == 0)
483  {
484  idx = 1;
485  }
486 
487  vtkm::Vec<Vector3, 2> line(pointWCoords[idx - 1], pointWCoords[idx]);
488  Vector3 lpc;
490  WorldCoordinatesToParametricCoordinates(line, wcoords, vtkm::CellShapeTagLine{}, lpc));
491 
492  //Segment param is [0,1] on that segment.
493  //Map that onto the param for the entire segment.
494  T dParam = static_cast<T>(1) / static_cast<T>(numPoints - 1);
495  T polyLineParam = static_cast<T>(idx - 1) * dParam + lpc[0] * dParam;
496 
497  result = Vector3(polyLineParam, 0, 0);
499 }
500 
501 template <typename WorldCoordVector>
502 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
503  const WorldCoordVector& pointWCoords,
504  const typename WorldCoordVector::ComponentType& wcoords,
505  vtkm::CellShapeTagPolygon,
506  typename WorldCoordVector::ComponentType& result)
507 {
508  auto numPoints = pointWCoords.GetNumberOfComponents();
509  switch (numPoints)
510  {
511  case 1:
512  return WorldCoordinatesToParametricCoordinates(
513  pointWCoords, wcoords, vtkm::CellShapeTagVertex{}, result);
514  case 2:
515  return WorldCoordinatesToParametricCoordinates(
516  pointWCoords, wcoords, vtkm::CellShapeTagLine{}, result);
517  default:
518  return internal::WorldCoordinatesToParametricCoordinatesImpl(
519  lcl::Polygon(numPoints), pointWCoords, wcoords, result);
520  }
521 }
522 
523 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
524  const vtkm::VecAxisAlignedPointCoordinates<2>& pointWCoords,
525  const vtkm::Vec3f& wcoords,
526  vtkm::CellShapeTagQuad,
527  vtkm::Vec3f& result)
528 {
529  return internal::WorldCoordinatesToParametricCoordinatesImpl(
530  lcl::Pixel{}, pointWCoords, wcoords, result);
531 }
532 
533 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
534  const vtkm::VecAxisAlignedPointCoordinates<3>& pointWCoords,
535  const vtkm::Vec3f& wcoords,
536  vtkm::CellShapeTagHexahedron,
537  vtkm::Vec3f& result)
538 {
539  return internal::WorldCoordinatesToParametricCoordinatesImpl(
540  lcl::Voxel{}, pointWCoords, wcoords, result);
541 }
542 
543 //-----------------------------------------------------------------------------
546 template <typename WorldCoordVector>
547 static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates(
548  const WorldCoordVector& pointWCoords,
549  const typename WorldCoordVector::ComponentType& wcoords,
551  typename WorldCoordVector::ComponentType& result)
552 {
553  vtkm::ErrorCode status;
554  switch (shape.Id)
555  {
556  vtkmGenericCellShapeMacro(status = WorldCoordinatesToParametricCoordinates(
557  pointWCoords, wcoords, CellShapeTag(), result));
558  default:
559  result = { 0 };
561  }
562  return status;
563 }
564 
565 }
566 } // namespace vtkm::exec
567 
568 #endif //vtk_m_exec_ParametricCoordinates_h
vtkm::ErrorCode
ErrorCode
Definition: ErrorCode.h:19
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
Represents a component ID (index of component in a vector).
Definition: Types.h:168
FastVec.h
vtkm::ErrorCode::Success
@ Success
Assert.h
CellInterpolate.h
CellShape.h
Assume.h
vtkmGenericCellShapeMacro
#define vtkmGenericCellShapeMacro(call)
A macro used in a switch statement to determine cell shape.
Definition: CellShape.h:230
FunctorBase.h
vtkm::exec::CellInterpolate
VTKM_EXEC vtkm::ErrorCode CellInterpolate(const FieldVecType &pointFieldValues, const vtkm::Vec< ParametricCoordType, 3 > &pcoords, CellShapeTag tag, typename FieldVecType::ComponentType &result)
Definition: CellInterpolate.h:56
vtkm::ErrorCode::InvalidPointId
@ InvalidPointId
vtkm::Vec
A short fixed-length array.
Definition: Types.h:767
vtkm::CellShapeTagGeneric::Id
vtkm::UInt8 Id
Definition: CellShape.h:160
vtkm::ErrorCode::OperationOnEmptyCell
@ OperationOnEmptyCell
VTKM_RETURN_ON_ERROR
#define VTKM_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:111
vtkm::CellShapeTagGeneric
A special cell shape tag that holds a cell shape that is not known at compile time.
Definition: CellShape.h:152
VecAxisAlignedPointCoordinates.h
vtkm::TypeTraits::ZeroInitialization
static VTKM_EXEC_CONT T ZeroInitialization()
Definition: TypeTraits.h:75
vtkm::ErrorCode::InvalidNumberOfPoints
@ InvalidNumberOfPoints
vtkm::ErrorCode::InvalidShapeId
@ InvalidShapeId