7 #ifndef PXR_BASE_VT_WRAP_ARRAY_H
8 #define PXR_BASE_VT_WRAP_ARRAY_H
12 #include "pxr/base/vt/array.h"
35 #include "pxr/external/boost/python/class.hpp"
36 #include "pxr/external/boost/python/copy_const_reference.hpp"
37 #include "pxr/external/boost/python/def.hpp"
38 #include "pxr/external/boost/python/detail/api_placeholder.hpp"
39 #include "pxr/external/boost/python/extract.hpp"
40 #include "pxr/external/boost/python/implicit.hpp"
41 #include "pxr/external/boost/python/iterator.hpp"
42 #include "pxr/external/boost/python/make_constructor.hpp"
43 #include "pxr/external/boost/python/object.hpp"
44 #include "pxr/external/boost/python/operators.hpp"
45 #include "pxr/external/boost/python/return_arg.hpp"
46 #include "pxr/external/boost/python/slice.hpp"
47 #include "pxr/external/boost/python/type_id.hpp"
48 #include "pxr/external/boost/python/overloads.hpp"
59 namespace Vt_WrapArray {
61 using namespace pxr_boost::python;
63 using std::unique_ptr;
71 object ellipsis =
object(handle<>(borrowed(Py_Ellipsis)));
72 if (idx != ellipsis) {
73 PyErr_SetString(PyExc_TypeError,
"unsupported index type");
74 throw_error_already_set();
83 static const bool throwError =
true;
93 slice::range<typename VtArray<T>::const_iterator>
range =
94 idx.get_indices(
self.
begin(),
self.
end());
95 const size_t setSize = 1 + (range.stop - range.start) / range.step;
98 for (; range.start != range.stop; range.start += range.step, ++i) {
104 catch (std::invalid_argument
const &) {
109 template <
typename T,
typename S>
112 slice::range<T*>&
range,
size_t setSize,
bool tile =
false)
115 const size_t length = len(value);
118 if (!tile && length < setSize) {
120 (
"Not enough values to set slice. Expected %zu, got %zu.",
127 std::vector<T> extracted;
128 extract<std::vector<T> > vectorExtraction(value);
129 if (vectorExtraction.check()) {
130 std::vector<T> tmp = vectorExtraction();
134 extracted.reserve(length);
135 for (
size_t i = 0; i !=
length; ++i) {
136 extracted.push_back(extract<T>(value[i]));
142 if (range.step == 1 && length >= setSize) {
143 std::copy(extracted.begin(), extracted.begin() + setSize, range.start);
146 for (
size_t i = 0; i != setSize; range.start += range.step, ++i) {
147 *range.start = extracted[i %
length];
152 template <
typename T>
157 slice::range<T*>
range;
159 T*
data =
self.data();
160 range = idx.get_indices(data, data +
self.
size());
162 catch (std::invalid_argument
const &) {
168 const size_t setSize = 1 + (range.stop - range.start) / range.step;
177 const size_t length = val.size();
180 if (!tile && length < setSize) {
182 (
"Not enough values to set slice. Expected %zu, got %zu.",
188 for (
size_t i = 0; i != setSize; range.start += range.step, ++i) {
189 *range.start = val[i %
length];
194 else if (extract<T>(value).check()) {
202 for (
size_t i = 0; i != setSize; range.start += range.step, ++i) {
208 else if (extract<list>(value).check()) {
209 setArraySlice(
self, extract<list>(value)(), range, setSize, tile);
213 else if (extract<tuple>(value).check()) {
214 setArraySlice(
self, extract<tuple>(value)(), range, setSize, tile);
224 template <
typename T>
228 object ellipsis =
object(handle<>(borrowed(Py_Ellipsis)));
229 if (idx != ellipsis) {
230 PyErr_SetString(PyExc_TypeError,
"unsupported index type");
231 throw_error_already_set();
236 template <
typename T>
244 template <
typename T>
255 template <
class T,
class... Ts>
257 return (std::is_same_v<T, Ts> || ...);
260 template <
class T,
class TypeList>
262 return Vt_IsAnySameImpl<T>(TypeList{});
271 long long,
unsigned long long>;
277 template <
typename T>
279 return std::isfinite(value);
282 return std::isfinite(static_cast<float>(value));
285 template <
typename T>
286 static void streamValue(std::ostringstream &
stream, T
const &
value) {
289 if constexpr(Vt_IsAnySame<T, Vt_OptimizedStreamIntegralTypes>()) {
311 template <
typename T>
318 std::ostringstream
stream;
319 stream.precision(17);
321 for (
size_t i = 0; i <
self.size(); ++i) {
322 stream << (i ?
", " :
"");
323 streamValue(stream,
self[i]);
325 stream << (
self.size() == 1 ?
",)" :
")");
330 self.
size(), stream.str().c_str());
340 size_t lastDimSize = 0;
344 std::string shapeStr =
"(";
345 for (
size_t i = 0; i != rank-1; ++i) {
347 i ?
", %d" :
"%d", shapeData->otherDims[i]);
351 repr.c_str(), shapeStr.c_str());
357 template <
typename T>
361 unique_ptr<VtArray<T> > ret(
new VtArray<T>(len(values)));
365 static const bool tile =
true;
367 return ret.release();
369 template <
typename T>
373 unique_ptr<VtArray<T> > ret(
new VtArray<T>(size));
377 static const bool tile =
true;
380 return ret.release();
398 template <typename T>
399 static std::
string _VtStr(T const &self)
404 template <
typename T>
407 using namespace Vt_WrapArray;
410 typedef typename This::ElementType
Type;
412 string name = GetVtArrayName<This>();
414 string docStr =
TfStringPrintf(
"An array of type %s.", typeStr.c_str());
416 auto selfCls = class_<This>(
name.c_str(), docStr.c_str(), no_init)
417 .setattr(
"_isVtArray",
true)
420 .def(
"__init__", make_constructor(VtArray__init__<Type>),
422 "__init__(values)\n\n"
423 "values: a sequence (tuple, list, or another VtArray with "
424 "element type convertible to the new array's element type)\n\n"
426 .def(
"__init__", make_constructor(VtArray__init__2<Type>))
427 .def(init<unsigned int>())
429 .def(
"__getitem__", getitem_ellipsis<Type>)
430 .def(
"__getitem__", getitem_slice<Type>)
431 .def(
"__getitem__", getitem_index<Type>)
432 .def(
"__setitem__", setitem_ellipsis<Type>)
433 .def(
"__setitem__", setitem_slice<Type>)
434 .def(
"__setitem__", setitem_index<Type>)
437 .def(
"__iter__", iterator<This>())
439 .def(
"__repr__", __repr__<Type>)
442 .def(
"__str__", _VtStr<T>)
446 #ifdef NUMERIC_OPERATORS
447 #define ADDITION_OPERATOR
448 #define SUBTRACTION_OPERATOR
449 #define MULTIPLICATION_OPERATOR
450 #define DIVISION_OPERATOR
451 #define UNARY_NEG_OPERATOR
454 #ifdef ADDITION_OPERATOR
457 #ifdef SUBTRACTION_OPERATOR
460 #ifdef MULTIPLICATION_OPERATOR
463 #ifdef DIVISION_OPERATOR
469 #ifdef DOUBLE_MULT_OPERATOR
470 .def(
self *
double())
471 .def(
double() *
self)
473 #ifdef DOUBLE_DIV_OPERATOR
474 .def(
self /
double())
476 #ifdef UNARY_NEG_OPERATOR
489 implicitly_convertible<This, TfSpan<Type> >();
490 implicitly_convertible<This, TfSpan<const Type> >();
493 template <
class Array>
497 typedef typename Array::ElementType ElemType;
499 if (PySequence_Check(obj.ptr())) {
500 Py_ssize_t len = PySequence_Length(obj.ptr());
502 ElemType *elem = result.data();
503 for (Py_ssize_t i = 0; i != len; ++i) {
504 pxr_boost::python::handle<>
h(PySequence_ITEM(obj.ptr(), i));
506 if (PyErr_Occurred())
510 pxr_boost::python::extract<ElemType> e(h.get());
516 }
else if (PyIter_Check(obj.ptr())) {
518 while (PyObject *item = PyIter_Next(obj.ptr())) {
519 pxr_boost::python::handle<>
h(item);
521 if (PyErr_Occurred())
525 pxr_boost::python::extract<ElemType> e(h.get());
528 result.push_back(e());
535 template <
class Array,
class Iter>
539 typedef typename Array::ElementType ElemType;
541 for (ElemType *e = result.data(); begin !=
end; ++
begin) {
558 }
else if (v.
IsHolding<std::vector<VtValue> >()) {
559 std::vector<VtValue>
const &vec = v.
UncheckedGet<std::vector<VtValue> >();
560 ret = Vt_ConvertFromRange<T>(vec.begin(), vec.end());
566 template <
class Elem>
570 VtValue::RegisterCast<TfPyObjWrapper, Array>(Vt_CastToArray<Array>);
571 VtValue::RegisterCast<std::vector<VtValue>, Array>(Vt_CastToArray<Array>);
574 #define VT_WRAP_ARRAY(unused, elem) \
575 VtWrapArray< VtArray< VT_TYPE(elem) > >();
579 #endif // PXR_BASE_VT_WRAP_ARRAY_H
TF_API std::string TfStringPrintf(const char *fmt,...)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
#define VTOPERATOR_WRAPDECLARE(op, lmethod, rmethod)
T const & UncheckedGet() const &
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
GLsizei const GLfloat * value
ARCH_API std::string ArchGetDemangled(const std::string &typeName)
GLuint GLsizei GLsizei * length
string __repr__(VtArray< T > const &self)
#define ARCH_PRAGMA_UNSAFE_USE_OF_BOOL
VtValue & Swap(VtValue &rhs) noexcept
Swap this with rhs.
VT_API unsigned int Vt_ComputeEffectiveRankAndLastDimSize(Vt_ShapeData const *sd, size_t *lastDimSize)
TF_API void TfPyThrowValueError(const char *msg)
**But if you need a result
bool IsEmpty() const
Returns true iff this value is empty.
bool _IsFinite(T const &value)
object getitem_index(VtArray< T > const &self, int64_t idx)
VtValue Vt_ConvertFromRange(Iter begin, Iter end)
constexpr bool Vt_IsAnySame()
VtValue Vt_CastToArray(VtValue const &v)
std::string TfPyRepr(T const &t)
OIIO_FORCEINLINE bool extract(const vbool4 &a)
void setitem_slice(VtArray< T > &self, slice idx, object value)
SYS_FORCE_INLINE const X * cast(const InstancablePtr *o)
object getitem_slice(VtArray< T > const &self, slice idx)
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER class IMF_EXPORT_TEMPLATE_TYPE Array
TfMetaList< short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long > Vt_OptimizedStreamIntegralTypes
VtArray< T > * VtArray__init__(object const &values)
std::string TfStringify(const T &v)
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.
VtArray< T > * VtArray__init__2(size_t size, object const &values)
GLfloat GLfloat GLfloat GLfloat h
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
GLenum GLsizei GLsizei GLint * values
VtValue Vt_ConvertFromPySequenceOrIter(TfPyObjWrapper const &obj)
object getitem_ellipsis(VtArray< T > const &self, object idx)
void setitem_index(VtArray< T > &self, int64_t idx, object value)
#define PXR_NAMESPACE_CLOSE_SCOPE
OIIO_UTIL_API const char * c_str(string_view str)
TF_API int64_t TfPyNormalizeIndex(int64_t index, uint64_t size, bool throwError=false)
#define TF_PY_REPR_PREFIX
constexpr bool Vt_IsAnySameImpl(TfMetaList< Ts...>)
SIM_API const UT_StringHolder distance
#define VTOPERATOR_WRAP(lmethod, rmethod)
#define VTOPERATOR_WRAP_NONCOMM(lmethod, rmethod)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.