Add ability to multiply any Vec by vtkm::Float64.

This has been requested on the mailing list to make it easier to
interpolate integer vectors.

There are a couple of downsides to this addition. First, it implicitly
casts doubles back to whatever the vector type is, which can cause a
loss of precision. Second, it makes it more likely to get overload
errors when multiplying with Vec. In particular, the operator to cast
Vec of size 1 to the component class had to be removed.
This commit is contained in:
Kenneth Moreland 2015-11-07 06:19:40 -07:00
parent e5200db8eb
commit bf03243516
4 changed files with 92 additions and 33 deletions

@ -638,7 +638,7 @@ struct VecComponentWiseUnaryOperation<4>
}
};
template<typename T, typename BinaryOpType>
template<typename T, typename BinaryOpType, typename ReturnT = T>
struct BindLeftBinaryOp
{
// Warning: a reference.
@ -648,13 +648,13 @@ struct BindLeftBinaryOp
BindLeftBinaryOp(const T &leftValue, BinaryOpType binaryOp = BinaryOpType())
: LeftValue(leftValue), BinaryOp(binaryOp) { }
VTKM_EXEC_CONT_EXPORT
T operator()(const T &rightValue) const
ReturnT operator()(const T &rightValue) const
{
return this->BinaryOp(this->LeftValue, rightValue);
return static_cast<ReturnT>(this->BinaryOp(this->LeftValue, rightValue));
}
};
template<typename T, typename BinaryOpType>
template<typename T, typename BinaryOpType, typename ReturnT = T>
struct BindRightBinaryOp
{
// Warning: a reference.
@ -664,9 +664,9 @@ struct BindRightBinaryOp
BindRightBinaryOp(const T &rightValue, BinaryOpType binaryOp = BinaryOpType())
: RightValue(rightValue), BinaryOp(binaryOp) { }
VTKM_EXEC_CONT_EXPORT
T operator()(const T &leftValue) const
ReturnT operator()(const T &leftValue) const
{
return this->BinaryOp(leftValue, this->RightValue);
return static_cast<ReturnT>(this->BinaryOp(leftValue, this->RightValue));
}
};
@ -875,15 +875,6 @@ public:
vtkm::internal::Multiply());
}
VTKM_EXEC_CONT_EXPORT
DerivedClass operator*(ComponentType scalar) const
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
*reinterpret_cast<const DerivedClass*>(this),
vtkm::internal::BindRightBinaryOp<
ComponentType,vtkm::internal::Multiply>(scalar));
}
VTKM_EXEC_CONT_EXPORT
DerivedClass operator/(const DerivedClass &other) const
@ -989,16 +980,18 @@ class Vec<T,1> : public detail::VecBase<T, 1, Vec<T,1> >
public:
VTKM_EXEC_CONT_EXPORT Vec() {}
VTKM_EXEC_CONT_EXPORT Vec(const T& value) : Superclass(value) { }
VTKM_EXEC_CONT_EXPORT explicit Vec(const T& value) : Superclass(value) { }
template<typename OtherType>
VTKM_EXEC_CONT_EXPORT Vec(const Vec<OtherType, 1> &src) : Superclass(src) { }
VTKM_EXEC_CONT_EXPORT
operator T() const
{
return this->Components[0];
}
// This convenience operator removed because it was causing ambiguous
// overload errors
// VTKM_EXEC_CONT_EXPORT
// operator T() const
// {
// return this->Components[0];
// }
};
//-----------------------------------------------------------------------------
@ -1170,6 +1163,61 @@ vtkm::Vec<T, Size> operator*(T scalar, const vtkm::Vec<T, Size> &vec)
vtkm::internal::BindLeftBinaryOp<T,vtkm::internal::Multiply>(scalar));
}
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<T, Size> operator*(const vtkm::Vec<T, Size> &vec, T scalar)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec,
vtkm::internal::BindRightBinaryOp<T,vtkm::internal::Multiply>(scalar));
}
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<T, Size>
operator*(vtkm::Float64 scalar, const vtkm::Vec<T, Size> &vec)
{
return vtkm::Vec<T, Size>(
vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec,
vtkm::internal::BindLeftBinaryOp<
vtkm::Float64,vtkm::internal::Multiply,T>(scalar)));
}
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<T, Size>
operator*(const vtkm::Vec<T, Size> &vec, vtkm::Float64 scalar)
{
return vtkm::Vec<T, Size>(
vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec,
vtkm::internal::BindRightBinaryOp<
vtkm::Float64,vtkm::internal::Multiply,T>(scalar)));
}
template<vtkm::IdComponent Size>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<vtkm::Float64, Size>
operator*(vtkm::Float64 scalar, const vtkm::Vec<vtkm::Float64, Size> &vec)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec,
vtkm::internal::BindLeftBinaryOp<
vtkm::Float64,vtkm::internal::Multiply>(scalar));
}
template<vtkm::IdComponent Size>
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<vtkm::Float64, Size>
operator*(const vtkm::Vec<vtkm::Float64, Size> &vec, vtkm::Float64 scalar)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec,
vtkm::internal::BindRightBinaryOp<
vtkm::Float64,vtkm::internal::Multiply>(scalar));
}
// The enable_if for this operator is effectively disabling the negate
// operator for Vec of unsigned integers. Another approach would be
// to use disable_if<is_unsigned>. That would be more inclusive but would

@ -88,7 +88,7 @@ public:
}
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<vtkm::Id,Dimension>
SchedulingRangeType
FlatToLogicalFromIndex(vtkm::Id flatFromIndex) const
{
return Helper::FlatToLogicalFromIndex(this->Internals, flatFromIndex);
@ -96,13 +96,13 @@ public:
VTKM_EXEC_CONT_EXPORT
vtkm::Id LogicalToFlatFromIndex(
const vtkm::Vec<vtkm::Id,Dimension> &logicalFromIndex) const
const SchedulingRangeType &logicalFromIndex) const
{
return Helper::LogicalToFlatFromIndex(this->Internals, logicalFromIndex);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<vtkm::Id,Dimension>
SchedulingRangeType
FlatToLogicalToIndex(vtkm::Id flatToIndex) const
{
return Helper::FlatToLogicalToIndex(this->Internals, flatToIndex);
@ -110,7 +110,7 @@ public:
VTKM_EXEC_CONT_EXPORT
vtkm::Id LogicalToFlatToIndex(
const vtkm::Vec<vtkm::Id,Dimension> &logicalToIndex) const
const SchedulingRangeType &logicalToIndex) const
{
return Helper::LogicalToFlatToIndex(this->Internals, logicalToIndex);
}

@ -94,6 +94,17 @@ make_VecRectilinearPointCoordinates(
return vtkm::VecRectilinearPointCoordinates<1>(offsetOrigin, spacing);
}
VTKM_EXEC_EXPORT
vtkm::VecRectilinearPointCoordinates<1>
make_VecRectilinearPointCoordinates(
const vtkm::Vec<vtkm::FloatDefault,3> &origin,
const vtkm::Vec<vtkm::FloatDefault,3> &spacing,
vtkm::Id logicalId)
{
return make_VecRectilinearPointCoordinates(
origin, spacing, vtkm::Vec<vtkm::Id,1>(logicalId));
}
VTKM_EXEC_EXPORT
vtkm::VecRectilinearPointCoordinates<2>
make_VecRectilinearPointCoordinates(

@ -588,7 +588,7 @@ struct ConnectivityStructuredIndexHelper<
}
VTKM_EXEC_CONT_EXPORT
static vtkm::Vec<vtkm::Id,Dimension>
static LogicalIndexType
FlatToLogicalFromIndex(const ConnectivityType &connectivity,
vtkm::Id flatFromIndex)
{
@ -598,13 +598,13 @@ struct ConnectivityStructuredIndexHelper<
VTKM_EXEC_CONT_EXPORT
static vtkm::Id
LogicalToFlatFromIndex(const ConnectivityType &connectivity,
const vtkm::Vec<vtkm::Id,Dimension> &logicalFromIndex)
const LogicalIndexType &logicalFromIndex)
{
return connectivity.LogicalToFlatPointIndex(logicalFromIndex);
}
VTKM_EXEC_CONT_EXPORT
static vtkm::Vec<vtkm::Id,Dimension>
static LogicalIndexType
FlatToLogicalToIndex(const ConnectivityType &connectivity,
vtkm::Id flatToIndex)
{
@ -614,7 +614,7 @@ struct ConnectivityStructuredIndexHelper<
VTKM_EXEC_CONT_EXPORT
static vtkm::Id
LogicalToFlatToIndex(const ConnectivityType &connectivity,
const vtkm::Vec<vtkm::Id,Dimension> &logicalToIndex)
const LogicalIndexType &logicalToIndex)
{
return connectivity.LogicalToFlatCellIndex(logicalToIndex);
}
@ -649,7 +649,7 @@ struct ConnectivityStructuredIndexHelper<
}
VTKM_EXEC_CONT_EXPORT
static vtkm::Vec<vtkm::Id,Dimension>
static LogicalIndexType
FlatToLogicalFromIndex(const ConnectivityType &connectivity,
vtkm::Id flatFromIndex)
{
@ -659,13 +659,13 @@ struct ConnectivityStructuredIndexHelper<
VTKM_EXEC_CONT_EXPORT
static vtkm::Id
LogicalToFlatFromIndex(const ConnectivityType &connectivity,
const vtkm::Vec<vtkm::Id,Dimension> &logicalFromIndex)
const LogicalIndexType &logicalFromIndex)
{
return connectivity.LogicalToFlatCellIndex(logicalFromIndex);
}
VTKM_EXEC_CONT_EXPORT
static vtkm::Vec<vtkm::Id,Dimension>
static LogicalIndexType
FlatToLogicalToIndex(const ConnectivityType &connectivity,
vtkm::Id flatToIndex)
{
@ -675,7 +675,7 @@ struct ConnectivityStructuredIndexHelper<
VTKM_EXEC_CONT_EXPORT
static vtkm::Id
LogicalToFlatToIndex(const ConnectivityType &connectivity,
const vtkm::Vec<vtkm::Id,Dimension> &logicalToIndex)
const LogicalIndexType &logicalToIndex)
{
return connectivity.LogicalToFlatPointIndex(logicalToIndex);
}