Browse Source

add copy_data_from version that takes a Python buffer object

rdb 12 years ago
parent
commit
4a91704958

+ 45 - 15
panda/src/gobj/geomVertexArrayData.cxx

@@ -839,15 +839,52 @@ 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();
+  const unsigned char *source = other->_cdata->_buffer.get_read_pointer(true);
+
+  copy_data_from(source, size);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomVertexArrayDataHandle::copy_subdata_from
+//       Access: Public
+//  Description: Copies a portion of the data array from the other
+//               object 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 GeomVertexArrayDataHandle *other,
+                  size_t from_start, size_t from_size) {
+  other->mark_used();
+
+  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();
-  const unsigned char *source = other->_cdata->_buffer.get_read_pointer(true);
   memcpy(dest, source, size);
 
   _cdata->_modified = Geom::get_next_modified();
@@ -860,29 +897,23 @@ copy_data_from(const GeomVertexArrayDataHandle *other) {
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomVertexArrayDataHandle::copy_subdata_from
 //       Access: Public
-//  Description: Copies a portion of the data array from the other
-//               object into a portion of the data array of this
-//               object.  If to_size != from_size, the size of this
-//               data array is adjusted accordingly.
+//  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 GeomVertexArrayDataHandle *other,
+                  const unsigned char *source,
                   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);
-
   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) {

+ 15 - 1
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;

+ 108 - 0
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<GeomVertexArrayDataHandle>::
+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<GeomVertexArrayDataHandle>::
+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<GeomVertexArrayDataHandle>::
+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
+}
+

+ 19 - 0
panda/src/gobj/geomVertexArrayData_ext.h

@@ -32,9 +32,28 @@
 template<>
 class Extension<GeomVertexArrayData> : public ExtensionBase<GeomVertexArrayData> {
 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<GeomVertexArrayDataHandle>
+// Description : This class defines the extension methods for
+//               GeomVertexArrayDataHandle, which are called instead
+//               of any C++ methods with the same prototype.
+////////////////////////////////////////////////////////////////////
+template<>
+class Extension<GeomVertexArrayDataHandle> : public ExtensionBase<GeomVertexArrayDataHandle> {
+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