diff --git a/panda/src/gobj/geomVertexArrayData.cxx b/panda/src/gobj/geomVertexArrayData.cxx index 900cc89f09..c9c32d5483 100644 --- a/panda/src/gobj/geomVertexArrayData.cxx +++ b/panda/src/gobj/geomVertexArrayData.cxx @@ -839,22 +839,12 @@ reserve_num_rows(int n) { void GeomVertexArrayDataHandle:: copy_data_from(const GeomVertexArrayDataHandle *other) { nassertv(_writable); - mark_used(); other->mark_used(); size_t size = other->_cdata->_buffer.get_size(); - _cdata->_buffer.unclean_realloc(size); - _cdata->_buffer.set_size(size); - - unsigned char *dest = _cdata->_buffer.get_write_pointer(); const unsigned char *source = other->_cdata->_buffer.get_read_pointer(true); - memcpy(dest, source, size); - _cdata->_modified = Geom::get_next_modified(); - - if (get_current_thread()->get_pipeline_stage() == 0) { - _object->set_lru_size(_cdata->_buffer.get_size()); - } + copy_data_from(source, size); } //////////////////////////////////////////////////////////////////// @@ -869,20 +859,61 @@ void GeomVertexArrayDataHandle:: copy_subdata_from(size_t to_start, size_t to_size, const GeomVertexArrayDataHandle *other, size_t from_start, size_t from_size) { - nassertv(_writable); - mark_used(); other->mark_used(); - VertexDataBuffer &to_buffer = _cdata->_buffer; - size_t to_buffer_orig_size = to_buffer.get_size(); - to_start = min(to_start, to_buffer_orig_size); - to_size = min(to_size, to_buffer_orig_size - to_start); - const VertexDataBuffer &from_buffer = other->_cdata->_buffer; size_t from_buffer_orig_size = from_buffer.get_size(); from_start = min(from_start, from_buffer_orig_size); from_size = min(from_size, from_buffer_orig_size - from_start); + copy_subdata_from(to_start, to_size, + other->get_read_pointer(true), + from_start, from_size); +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexArrayDataHandle::copy_data_from +// Access: Public +// Description: Copies the entire data array from the buffer. +//////////////////////////////////////////////////////////////////// +void GeomVertexArrayDataHandle:: +copy_data_from(const unsigned char *source, size_t size) { + nassertv(_writable); + mark_used(); + + _cdata->_buffer.unclean_realloc(size); + _cdata->_buffer.set_size(size); + + unsigned char *dest = _cdata->_buffer.get_write_pointer(); + memcpy(dest, source, size); + + _cdata->_modified = Geom::get_next_modified(); + + if (get_current_thread()->get_pipeline_stage() == 0) { + _object->set_lru_size(_cdata->_buffer.get_size()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexArrayDataHandle::copy_subdata_from +// Access: Public +// Description: Copies a portion of the data array from the buffer +// into a portion of the data array of this object. +// If to_size != from_size, the size of this data +// array is adjusted accordingly. +//////////////////////////////////////////////////////////////////// +void GeomVertexArrayDataHandle:: +copy_subdata_from(size_t to_start, size_t to_size, + const unsigned char *source, + size_t from_start, size_t from_size) { + nassertv(_writable); + mark_used(); + + VertexDataBuffer &to_buffer = _cdata->_buffer; + size_t to_buffer_orig_size = to_buffer.get_size(); + to_start = min(to_start, to_buffer_orig_size); + to_size = min(to_size, to_buffer_orig_size - to_start); + if (from_size < to_size) { // Reduce the array. unsigned char *pointer = to_buffer.get_write_pointer(); @@ -909,8 +940,7 @@ copy_subdata_from(size_t to_start, size_t to_size, // Now copy the data. memcpy(to_buffer.get_write_pointer() + to_start, - other->get_read_pointer(true) + from_start, - from_size); + source + from_start, from_size); _cdata->_modified = Geom::get_next_modified(); if (get_current_thread()->get_pipeline_stage() == 0) { diff --git a/panda/src/gobj/geomVertexArrayData.h b/panda/src/gobj/geomVertexArrayData.h index d7682ad979..684336ae92 100644 --- a/panda/src/gobj/geomVertexArrayData.h +++ b/panda/src/gobj/geomVertexArrayData.h @@ -47,7 +47,7 @@ class SimpleAllocatorBlock; // structure. Many GeomVertexData structures will only // define one array, with all data elements interleaved // (DirectX 8.0 and before insisted on this format); -// some will define multiple arrays. +// some will define multiple arrays. // // DirectX calls this concept of one array a "stream". // It also closely correlates with the concept of a @@ -114,9 +114,11 @@ PUBLISHED: static void lru_epoch(); INLINE static VertexDataBook &get_book(); +#if PY_VERSION_HEX >= 0x02060000 EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags)); EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const); EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const); +#endif public: virtual void evict_lru(); @@ -292,6 +294,18 @@ PUBLISHED: const GeomVertexArrayDataHandle *other, size_t from_start, size_t from_size); + void copy_data_from(const unsigned char *source, size_t size); + void copy_subdata_from(size_t to_start, size_t to_size, + const unsigned char *source, + size_t from_start, size_t from_size); + + EXTENSION(void copy_data_from(PyObject *buffer)); + EXTENSION(void copy_subdata_from(size_t to_start, size_t to_size, + PyObject *buffer)); + EXTENSION(void copy_subdata_from(size_t to_start, size_t to_size, + PyObject *buffer, + size_t from_start, size_t from_size)); + INLINE string get_data() const; void set_data(const string &data); INLINE string get_subdata(size_t start, size_t size) const; diff --git a/panda/src/gobj/geomVertexArrayData_ext.cxx b/panda/src/gobj/geomVertexArrayData_ext.cxx index edc95cd0ae..c8310909af 100644 --- a/panda/src/gobj/geomVertexArrayData_ext.cxx +++ b/panda/src/gobj/geomVertexArrayData_ext.cxx @@ -21,6 +21,7 @@ struct InternalBufferData { string _format; }; +#if PY_VERSION_HEX >= 0x02060000 //////////////////////////////////////////////////////////////////// // Function: GeomVertexArrayData::__getbuffer__ // Access: Published @@ -165,3 +166,110 @@ __releasebuffer__(PyObject *self, Py_buffer *view) const { delete data; view->internal = NULL; } + +#endif // PY_VERSION_HEX >= 0x02060000 + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexArrayDataHandle::copy_data_from +// Access: Published +// Description: Copies all data from the given buffer object. +// The array is rescaled as necessary. +//////////////////////////////////////////////////////////////////// +void Extension:: +copy_data_from(PyObject *buffer) { + +#if PY_VERSION_HEX < 0x02060000 + PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6"); + +#else + if (!PyObject_CheckBuffer(buffer)) { + PyErr_SetString(PyExc_TypeError, "buffer object expected"); + return; + } + + Py_buffer view; + if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) { + PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected"); + return; + } + + _this->copy_data_from((const unsigned char *) view.buf, view.len); + + PyBuffer_Release(&view); +#endif +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexArrayDataHandle::copy_subdata_from +// Access: Public +// Description: Copies the entire data array from the buffer +// into a portion of the data array of this object. +// If to_size is not the size of the given buffer, +// the size of this dat array is adjusted accordingly. +//////////////////////////////////////////////////////////////////// +void Extension:: +copy_subdata_from(size_t to_start, size_t to_size, PyObject *buffer) { + +#if PY_VERSION_HEX < 0x02060000 + PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6"); + +#else + if (!PyObject_CheckBuffer(buffer)) { + PyErr_SetString(PyExc_TypeError, "buffer object expected"); + return; + } + + Py_buffer view; + if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) { + PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected"); + return; + } + + _this->copy_subdata_from(to_start, to_size, + (const unsigned char *) view.buf, + 0, (size_t) view.len); + + PyBuffer_Release(&view); +#endif +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexArrayDataHandle::copy_subdata_from +// Access: Public +// Description: Copies a portion of the data array from the buffer +// into a portion of the data array of this object. +// If to_size != from_size, the size of this data +// array is adjusted accordingly. +//////////////////////////////////////////////////////////////////// +void Extension:: +copy_subdata_from(size_t to_start, size_t to_size, + PyObject *buffer, + size_t from_start, size_t from_size) { + +#if PY_VERSION_HEX < 0x02060000 + PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6"); + +#else + if (!PyObject_CheckBuffer(buffer)) { + PyErr_SetString(PyExc_TypeError, "buffer object expected"); + return; + } + + Py_buffer view; + if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) { + PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected"); + return; + } + + size_t from_buffer_orig_size = (size_t) view.len; + from_start = min(from_start, from_buffer_orig_size); + from_size = min(from_size, from_buffer_orig_size - from_start); + + _this->copy_subdata_from(to_start, to_size, + (const unsigned char *) view.buf, + from_start, from_size); + + PyBuffer_Release(&view); +#endif +} + diff --git a/panda/src/gobj/geomVertexArrayData_ext.h b/panda/src/gobj/geomVertexArrayData_ext.h index 826e39ae1f..1814cc5599 100644 --- a/panda/src/gobj/geomVertexArrayData_ext.h +++ b/panda/src/gobj/geomVertexArrayData_ext.h @@ -32,9 +32,28 @@ template<> class Extension : public ExtensionBase { public: +#if PY_VERSION_HEX >= 0x02060000 int __getbuffer__(PyObject *self, Py_buffer *view, int flags); int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const; void __releasebuffer__(PyObject *self, Py_buffer *view) const; +#endif +}; + +//////////////////////////////////////////////////////////////////// +// Class : Extension +// Description : This class defines the extension methods for +// GeomVertexArrayDataHandle, which are called instead +// of any C++ methods with the same prototype. +//////////////////////////////////////////////////////////////////// +template<> +class Extension : public ExtensionBase { +public: + void copy_data_from(PyObject *buffer); + void copy_subdata_from(size_t to_start, size_t to_size, + PyObject *buffer); + void copy_subdata_from(size_t to_start, size_t to_size, + PyObject *buffer, + size_t from_start, size_t from_size); }; #endif // HAVE_PYTHON