Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
10.6.x.x (relative to 10.6.2.1)
========

API
---

- IECorePython : Added `Buffer` object and associated `asReadOnlyBuffer()` and `asReadWriteBuffer()` methods for numeric-based `*VectorData` types. This adds support for Python's buffer protocol which allows direct access to the vector.

10.6.2.1 (relative to 10.6.2.0)
========
Expand Down
5 changes: 4 additions & 1 deletion SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,13 @@ o.Add(
# https://developercommunity.visualstudio.com/content/problem/756694/including-windowsh-and-boostinterprocess-headers-l.html
# /DBOOST_ALL_NO_LIB is needed to find Boost when it is built without
# verbose system information added to file and directory names.
# /DZc:strictStrings- fixes a compilation error when setting the `Py_buffer.format` member in `VectorTypedDataBinding.inl`
# `getBuffer()` method. Python declares that member as `char *` but MSVC requires `const char *` for string literals.
# Disabling strict strings relaxes that requirement.
o.Add(
"CXXFLAGS",
"The extra flags to pass to the C++ compiler during compilation.",
[ "-pipe", "-Wall", "-Wextra", "-Wsuggest-override" ] if Environment()["PLATFORM"] != "win32" else [ "/permissive-", "/D_USE_MATH_DEFINES", "/Zc:externC-", "/DBOOST_ALL_NO_LIB" ],
[ "-pipe", "-Wall", "-Wextra", "-Wsuggest-override" ] if Environment()["PLATFORM"] != "win32" else [ "/permissive-", "/D_USE_MATH_DEFINES", "/Zc:externC-", "/DBOOST_ALL_NO_LIB", "/Zc:strictStrings-" ],
)

o.Add(
Expand Down
16 changes: 16 additions & 0 deletions include/IECore/DataAlgo.inl
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ typename std::invoke_result_t<F, Data *, Args&&...> dispatch( Data *data, F &&fu
return functor( static_cast<V3fVectorData *>( data ), std::forward<Args>( args )... );
case V3dVectorDataTypeId :
return functor( static_cast<V3dVectorData *>( data ), std::forward<Args>( args )... );
case Box2iVectorDataTypeId :
return functor( static_cast<Box2iVectorData *>( data ), std::forward<Args>( args )... );
case Box2fVectorDataTypeId :
return functor( static_cast<Box2fVectorData *>( data ), std::forward<Args>( args )... );
case Box2dVectorDataTypeId :
return functor( static_cast<Box2dVectorData *>( data ), std::forward<Args>( args )... );
case Box3iVectorDataTypeId :
return functor( static_cast<Box3iVectorData *>( data ), std::forward<Args>( args )... );
case Box3fVectorDataTypeId :
return functor( static_cast<Box3fVectorData *>( data ), std::forward<Args>( args )... );
case Box3dVectorDataTypeId :
Expand Down Expand Up @@ -328,6 +336,14 @@ typename std::invoke_result_t<F, const Data *, Args&&...> dispatch( const Data *
return functor( static_cast<const V3fVectorData *>( data ), std::forward<Args>( args )... );
case V3dVectorDataTypeId :
return functor( static_cast<const V3dVectorData *>( data ), std::forward<Args>( args )... );
case Box2iVectorDataTypeId :
return functor( static_cast<const Box2iVectorData *>( data ), std::forward<Args>( args )... );
case Box2fVectorDataTypeId :
return functor( static_cast<const Box2fVectorData *>( data ), std::forward<Args>( args )... );
case Box2dVectorDataTypeId :
return functor( static_cast<const Box2dVectorData *>( data ), std::forward<Args>( args )... );
case Box3iVectorDataTypeId :
return functor( static_cast<const Box3iVectorData *>( data ), std::forward<Args>( args )... );
case Box3fVectorDataTypeId :
return functor( static_cast<const Box3fVectorData *>( data ), std::forward<Args>( args )... );
case Box3dVectorDataTypeId :
Expand Down
1 change: 1 addition & 0 deletions include/IECorePython/GeometricTypedDataBinding.inl
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ class GeometricVectorTypedDataFunctions : ThisBinder
"\nor any other python built-in type that is convertible to it. Alternatively accepts the size of the new vector.") \
.def("getInterpretation", &ThisClass::getInterpretation, "Returns the geometric interpretation of this data.") \
.def("setInterpretation", &ThisClass::setInterpretation, "Sets the geometric interpretation of this data.") \
BIND_BUFFER_PROTOCOL_METHODS \
; \
} \

Expand Down
27 changes: 27 additions & 0 deletions include/IECorePython/VectorTypedDataBinding.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,35 @@

#include "IECorePython/Export.h"

#include "IECore/Data.h"
#include "IECore/RefCounted.h"


namespace IECorePython
{

class Buffer : public IECore::RefCounted
{
public :
IE_CORE_DECLAREMEMBERPTR( Buffer );

Buffer( IECore::Data *data, const bool writable );
~Buffer() override;

IECore::DataPtr asData() const;

bool isWritable() const;

static int getBuffer( PyObject *object, Py_buffer *view, int flags );
static void releaseBuffer( PyObject *object, Py_buffer *view );

private :
IECore::DataPtr m_data;
const bool m_writable;
};

IE_CORE_DECLAREPTR( Buffer )

extern IECOREPYTHON_API void bindAllVectorTypedData();
}

Expand Down
26 changes: 25 additions & 1 deletion include/IECorePython/VectorTypedDataBinding.inl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#include "IECorePython/IECoreBinding.h"
#include "IECorePython/RunTimeTypedBinding.h"
#include "IECorePython/VectorTypedDataBinding.h"

#include "boost/numeric/conversion/cast.hpp"
#include "boost/python/suite/indexing/container_utils.hpp"
Expand Down Expand Up @@ -541,6 +542,21 @@ class VectorTypedDataFunctions
);
}

static bool dataSourceEqual( ThisClass &x, ThisClass &y )
{
return &x.readable() == &y.readable();
}

static IECorePython::BufferPtr asReadOnlyBuffer( ThisClass &x )
{
return new Buffer( &x, /* writable = */ false );
}

static IECorePython::BufferPtr asReadWriteBuffer( ThisClass &x )
{
return new Buffer( &x, /* writable = */ true );
}


protected:
/*
Expand Down Expand Up @@ -695,7 +711,7 @@ std::string str<IECore::TypedData<std::vector<TYPE> > >( IECore::TypedData<std::
#define BASIC_VECTOR_BINDING(ThisClass, Tname) \
typedef VectorTypedDataFunctions< ThisClass > ThisBinder; \
\
RunTimeTypedClass<ThisClass>( \
RunTimeTypedClass<ThisClass>( \
Tname "-type vector class derived from Data class.\n" \
"This class behaves like the native python lists, except that it only accepts " Tname " values.\n" \
"The copy constructor accepts another instance of this class or a python list containing " Tname \
Expand Down Expand Up @@ -725,6 +741,7 @@ std::string str<IECore::TypedData<std::vector<TYPE> > >( IECore::TypedData<std::
.def("resize", &ThisBinder::resize, "s.resize( size )\nAdjusts the size of s.") \
.def("resize", &ThisBinder::resizeWithValue, "s.resize( size, value )\nAdjusts the size of s, inserting elements of value as necessary.") \
.def("hasBase", &ThisClass::hasBase ).staticmethod( "hasBase" ) \
.def("_dataSourceEqual", &ThisBinder::dataSourceEqual, "Returns true if the given object points to the same source data as this object.") \
.def("__str__", &str<ThisClass> ) \
.def("__repr__", &repr<ThisClass> ) \

Expand All @@ -736,6 +753,10 @@ std::string str<IECore::TypedData<std::vector<TYPE> > >( IECore::TypedData<std::
; \
}

#define BIND_BUFFER_PROTOCOL_METHODS \
.def("asReadOnlyBuffer", &ThisBinder::asReadOnlyBuffer, "Returns a read-only Buffer object that can be passed to Python objects that support the buffer protocol." ) \
.def("asReadWriteBuffer", &ThisBinder::asReadWriteBuffer, "Returns a writable Buffer object that can be passed to Python objects that support the buffer protocol." ) \

// bind a VectorTypedData class that supports simple Math operators (+=, -= and *=)
#define BIND_SIMPLE_OPERATED_VECTOR_TYPEDDATA(T, Tname) \
{ \
Expand All @@ -749,6 +770,7 @@ std::string str<IECore::TypedData<std::vector<TYPE> > >( IECore::TypedData<std::
.def("__imul__", &ThisBinder::imul, "inplace multiplication (s *= v) : accepts another vector of the same type or a single " Tname) \
.def("__cmp__", &ThisBinder::invalidOperator, "Raises an exception. This vector type does not support comparison operators.") \
.def("toString", &ThisBinder::toString, "Returns a string with a copy of the bytes in the vector.")\
BIND_BUFFER_PROTOCOL_METHODS \
; \
}

Expand All @@ -769,6 +791,7 @@ std::string str<IECore::TypedData<std::vector<TYPE> > >( IECore::TypedData<std::
.def("__itruediv__", &ThisBinder::idiv, "inplace division (s /= v) : accepts another vector of the same type or a single " Tname) \
.def("__cmp__", &ThisBinder::invalidOperator, "Raises an exception. This vector type does not support comparison operators.") \
.def("toString", &ThisBinder::toString, "Returns a string with a copy of the bytes in the vector.")\
BIND_BUFFER_PROTOCOL_METHODS \
; \
}

Expand All @@ -793,6 +816,7 @@ std::string str<IECore::TypedData<std::vector<TYPE> > >( IECore::TypedData<std::
.def("__gt__", &ThisBinder::gt, "The comparison is element-wise, like a string comparison. \n") \
.def("__ge__", &ThisBinder::ge, "The comparison is element-wise, like a string comparison. \n") \
.def("toString", &ThisBinder::toString, "Returns a string with a copy of the bytes in the vector.")\
BIND_BUFFER_PROTOCOL_METHODS \
; \
}

Expand Down
20 changes: 14 additions & 6 deletions src/IECorePython/ImathBoxVectorBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,22 @@ IECOREPYTHON_DEFINEVECTORDATASTRSPECIALISATION( Box3i )
IECOREPYTHON_DEFINEVECTORDATASTRSPECIALISATION( Box3f )
IECOREPYTHON_DEFINEVECTORDATASTRSPECIALISATION( Box3d )

#define BIND_BOX_VECTOR_TYPEDDATA(T, Tname) \
{ \
BASIC_VECTOR_BINDING(IECore::TypedData< std::vector< T > >, Tname) \
.def("__cmp__", &ThisBinder::invalidOperator, "Raises an exception. This vector type does not support comparison operators.") \
BIND_BUFFER_PROTOCOL_METHODS \
; \
}

void bindImathBoxVectorTypedData()
{
BIND_VECTOR_TYPEDDATA ( Box< V2i >, "Box2i")
BIND_VECTOR_TYPEDDATA ( Box< V2f >, "Box2f")
BIND_VECTOR_TYPEDDATA ( Box< V2d >, "Box2d")
BIND_VECTOR_TYPEDDATA ( Box< V3i >, "Box3i")
BIND_VECTOR_TYPEDDATA ( Box< V3f >, "Box3f")
BIND_VECTOR_TYPEDDATA ( Box< V3d >, "Box3d")
BIND_BOX_VECTOR_TYPEDDATA ( Box< V2i >, "Box2i")
BIND_BOX_VECTOR_TYPEDDATA ( Box< V2f >, "Box2f")
BIND_BOX_VECTOR_TYPEDDATA ( Box< V2d >, "Box2d")
BIND_BOX_VECTOR_TYPEDDATA ( Box< V3i >, "Box3i")
BIND_BOX_VECTOR_TYPEDDATA ( Box< V3f >, "Box3f")
BIND_BOX_VECTOR_TYPEDDATA ( Box< V3d >, "Box3d")
}

} // namespace IECorePython
Loading
Loading