/* License: Apache 2.0. See LICENSE file in root directory. Copyright(c) 2017 Intel Corporation. All Rights Reserved. */ #pragma once #include #define NAME pyrealsense2 #define SNAME "pyrealsense2" // For rs2_format #include "../include/librealsense2/h/rs_sensor.h" // Hacky little bit of half-functions to make .def(BIND_DOWNCAST) look nice for binding as/is functions #define BIND_DOWNCAST(class, downcast) "is_"#downcast, &rs2::class::is).def("as_"#downcast, &rs2::class::as // Binding enums const std::string rs2_prefix{ "rs2_" }; std::string make_pythonic_str(std::string str); #define BIND_ENUM(module, rs2_enum_type, RS2_ENUM_COUNT, docstring) BIND_ENUM_CUSTOM( module, rs2_enum_type, 0, RS2_ENUM_COUNT-1, docstring) #define BIND_ENUM_CUSTOM(module, rs2_enum_type, FIRST, LAST, docstring) \ static std::string rs2_enum_type##pyclass_name = std::string(#rs2_enum_type).substr(rs2_prefix.length()); \ /* Above 'static' is required in order to keep the string alive since py::class_ does not copy it */ \ py::enum_ py_##rs2_enum_type(module, rs2_enum_type##pyclass_name.c_str(), docstring); \ /* std::cout << std::endl << "## " << rs2_enum_type##pyclass_name << ":" << std::endl; */ \ for (int i = FIRST; i <= LAST; i++) \ { \ rs2_enum_type v = static_cast(i); \ const char* enum_name = rs2_enum_type##_to_string(v); \ auto python_name = make_pythonic_str(enum_name); \ py_##rs2_enum_type.value(python_name.c_str(), v); \ /* std::cout << " - " << python_name << std::endl; */ \ } // Binding arrays and matrices template void copy_raw_array(T(&dst)[SIZE], const std::array& src) { for (size_t i = 0; i < SIZE; i++) { dst[i] = src[i]; } } template void copy_raw_2d_array(T(&dst)[NROWS][NCOLS], const std::array, NROWS>& src) { for (size_t i = 0; i < NROWS; i++) { for (size_t j = 0; j < NCOLS; j++) { dst[i][j] = src[i][j]; } } } template std::string array_to_string(const T(&arr)[N]) { std::ostringstream oss; oss << "["; for (int i = 0; i < N; i++) { if (i != 0) oss << ", "; oss << arr[i]; } oss << "]"; return oss.str(); } template std::string matrix_to_string(const T(&arr)[N][M]) { std::ostringstream oss; oss << "["; for (int i = 0; i < N; i++) { if (i != 0) oss << ", "; oss << "["; for (int j = 0; j < M; j++) { if (j != 0) oss << ", "; oss << arr[i][j]; } oss << "]"; } oss << "]"; return oss.str(); } #define BIND_RAW_ARRAY_GETTER(T, member, valueT, SIZE) [](const T& self) -> const std::array& { return reinterpret_cast&>(self.member); } #define BIND_RAW_ARRAY_SETTER(T, member, valueT, SIZE) [](T& self, const std::array& src) { copy_raw_array(self.member, src); } #define BIND_RAW_2D_ARRAY_GETTER(T, member, valueT, NROWS, NCOLS) [](const T& self) -> const std::array, NROWS>& { return reinterpret_cast, NROWS>&>(self.member); } #define BIND_RAW_2D_ARRAY_SETTER(T, member, valueT, NROWS, NCOLS) [](T& self, const std::array, NROWS>& src) { copy_raw_2d_array(self.member, src); } #define BIND_RAW_ARRAY_PROPERTY(T, member, valueT, SIZE) #member, BIND_RAW_ARRAY_GETTER(T, member, valueT, SIZE), BIND_RAW_ARRAY_SETTER(T, member, valueT, SIZE) #define BIND_RAW_2D_ARRAY_PROPERTY(T, member, valueT, NROWS, NCOLS) #member, BIND_RAW_2D_ARRAY_GETTER(T, member, valueT, NROWS, NCOLS), BIND_RAW_2D_ARRAY_SETTER(T, member, valueT, NROWS, NCOLS) // TODO: Fill in missing formats // Map format->data type for various things template struct FmtToType { using type = uint8_t; }; // Default to uint8_t #define MAP_FMT_TO_TYPE(F, T) template <> struct FmtToType { using type = T; } MAP_FMT_TO_TYPE(RS2_FORMAT_Z16, uint16_t); //MAP_FMT_TO_TYPE(RS2_FORMAT_DISPARITY16, ); MAP_FMT_TO_TYPE(RS2_FORMAT_XYZ32F, float); MAP_FMT_TO_TYPE(RS2_FORMAT_YUYV, uint8_t); MAP_FMT_TO_TYPE(RS2_FORMAT_RGB8, uint8_t); MAP_FMT_TO_TYPE(RS2_FORMAT_BGR8, uint8_t); MAP_FMT_TO_TYPE(RS2_FORMAT_RGBA8, uint8_t); MAP_FMT_TO_TYPE(RS2_FORMAT_BGRA8, uint8_t); MAP_FMT_TO_TYPE(RS2_FORMAT_Y8, uint8_t); MAP_FMT_TO_TYPE(RS2_FORMAT_Y16, uint16_t); //MAP_FMT_TO_TYPE(RS2_FORMAT_RAW10, ); MAP_FMT_TO_TYPE(RS2_FORMAT_RAW16, uint16_t); MAP_FMT_TO_TYPE(RS2_FORMAT_RAW8, uint8_t); MAP_FMT_TO_TYPE(RS2_FORMAT_UYVY, uint8_t); //MAP_FMT_TO_TYPE(RS2_FORMAT_MOTION_RAW, ); MAP_FMT_TO_TYPE(RS2_FORMAT_MOTION_XYZ32F, float); //MAP_FMT_TO_TYPE(RS2_FORMAT_GPIO_RAW, ); //MAP_FMT_TO_TYPE(RS2_FORMAT_6DOF, ); MAP_FMT_TO_TYPE(RS2_FORMAT_DISPARITY32, float); MAP_FMT_TO_TYPE(RS2_FORMAT_Y10BPACK, uint8_t); MAP_FMT_TO_TYPE(RS2_FORMAT_DISTANCE, float); //MAP_FMT_TO_TYPE(RS2_FORMAT_MJPEG, ); MAP_FMT_TO_TYPE(RS2_FORMAT_Y8I, uint8_t); //MAP_FMT_TO_TYPE(RS2_FORMAT_Y12I, ); //MAP_FMT_TO_TYPE(RS2_FORMAT_INZI, ); MAP_FMT_TO_TYPE(RS2_FORMAT_INVI, uint8_t); //MAP_FMT_TO_TYPE(RS2_FORMAT_W10, ); MAP_FMT_TO_TYPE(RS2_FORMAT_FG, uint16_t); //MAP_FMT_TO_TYPE(RS2_FORMAT_Y411, ); // RS2_FORMAT_Y411 is 12 bit per pixel and don't fit to any type template struct itemsize { static constexpr size_t func() { return sizeof(typename FmtToType::type); } }; template struct fmtstring { static const std::string func() { return py::format_descriptor::type>::format(); } }; template class F> /*constexpr*/ auto fmt_to_value(rs2_format fmt) -> typename std::result_of::func)()>::type { switch (fmt) { case RS2_FORMAT_Z16: return F::func(); case RS2_FORMAT_DISPARITY16: return F::func(); case RS2_FORMAT_XYZ32F: return F::func(); case RS2_FORMAT_YUYV: return F::func(); case RS2_FORMAT_RGB8: return F::func(); case RS2_FORMAT_BGR8: return F::func(); case RS2_FORMAT_RGBA8: return F::func(); case RS2_FORMAT_BGRA8: return F::func(); case RS2_FORMAT_Y8: return F::func(); case RS2_FORMAT_Y16: return F::func(); case RS2_FORMAT_RAW10: return F::func(); case RS2_FORMAT_RAW16: return F::func(); case RS2_FORMAT_RAW8: return F::func(); case RS2_FORMAT_UYVY: return F::func(); case RS2_FORMAT_MOTION_RAW: return F::func(); case RS2_FORMAT_MOTION_XYZ32F: return F::func(); case RS2_FORMAT_GPIO_RAW: return F::func(); case RS2_FORMAT_6DOF: return F::func(); case RS2_FORMAT_DISPARITY32: return F::func(); case RS2_FORMAT_Y10BPACK: return F::func(); case RS2_FORMAT_DISTANCE: return F::func(); case RS2_FORMAT_MJPEG: return F::func(); case RS2_FORMAT_Y8I: return F::func(); case RS2_FORMAT_Y12I: return F::func(); case RS2_FORMAT_INZI: return F::func(); case RS2_FORMAT_INVI: return F::func(); case RS2_FORMAT_W10: return F::func(); case RS2_FORMAT_FG: return F::func(); case RS2_FORMAT_Y411: return F::func(); // c++11 standard doesn't allow throw in constexpr function switch case case RS2_FORMAT_COUNT: throw std::runtime_error("format.count is not a valid value for arguments of type format!"); default: return F::func(); } } // Support Python's buffer protocol class BufData { public: void *_ptr = nullptr; // Pointer to the underlying storage size_t _itemsize = 0; // Size of individual items in bytes std::string _format; // For homogeneous buffers, this should be set to format_descriptor::format() size_t _ndim = 0; // Number of dimensions std::vector _shape; // Shape of the tensor (1 entry per dimension) std::vector _strides; // Number of entries between adjacent entries (for each per dimension) public: BufData(void *ptr, size_t itemsize, const std::string& format, size_t ndim, const std::vector &shape, const std::vector &strides) : _ptr(ptr), _itemsize(itemsize), _format(format), _ndim(ndim), _shape(shape), _strides(strides) {} BufData(void *ptr, size_t itemsize, const std::string& format, size_t size) : BufData(ptr, itemsize, format, 1, std::vector { size }, std::vector { itemsize }) { } BufData(void *ptr, // Raw data pointer size_t itemsize, // Size of the type in bytes const std::string& format, // Data type's format descriptor (e.g. "@f" for float xyz) size_t dim, // number of data elements per group (e.g. 3 for float xyz) size_t count) // Number of groups : BufData(ptr, itemsize, format, 2, std::vector { count, dim }, std::vector { itemsize*dim, itemsize }) { } }; /*PYBIND11_MAKE_OPAQUE(std::vector)*/ // Partial module definition functions void init_c_files(py::module &m); void init_types(py::module &m); void init_frame(py::module &m); void init_options(py::module &m); void init_processing(py::module &m); void init_sensor(py::module &m); void init_device(py::module &m); void init_record_playback(py::module &m); void init_context(py::module &m); void init_pipeline(py::module &m); void init_internal(py::module &m); void init_export(py::module &m); void init_advanced_mode(py::module &m); void init_serializable_device(py::module& m); void init_util(py::module &m);