Viskores  1.0
ParametricCoordinates.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_exec_ParametricCoordinates_h
19 #define viskores_exec_ParametricCoordinates_h
20 
21 #include <viskores/Assert.h>
22 #include <viskores/CellShape.h>
28 
29 #include <lcl/lcl.h>
30 
31 namespace viskores
32 {
33 namespace exec
34 {
35 
36 //-----------------------------------------------------------------------------
37 template <typename ParametricCoordType, typename CellShapeTag>
38 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesCenter(
39  viskores::IdComponent numPoints,
40  CellShapeTag,
42 {
43  auto lclTag = typename viskores::internal::CellShapeTagViskoresToVtkc<CellShapeTag>::Type{};
44 
45  pcoords = viskores::TypeTraits<viskores::Vec<ParametricCoordType, 3>>::ZeroInitialization();
46  if (numPoints != lclTag.numberOfPoints())
47  {
49  }
50 
51  return viskores::internal::LclErrorToViskoresError(lcl::parametricCenter(lclTag, pcoords));
52 }
53 
54 template <typename ParametricCoordType>
55 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesCenter(
56  viskores::IdComponent numPoints,
59 {
60  pcoords = viskores::TypeTraits<viskores::Vec<ParametricCoordType, 3>>::ZeroInitialization();
61  if (numPoints != 0)
62  {
64  }
66 }
67 
68 template <typename ParametricCoordType>
69 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesCenter(
70  viskores::IdComponent numPoints,
73 {
74  pcoords = viskores::TypeTraits<viskores::Vec<ParametricCoordType, 3>>::ZeroInitialization();
75  if (numPoints != 1)
76  {
78  }
80 }
81 
82 template <typename ParametricCoordType>
83 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesCenter(
84  viskores::IdComponent numPoints,
87 {
88  switch (numPoints)
89  {
90  case 1:
91  return ParametricCoordinatesCenter(numPoints, viskores::CellShapeTagVertex(), pcoords);
92  case 2:
93  return ParametricCoordinatesCenter(numPoints, viskores::CellShapeTagLine(), pcoords);
94  }
95  pcoords[0] = 0.5;
96  pcoords[1] = 0;
97  pcoords[2] = 0;
99 }
100 
101 template <typename ParametricCoordType>
102 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesCenter(
103  viskores::IdComponent numPoints,
106 {
107  if (numPoints < 1)
108  {
109  pcoords = { 0 };
111  }
112  switch (numPoints)
113  {
114  case 1:
115  return ParametricCoordinatesCenter(numPoints, viskores::CellShapeTagVertex(), pcoords);
116  case 2:
117  return ParametricCoordinatesCenter(numPoints, viskores::CellShapeTagLine(), pcoords);
118  default:
119  pcoords = viskores::TypeTraits<viskores::Vec<ParametricCoordType, 3>>::ZeroInitialization();
120  return viskores::internal::LclErrorToViskoresError(
121  lcl::parametricCenter(lcl::Polygon(numPoints), pcoords));
122  }
123 }
124 
125 //-----------------------------------------------------------------------------
133 template <typename ParametricCoordType>
134 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesCenter(
135  viskores::IdComponent numPoints,
138 {
139  viskores::ErrorCode status;
140  switch (shape.Id)
141  {
143  status = ParametricCoordinatesCenter(numPoints, CellShapeTag(), pcoords));
144  default:
145  pcoords = { 0 };
147  }
148  return status;
149 }
150 
151 //-----------------------------------------------------------------------------
152 template <typename ParametricCoordType, typename CellShapeTag>
153 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesPoint(
154  viskores::IdComponent numPoints,
155  viskores::IdComponent pointIndex,
156  CellShapeTag,
158 {
159  auto lclTag = typename viskores::internal::CellShapeTagViskoresToVtkc<CellShapeTag>::Type{};
160 
161  if (numPoints != lclTag.numberOfPoints())
162  {
163  pcoords = { 0 };
165  }
166  if ((pointIndex < 0) || (pointIndex >= numPoints))
167  {
168  pcoords = { 0 };
170  }
171 
172  pcoords = viskores::TypeTraits<viskores::Vec<ParametricCoordType, 3>>::ZeroInitialization();
173  return viskores::internal::LclErrorToViskoresError(
174  lcl::parametricPoint(lclTag, pointIndex, pcoords));
175 }
176 
177 template <typename ParametricCoordType>
178 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesPoint(
183 {
184  pcoords[0] = pcoords[1] = pcoords[2] = 0;
186 }
187 
188 template <typename ParametricCoordType>
189 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesPoint(
190  viskores::IdComponent numPoints,
191  viskores::IdComponent pointIndex,
194 {
195  pcoords = viskores::TypeTraits<viskores::Vec<ParametricCoordType, 3>>::ZeroInitialization();
196  if (numPoints != 1)
197  {
199  }
200  if (pointIndex != 0)
201  {
203  }
205 }
206 
207 template <typename ParametricCoordType>
208 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesPoint(
209  viskores::IdComponent numPoints,
210  viskores::IdComponent pointIndex,
213 {
214  if (numPoints < 1)
215  {
216  pcoords = { 0 };
218  }
219  switch (numPoints)
220  {
221  case 1:
222  return ParametricCoordinatesPoint(
223  numPoints, pointIndex, viskores::CellShapeTagVertex(), pcoords);
224  case 2:
225  return ParametricCoordinatesPoint(
226  numPoints, pointIndex, viskores::CellShapeTagLine(), pcoords);
227  }
228  pcoords[0] =
229  static_cast<ParametricCoordType>(pointIndex) / static_cast<ParametricCoordType>(numPoints - 1);
230  pcoords[1] = 0;
231  pcoords[2] = 0;
233 }
234 
235 template <typename ParametricCoordType>
236 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesPoint(
237  viskores::IdComponent numPoints,
238  viskores::IdComponent pointIndex,
241 {
242  switch (numPoints)
243  {
244  case 1:
245  return ParametricCoordinatesPoint(
246  numPoints, pointIndex, viskores::CellShapeTagVertex(), pcoords);
247  case 2:
248  return ParametricCoordinatesPoint(
249  numPoints, pointIndex, viskores::CellShapeTagLine(), pcoords);
250  default:
251  pcoords = viskores::TypeTraits<viskores::Vec<ParametricCoordType, 3>>::ZeroInitialization();
252  return viskores::internal::LclErrorToViskoresError(
253  lcl::parametricPoint(lcl::Polygon(numPoints), pointIndex, pcoords));
254  }
255 }
256 
257 //-----------------------------------------------------------------------------
267 template <typename ParametricCoordType>
268 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesPoint(
269  viskores::IdComponent numPoints,
270  viskores::IdComponent pointIndex,
273 {
274  viskores::ErrorCode status;
275  switch (shape.Id)
276  {
278  status = ParametricCoordinatesPoint(numPoints, pointIndex, CellShapeTag(), pcoords));
279  default:
280  pcoords[0] = pcoords[1] = pcoords[2] = 0;
282  }
283  return status;
284 }
285 
286 //-----------------------------------------------------------------------------
287 namespace internal
288 {
289 
290 template <typename LclCellShapeTag, typename WorldCoordVector, typename PCoordType>
291 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesToWorldCoordinatesImpl(
292  LclCellShapeTag tag,
293  const WorldCoordVector& pointWCoords,
294  const PCoordType& pcoords,
295  typename WorldCoordVector::ComponentType& wcoords)
296 {
297  return viskores::internal::LclErrorToViskoresError(lcl::parametricToWorld(
298  tag, lcl::makeFieldAccessorNestedSOA(pointWCoords, 3), pcoords, wcoords));
299 }
300 
301 } // namespace internal
302 
303 template <typename WorldCoordVector, typename PCoordType, typename CellShapeTag>
304 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesToWorldCoordinates(
305  const WorldCoordVector& pointWCoords,
306  const viskores::Vec<PCoordType, 3>& pcoords,
307  CellShapeTag shape,
308  typename WorldCoordVector::ComponentType& result)
309 {
310  auto numPoints = pointWCoords.GetNumberOfComponents();
311  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
312  viskores::internal::make_LclCellShapeTag(shape, numPoints), pointWCoords, pcoords, result);
313 }
314 
315 template <typename WorldCoordVector, typename PCoordType>
316 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesToWorldCoordinates(
317  const WorldCoordVector& pointWCoords,
318  const viskores::Vec<PCoordType, 3>& pcoords,
320  typename WorldCoordVector::ComponentType& result)
321 {
322  return viskores::exec::CellInterpolate(pointWCoords, pcoords, empty, result);
323 }
324 
325 template <typename WorldCoordVector, typename PCoordType>
326 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesToWorldCoordinates(
327  const WorldCoordVector& pointWCoords,
328  const viskores::Vec<PCoordType, 3>& pcoords,
330  typename WorldCoordVector::ComponentType& result)
331 {
332  return viskores::exec::CellInterpolate(pointWCoords, pcoords, polyLine, result);
333 }
334 
335 template <typename WorldCoordVector, typename PCoordType>
336 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesToWorldCoordinates(
337  const WorldCoordVector& pointWCoords,
338  const viskores::Vec<PCoordType, 3>& pcoords,
340  typename WorldCoordVector::ComponentType& result)
341 {
342  auto numPoints = pointWCoords.GetNumberOfComponents();
343  switch (numPoints)
344  {
345  case 1:
346  return ParametricCoordinatesToWorldCoordinates(
347  pointWCoords, pcoords, viskores::CellShapeTagVertex{}, result);
348  case 2:
349  return ParametricCoordinatesToWorldCoordinates(
350  pointWCoords, pcoords, viskores::CellShapeTagLine{}, result);
351  default:
352  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
353  lcl::Polygon(numPoints), pointWCoords, pcoords, result);
354  }
355 }
356 
357 template <typename WorldCoordVector, typename PCoordType>
358 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesToWorldCoordinates(
360  const viskores::Vec<PCoordType, 3>& pcoords,
362  typename WorldCoordVector::ComponentType& result)
363 {
364  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
365  lcl::Pixel{}, pointWCoords, pcoords, result);
366 }
367 
368 template <typename WorldCoordVector, typename PCoordType>
369 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesToWorldCoordinates(
371  const viskores::Vec<PCoordType, 3>& pcoords,
373  typename WorldCoordVector::ComponentType& result)
374 {
375  return internal::ParametricCoordinatesToWorldCoordinatesImpl(
376  lcl::Voxel{}, pointWCoords, pcoords, result);
377 }
378 
379 //-----------------------------------------------------------------------------
391 template <typename WorldCoordVector, typename PCoordType>
392 static inline VISKORES_EXEC viskores::ErrorCode ParametricCoordinatesToWorldCoordinates(
393  const WorldCoordVector& pointWCoords,
394  const viskores::Vec<PCoordType, 3>& pcoords,
396  typename WorldCoordVector::ComponentType& result)
397 {
398  viskores::ErrorCode status;
399  switch (shape.Id)
400  {
401  viskoresGenericCellShapeMacro(status = ParametricCoordinatesToWorldCoordinates(
402  pointWCoords, pcoords, CellShapeTag(), result));
403  default:
404  result = { 0 };
406  }
407  return status;
408 }
409 
410 //-----------------------------------------------------------------------------
411 namespace internal
412 {
413 
414 template <typename LclCellShapeTag, typename WorldCoordVector>
415 static inline VISKORES_EXEC viskores::ErrorCode WorldCoordinatesToParametricCoordinatesImpl(
416  LclCellShapeTag tag,
417  const WorldCoordVector& pointWCoords,
418  const typename WorldCoordVector::ComponentType& wcoords,
419  typename WorldCoordVector::ComponentType& result)
420 {
421  if (pointWCoords.GetNumberOfComponents() != tag.numberOfPoints())
422  {
423  result = { 0 };
425  }
426 
428  return viskores::internal::LclErrorToViskoresError(
429  lcl::worldToParametric(tag, lcl::makeFieldAccessorNestedSOA(pointWCoords, 3), wcoords, result));
430 }
431 
432 } // namespace internal
433 
434 template <typename WorldCoordVector, typename CellShapeTag>
435 static inline VISKORES_EXEC viskores::ErrorCode WorldCoordinatesToParametricCoordinates(
436  const WorldCoordVector& pointWCoords,
437  const typename WorldCoordVector::ComponentType& wcoords,
438  CellShapeTag shape,
439  typename WorldCoordVector::ComponentType& result)
440 {
441  auto numPoints = pointWCoords.GetNumberOfComponents();
442  return internal::WorldCoordinatesToParametricCoordinatesImpl(
443  viskores::internal::make_LclCellShapeTag(shape, numPoints), pointWCoords, wcoords, result);
444 }
445 
446 template <typename WorldCoordVector>
447 static inline VISKORES_EXEC viskores::ErrorCode WorldCoordinatesToParametricCoordinates(
448  const WorldCoordVector&,
449  const typename WorldCoordVector::ComponentType&,
451  typename WorldCoordVector::ComponentType& result)
452 {
453  result = { 0 };
455 }
456 
457 template <typename WorldCoordVector>
458 static inline VISKORES_EXEC viskores::ErrorCode WorldCoordinatesToParametricCoordinates(
459  const WorldCoordVector& pointWCoords,
460  const typename WorldCoordVector::ComponentType&,
462  typename WorldCoordVector::ComponentType& result)
463 {
464  if (pointWCoords.GetNumberOfComponents() != 1)
465  {
466  result = { 0 };
468  }
469  result = typename WorldCoordVector::ComponentType(0, 0, 0);
471 }
472 
473 template <typename WorldCoordVector>
474 static inline VISKORES_EXEC viskores::ErrorCode WorldCoordinatesToParametricCoordinates(
475  const WorldCoordVector& pointWCoords,
476  const typename WorldCoordVector::ComponentType& wcoords,
478  typename WorldCoordVector::ComponentType& result)
479 {
480  viskores::IdComponent numPoints = pointWCoords.GetNumberOfComponents();
481  if (numPoints < 1)
482  {
483  result = { 0 };
485  }
486 
487  if (numPoints == 1)
488  {
489  return WorldCoordinatesToParametricCoordinates(
490  pointWCoords, wcoords, viskores::CellShapeTagVertex(), result);
491  }
492 
493  using Vector3 = typename WorldCoordVector::ComponentType;
494  using T = typename Vector3::ComponentType;
495 
496  //Find the closest vertex to the point.
497  viskores::IdComponent idx = 0;
498  Vector3 vec = pointWCoords[0] - wcoords;
499  T minDistSq = viskores::Dot(vec, vec);
500  for (viskores::IdComponent i = 1; i < numPoints; i++)
501  {
502  vec = pointWCoords[i] - wcoords;
503  T d = viskores::Dot(vec, vec);
504 
505  if (d < minDistSq)
506  {
507  idx = i;
508  minDistSq = d;
509  }
510  }
511 
512  //Find the right segment, and the parameterization along that segment.
513  //Closest to 0, so segment is (0,1)
514  if (idx == 0)
515  {
516  idx = 1;
517  }
518 
519  viskores::Vec<Vector3, 2> line(pointWCoords[idx - 1], pointWCoords[idx]);
520  Vector3 lpc;
522  WorldCoordinatesToParametricCoordinates(line, wcoords, viskores::CellShapeTagLine{}, lpc));
523 
524  //Segment param is [0,1] on that segment.
525  //Map that onto the param for the entire segment.
526  T dParam = static_cast<T>(1) / static_cast<T>(numPoints - 1);
527  T polyLineParam = static_cast<T>(idx - 1) * dParam + lpc[0] * dParam;
528 
529  result = Vector3(polyLineParam, 0, 0);
531 }
532 
533 template <typename WorldCoordVector>
534 static inline VISKORES_EXEC viskores::ErrorCode WorldCoordinatesToParametricCoordinates(
535  const WorldCoordVector& pointWCoords,
536  const typename WorldCoordVector::ComponentType& wcoords,
538  typename WorldCoordVector::ComponentType& result)
539 {
540  auto numPoints = pointWCoords.GetNumberOfComponents();
541  switch (numPoints)
542  {
543  case 1:
544  return WorldCoordinatesToParametricCoordinates(
545  pointWCoords, wcoords, viskores::CellShapeTagVertex{}, result);
546  case 2:
547  return WorldCoordinatesToParametricCoordinates(
548  pointWCoords, wcoords, viskores::CellShapeTagLine{}, result);
549  default:
550  return internal::WorldCoordinatesToParametricCoordinatesImpl(
551  lcl::Polygon(numPoints), pointWCoords, wcoords, result);
552  }
553 }
554 
555 static inline VISKORES_EXEC viskores::ErrorCode WorldCoordinatesToParametricCoordinates(
557  const viskores::Vec3f& wcoords,
559  viskores::Vec3f& result)
560 {
561  return internal::WorldCoordinatesToParametricCoordinatesImpl(
562  lcl::Pixel{}, pointWCoords, wcoords, result);
563 }
564 
565 static inline VISKORES_EXEC viskores::ErrorCode WorldCoordinatesToParametricCoordinates(
567  const viskores::Vec3f& wcoords,
569  viskores::Vec3f& result)
570 {
571  return internal::WorldCoordinatesToParametricCoordinatesImpl(
572  lcl::Voxel{}, pointWCoords, wcoords, result);
573 }
574 
575 //-----------------------------------------------------------------------------
588 template <typename WorldCoordVector>
589 static inline VISKORES_EXEC viskores::ErrorCode WorldCoordinatesToParametricCoordinates(
590  const WorldCoordVector& pointWCoords,
591  const typename WorldCoordVector::ComponentType& wcoords,
593  typename WorldCoordVector::ComponentType& result)
594 {
595  viskores::ErrorCode status;
596  switch (shape.Id)
597  {
598  viskoresGenericCellShapeMacro(status = WorldCoordinatesToParametricCoordinates(
599  pointWCoords, wcoords, CellShapeTag(), result));
600  default:
601  result = { 0 };
603  }
604  return status;
605 }
606 
607 }
608 } // namespace viskores::exec
609 
610 #endif //viskores_exec_ParametricCoordinates_h
viskores::CellShapeTagGeneric::Id
viskores::UInt8 Id
An identifier that corresponds to one of the CELL_SHAPE_* identifiers.
Definition: CellShape.h:188
viskores::VecAxisAlignedPointCoordinates
An implicit vector for point coordinates in axis aligned cells.
Definition: VecAxisAlignedPointCoordinates.h:86
viskores::CellShapeTagLine
Definition: CellShape.h:158
viskores::CellShapeTagHexahedron
Definition: CellShape.h:167
viskores::TypeTraits::ZeroInitialization
static T ZeroInitialization()
A static function that returns 0 (or the closest equivalent to it) for the given type.
Definition: TypeTraits.h:85
FastVec.h
viskoresGenericCellShapeMacro
#define viskoresGenericCellShapeMacro(call)
A macro used in a switch statement to determine cell shape.
Definition: CellShape.h:257
viskores::ErrorCode
ErrorCode
Identifies whether an operation was successful or what type of error it had.
Definition: ErrorCode.h:36
viskores::ErrorCode::InvalidNumberOfPoints
@ InvalidNumberOfPoints
The wrong number of points was provided for a given cell type.
Assert.h
CellInterpolate.h
viskores::ErrorCode::InvalidPointId
@ InvalidPointId
A bad point identifier was detected while operating on a cell.
viskores::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
CellShape.h
viskores::CellShapeTagGeneric
A special cell shape tag that holds a cell shape that is not known at compile time.
Definition: CellShape.h:178
viskores::ErrorCode::InvalidShapeId
@ InvalidShapeId
A unknown shape identifier was encountered.
VISKORES_RETURN_ON_ERROR
#define VISKORES_RETURN_ON_ERROR(call)
Definition: ErrorCode.h:210
Assume.h
viskores::CellShapeTagEmpty
Definition: CellShape.h:155
viskores::TypeTraits
The TypeTraits class provides helpful compile-time information about the basic types used in Viskores...
Definition: TypeTraits.h:69
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
FunctorBase.h
viskores::CellShapeTagVertex
Definition: CellShape.h:156
viskores::CellShapeTagQuad
Definition: CellShape.h:164
viskores::ErrorCode::OperationOnEmptyCell
@ OperationOnEmptyCell
An operation was attempted on a cell with an empty shape.
viskores::CellShapeTagPolygon
Definition: CellShape.h:162
viskores::ErrorCode::Success
@ Success
A successful operation.
viskores::CellShapeTagPolyLine
Definition: CellShape.h:159
VecAxisAlignedPointCoordinates.h
viskores::Vec
A short fixed-length array.
Definition: Types.h:365
VISKORES_EXEC
#define VISKORES_EXEC
Definition: ExportMacros.h:59
viskores::exec::CellInterpolate
viskores::ErrorCode CellInterpolate(const FieldVecType &pointFieldValues, const viskores::Vec< ParametricCoordType, 3 > &pcoords, CellShapeTag tag, typename FieldVecType::ComponentType &result)
Definition: CellInterpolate.h:66