24 #ifndef PXR_BASE_VT_WRAP_ARRAY_H
25 #define PXR_BASE_VT_WRAP_ARRAY_H
29 #include "pxr/base/vt/array.h"
51 #include <hboost/preprocessor/punctuation/comma_if.hpp>
52 #include <hboost/preprocessor/repetition/repeat.hpp>
53 #include <hboost/preprocessor/seq/for_each.hpp>
55 #include <hboost/python/class.hpp>
56 #include <hboost/python/copy_const_reference.hpp>
57 #include <hboost/python/def.hpp>
58 #include <hboost/python/detail/api_placeholder.hpp>
59 #include <hboost/python/extract.hpp>
60 #include <hboost/python/implicit.hpp>
61 #include <hboost/python/iterator.hpp>
62 #include <hboost/python/make_constructor.hpp>
63 #include <hboost/python/object.hpp>
64 #include <hboost/python/operators.hpp>
65 #include <hboost/python/return_arg.hpp>
66 #include <hboost/python/slice.hpp>
67 #include <hboost/python/type_id.hpp>
68 #include <hboost/python/overloads.hpp>
79 namespace Vt_WrapArray {
81 using namespace hboost::python;
83 using std::unique_ptr;
92 if (idx != ellipsis) {
93 PyErr_SetString(PyExc_TypeError,
"unsupported index type");
94 throw_error_already_set();
103 static const bool throwError =
true;
108 template <
typename T>
113 slice::range<typename VtArray<T>::const_iterator>
range =
114 idx.get_indices(
self.
begin(),
self.
end());
115 const size_t setSize = 1 + (range.stop - range.start) / range.step;
118 for (; range.start != range.stop; range.start += range.step, ++i) {
124 catch (std::invalid_argument
const &) {
129 template <
typename T,
typename S>
132 slice::range<T*>&
range,
size_t setSize,
bool tile =
false)
135 const size_t length = len(value);
138 if (!tile && length < setSize) {
140 (
"Not enough values to set slice. Expected %zu, got %zu.",
147 std::vector<T> extracted;
148 extract<std::vector<T> > vectorExtraction(value);
149 if (vectorExtraction.check()) {
150 std::vector<T> tmp = vectorExtraction();
154 extracted.reserve(length);
155 for (
size_t i = 0; i !=
length; ++i) {
156 extracted.push_back(extract<T>(value[i]));
162 if (range.step == 1 && length >= setSize) {
163 std::copy(extracted.begin(), extracted.begin() + setSize, range.start);
166 for (
size_t i = 0; i != setSize; range.start += range.step, ++i) {
167 *range.start = extracted[i %
length];
172 template <
typename T>
177 slice::range<T*>
range;
179 T*
data =
self.data();
180 range = idx.get_indices(data, data +
self.
size());
182 catch (std::invalid_argument
const &) {
188 const size_t setSize = 1 + (range.stop - range.start) / range.step;
197 const size_t length = val.size();
200 if (!tile && length < setSize) {
202 (
"Not enough values to set slice. Expected %zu, got %zu.",
208 for (
size_t i = 0; i != setSize; range.start += range.step, ++i) {
209 *range.start = val[i %
length];
214 else if (extract<T>(value).check()) {
222 for (
size_t i = 0; i != setSize; range.start += range.step, ++i) {
228 else if (extract<list>(value).check()) {
229 setArraySlice(
self, extract<list>(value)(), range, setSize, tile);
233 else if (extract<tuple>(value).check()) {
234 setArraySlice(
self, extract<tuple>(value)(), range, setSize, tile);
244 template <
typename T>
249 if (idx != ellipsis) {
250 PyErr_SetString(PyExc_TypeError,
"unsupported index type");
251 throw_error_already_set();
256 template <
typename T>
264 template <
typename T>
278 template <
typename T>
279 static void streamValue(std::ostringstream &
stream, T
const &
value) {
285 #define _OPTIMIZED_STREAM_INTEGRAL_TYPES \
295 #define MAKE_STREAM_FUNC(r, unused, type) \
297 streamValue(std::ostringstream &stream, type const &value) { \
301 #undef MAKE_STREAM_FUNC
302 #undef _OPTIMIZED_STREAM_INTEGRAL_TYPES
308 template <
typename T>
309 static bool _IsFinite(T
const &
value) {
310 return std::isfinite(value);
313 return std::isfinite(static_cast<float>(value));
317 #define MAKE_STREAM_FUNC(r, unused, elem) \
319 streamValue(std::ostringstream &stream, VT_TYPE(elem) const &value) { \
320 if (_IsFinite(value)) { \
323 stream << TfPyRepr(value); \
328 #undef MAKE_STREAM_FUNC
331 Vt_ComputeEffectiveRankAndLastDimSize(
340 1, [](
size_t x,
size_t y) {
return x * y; });
351 template <
typename T>
358 std::ostringstream
stream;
359 stream.precision(17);
361 for (
size_t i = 0; i <
self.size(); ++i) {
362 stream << (i ?
", " :
"");
363 streamValue(stream,
self[i]);
365 stream << (
self.size() == 1 ?
",)" :
")");
370 self.
size(), stream.str().c_str());
380 size_t lastDimSize = 0;
382 Vt_ComputeEffectiveRankAndLastDimSize(shapeData, &lastDimSize);
385 for (
size_t i = 0; i != rank-1; ++i) {
387 i ?
", %d" :
"%d", shapeData->otherDims[i]);
391 repr.c_str(), shapeStr.c_str());
397 template <
typename T>
401 unique_ptr<VtArray<T> > ret(
new VtArray<T>(len(values)));
405 static const bool tile =
true;
407 return ret.release();
409 template <
typename T>
413 unique_ptr<VtArray<T> > ret(
new VtArray<T>(size));
417 static const bool tile =
true;
420 return ret.release();
444 template <typename T>
445 static std::
string _VtStr(T
const &self)
450 template <
typename T>
453 using namespace Vt_WrapArray;
456 typedef typename This::ElementType
Type;
458 string name = GetVtArrayName<This>();
460 string docStr =
TfStringPrintf(
"An array of type %s.", typeStr.c_str());
462 auto selfCls = class_<This>(
name.c_str(), docStr.c_str(), no_init)
463 .setattr(
"_isVtArray",
true)
466 .def(
"__init__", make_constructor(VtArray__init__<Type>),
468 "__init__(values)\n\n"
469 "values: a sequence (tuple, list, or another VtArray with "
470 "element type convertible to the new array's element type)\n\n"
472 .def(
"__init__", make_constructor(VtArray__init__2<Type>))
473 .def(init<unsigned int>())
475 .def(
"__getitem__", getitem_ellipsis<Type>)
476 .def(
"__getitem__", getitem_slice<Type>)
477 .def(
"__getitem__", getitem_index<Type>)
478 .def(
"__setitem__", setitem_ellipsis<Type>)
479 .def(
"__setitem__", setitem_slice<Type>)
480 .def(
"__setitem__", setitem_index<Type>)
483 .def(
"__iter__", iterator<This>())
485 .def(
"__repr__", __repr__<Type>)
488 .def(
"__str__", _VtStr<T>)
492 #ifdef NUMERIC_OPERATORS
493 #define ADDITION_OPERATOR
494 #define SUBTRACTION_OPERATOR
495 #define MULTIPLICATION_OPERATOR
496 #define DIVISION_OPERATOR
497 #define UNARY_NEG_OPERATOR
500 #ifdef ADDITION_OPERATOR
503 #ifdef SUBTRACTION_OPERATOR
506 #ifdef MULTIPLICATION_OPERATOR
509 #ifdef DIVISION_OPERATOR
515 #ifdef DOUBLE_MULT_OPERATOR
516 .def(
self *
double())
517 .def(
double() *
self)
519 #ifdef DOUBLE_DIV_OPERATOR
520 .def(
self /
double())
522 #ifdef UNARY_NEG_OPERATOR
528 #define WRITE(z, n, data) HBOOST_PP_COMMA_IF(n) data
529 #define VtCat_DEF(z, n, unused) \
530 def("Cat",(VtArray<Type> (*)( HBOOST_PP_REPEAT(n, WRITE, VtArray<Type> const &) ))VtCat<Type>);
544 implicitly_convertible<This, TfSpan<Type> >();
545 implicitly_convertible<This, TfSpan<const Type> >();
549 template <
typename T>
552 using namespace Vt_WrapArray;
555 typedef typename This::ElementType
Type;
557 def(
"AnyTrue", VtAnyTrue<Type>);
558 def(
"AllTrue", VtAllTrue<Type>);
566 template <
class Array>
570 typedef typename Array::ElementType ElemType;
572 if (PySequence_Check(obj.ptr())) {
573 Py_ssize_t len = PySequence_Length(obj.ptr());
575 ElemType *elem = result.data();
576 for (Py_ssize_t i = 0; i != len; ++i) {
577 hboost::python::handle<>
h(PySequence_ITEM(obj.ptr(), i));
579 if (PyErr_Occurred())
583 hboost::python::extract<ElemType> e(h.get());
589 }
else if (PyIter_Check(obj.ptr())) {
591 while (PyObject *item = PyIter_Next(obj.ptr())) {
592 hboost::python::handle<>
h(item);
594 if (PyErr_Occurred())
598 hboost::python::extract<ElemType> e(h.get());
601 result.push_back(e());
608 template <
class Array,
class Iter>
612 typedef typename Array::ElementType ElemType;
614 for (ElemType *e = result.data(); begin !=
end; ++
begin) {
615 VtValue cast = VtValue::Cast<ElemType>(*begin);
631 }
else if (v.
IsHolding<std::vector<VtValue> >()) {
632 std::vector<VtValue>
const &vec = v.
UncheckedGet<std::vector<VtValue> >();
633 ret = Vt_ConvertFromRange<T>(vec.begin(), vec.end());
639 template <
class Elem>
643 VtValue::RegisterCast<TfPyObjWrapper, Array>(Vt_CastToArray<Array>);
644 VtValue::RegisterCast<std::vector<VtValue>, Array>(Vt_CastToArray<Array>);
647 #define VT_WRAP_ARRAY(r, unused, elem) \
648 VtWrapArray< VtArray< VT_TYPE(elem) > >();
649 #define VT_WRAP_COMPARISON(r, unused, elem) \
650 VtWrapComparisonFunctions< VtArray< VT_TYPE(elem) > >();
654 #endif // PXR_BASE_VT_WRAP_ARRAY_H
TF_API std::string TfStringPrintf(const char *fmt,...)
#define VTOPERATOR_WRAPDECLARE(op, lmethod, rmethod)
#define VTOPERATOR_WRAPDECLARE_BOOL(func)
T const & UncheckedGet() const &
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
GLsizei const GLchar *const * string
GLsizei const GLfloat * value
#define VTOPERATOR_WRAP_BOOL(func, op)
ARCH_API std::string ArchGetDemangled(const std::string &typeName)
GLuint GLsizei GLsizei * length
#define VT_FUNCTIONS_MAX_ARGS
unsigned int GetRank() const
string __repr__(VtArray< T > const &self)
#define ARCH_PRAGMA_UNSAFE_USE_OF_BOOL
VtValue & Swap(VtValue &rhs) noexcept
Swap this with rhs.
TF_API void TfPyThrowValueError(const char *msg)
**But if you need a result
bool IsEmpty() const
Returns true iff this value is empty.
object getitem_index(VtArray< T > const &self, int64_t idx)
VtValue Vt_ConvertFromRange(Iter begin, Iter end)
#define MAKE_STREAM_FUNC(r, unused, type)
VtValue Vt_CastToArray(VtValue const &v)
std::string TfPyRepr(T const &t)
OIIO_FORCEINLINE bool extract(const vbool4 &a)
bool lexical_cast(const std::string &input, T &output)
Integer conversion.
void setitem_slice(VtArray< T > &self, slice idx, object value)
object getitem_slice(VtArray< T > const &self, slice idx)
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER class IMF_EXPORT_TEMPLATE_TYPE Array
#define _OPTIMIZED_STREAM_INTEGRAL_TYPES
VtArray< T > * VtArray__init__(object const &values)
void setArraySlice(VtArray< T > &self, S value, slice::range< T * > &range, size_t setSize, bool tile=false)
void setitem_ellipsis(VtArray< T > &self, object idx, object value)
GLuint const GLchar * name
VT_API string GetVtArrayName()
#define ARCH_PRAGMA_UNARY_MINUS_ON_UNSIGNED
void VtRegisterValueCastsFromPythonSequencesToArray()
Register casts with VtValue from python sequences to VtArray types.
#define VT_FLOATING_POINT_BUILTIN_VALUE_TYPES
VtArray< T > * VtArray__init__2(size_t size, object const &values)
GLfloat GLfloat GLfloat GLfloat h
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
unsigned int otherDims[NumOtherDims]
GLenum GLsizei GLsizei GLint * values
VtValue Vt_ConvertFromPySequenceOrIter(TfPyObjWrapper const &obj)
void VtWrapComparisonFunctions()
object getitem_ellipsis(VtArray< T > const &self, object idx)
void setitem_index(VtArray< T > &self, int64_t idx, object value)
size_t *lastDimSize unsigned int rank
#define PXR_NAMESPACE_CLOSE_SCOPE
TF_API int64_t TfPyNormalizeIndex(int64_t index, uint64_t size, bool throwError=false)
bool accumulate(const PointDataTreeT &points, const std::string &attribute, typename PromoteType< ValueT >::Highest &total, const FilterT &filter, typename PointDataTreeT::template ValueConverter< ResultTreeT >::Type *totalTree)
Evaluates the total value of a point attribute and returns whether the value is valid. Optionally constructs localised total value trees.
#define TF_PY_REPR_PREFIX
SIM_API const UT_StringHolder distance
#define VtCat_DEF(z, n, unused)
#define VTOPERATOR_WRAP(lmethod, rmethod)
#define VTOPERATOR_WRAP_NONCOMM(lmethod, rmethod)
HBOOST_PP_SEQ_FOR_EACH(MAKE_STREAM_FUNC,~, VT_FLOATING_POINT_BUILTIN_VALUE_TYPES) static unsigned int Vt_ComputeEffectiveRankAndLastDimSize(Vt_ShapeData const *sd
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.