Skip to content

Commit

Permalink
Split pybind declarations and definitions (#6869)
Browse files Browse the repository at this point in the history
As explained in #6867 there are several instances where C++ types are shown in the Python binding documentation.
Some of those instances can be solved by splitting the py::_class and py::enum_ declarations from the method/function definitions using .def(...).
This ensures, that all types are properly declared before usage.
---------
Co-authored-by: Sameer Sheorey <[email protected]>
  • Loading branch information
timohl authored Aug 14, 2024
1 parent 7f9377d commit 48ccf2a
Show file tree
Hide file tree
Showing 114 changed files with 3,248 additions and 2,456 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
- Fix build with fmt v10.2.0 (#6783)
- Fix segmentation fault (lambda reference capture) of VisualizerWithCustomAnimation::Play (PR #6804)
- Add O3DVisualizer API to enable collapse control of verts in the side panel (PR #6865)
- Split pybind declarations/definitions to avoid C++ types in Python docs (PR #6869)
- Fix minimal oriented bounding box of MeshBase derived classes and add new unit tests (PR #6898)

## 0.13
Expand Down
97 changes: 52 additions & 45 deletions cpp/pybind/camera/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,48 @@
namespace open3d {
namespace camera {

void pybind_camera_classes(py::module &m) {
// open3d.camera.PinholeCameraIntrinsic
void pybind_camera_declarations(py::module &m) {
py::module m_camera = m.def_submodule("camera");
py::class_<PinholeCameraIntrinsic> pinhole_intr(
m, "PinholeCameraIntrinsic",
m_camera, "PinholeCameraIntrinsic",
"PinholeCameraIntrinsic class stores intrinsic camera matrix, and "
"image height and width.");
// open3d.camera.PinholeCameraIntrinsicParameters
py::enum_<PinholeCameraIntrinsicParameters> pinhole_intr_params(
m_camera, "PinholeCameraIntrinsicParameters", py::arithmetic(),
"PinholeCameraIntrinsicParameters");
pinhole_intr_params
.value("PrimeSenseDefault",
PinholeCameraIntrinsicParameters::PrimeSenseDefault,
"Default camera intrinsic parameter for PrimeSense.")
.value("Kinect2DepthCameraDefault",
PinholeCameraIntrinsicParameters::Kinect2DepthCameraDefault,
"Default camera intrinsic parameter for Kinect2 depth "
"camera.")
.value("Kinect2ColorCameraDefault",
PinholeCameraIntrinsicParameters::Kinect2ColorCameraDefault,
"Default camera intrinsic parameter for Kinect2 color "
"camera.")
.export_values();
pinhole_intr_params.attr("__doc__") = docstring::static_property(
py::cpp_function([](py::handle arg) -> std::string {
return "Enum class that contains default camera intrinsic "
"parameters for different sensors.";
}),
py::none(), py::none(), "");
py::class_<PinholeCameraParameters> pinhole_param(
m_camera, "PinholeCameraParameters",
"Contains both intrinsic and extrinsic pinhole camera parameters.");
py::class_<PinholeCameraTrajectory> pinhole_traj(
m_camera, "PinholeCameraTrajectory",
"Contains a list of ``PinholeCameraParameters``, useful to storing "
"trajectories.");
}
void pybind_camera_definitions(py::module &m) {
auto m_camera = static_cast<py::module>(m.attr("camera"));
// open3d.camera.PinholeCameraIntrinsic
auto pinhole_intr = static_cast<py::class_<PinholeCameraIntrinsic>>(
m_camera.attr("PinholeCameraIntrinsic"));
py::detail::bind_default_constructor<PinholeCameraIntrinsic>(pinhole_intr);
py::detail::bind_copy_functions<PinholeCameraIntrinsic>(pinhole_intr);
pinhole_intr
Expand Down Expand Up @@ -64,50 +100,28 @@ void pybind_camera_classes(py::module &m) {
std::string(
".\nAccess intrinsics with intrinsic_matrix.");
});
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic", "__init__");
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic",
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
"__init__");
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
"set_intrinsics",
{{"width", "Width of the image."},
{"height", "Height of the image."},
{"fx", "X-axis focal length"},
{"fy", "Y-axis focal length."},
{"cx", "X-axis principle point."},
{"cy", "Y-axis principle point."}});
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic",
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
"get_focal_length");
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic",
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
"get_principal_point");
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic", "get_skew");
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic", "is_valid");

// open3d.camera.PinholeCameraIntrinsicParameters
py::enum_<PinholeCameraIntrinsicParameters> pinhole_intr_params(
m, "PinholeCameraIntrinsicParameters", py::arithmetic(),
"PinholeCameraIntrinsicParameters");
pinhole_intr_params
.value("PrimeSenseDefault",
PinholeCameraIntrinsicParameters::PrimeSenseDefault,
"Default camera intrinsic parameter for PrimeSense.")
.value("Kinect2DepthCameraDefault",
PinholeCameraIntrinsicParameters::Kinect2DepthCameraDefault,
"Default camera intrinsic parameter for Kinect2 depth "
"camera.")
.value("Kinect2ColorCameraDefault",
PinholeCameraIntrinsicParameters::Kinect2ColorCameraDefault,
"Default camera intrinsic parameter for Kinect2 color "
"camera.")
.export_values();
pinhole_intr_params.attr("__doc__") = docstring::static_property(
py::cpp_function([](py::handle arg) -> std::string {
return "Enum class that contains default camera intrinsic "
"parameters for different sensors.";
}),
py::none(), py::none(), "");
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
"get_skew");
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
"is_valid");

// open3d.camera.PinholeCameraParameters
py::class_<PinholeCameraParameters> pinhole_param(
m, "PinholeCameraParameters",
"Contains both intrinsic and extrinsic pinhole camera parameters.");
auto pinhole_param = static_cast<py::class_<PinholeCameraParameters>>(
m_camera.attr("PinholeCameraParameters"));
py::detail::bind_default_constructor<PinholeCameraParameters>(
pinhole_param);
py::detail::bind_copy_functions<PinholeCameraParameters>(pinhole_param);
Expand All @@ -125,10 +139,8 @@ void pybind_camera_classes(py::module &m) {
});

// open3d.camera.PinholeCameraTrajectory
py::class_<PinholeCameraTrajectory> pinhole_traj(
m, "PinholeCameraTrajectory",
"Contains a list of ``PinholeCameraParameters``, useful to storing "
"trajectories.");
auto pinhole_traj = static_cast<py::class_<PinholeCameraTrajectory>>(
m_camera.attr("PinholeCameraTrajectory"));
py::detail::bind_default_constructor<PinholeCameraTrajectory>(pinhole_traj);
py::detail::bind_copy_functions<PinholeCameraTrajectory>(pinhole_traj);
pinhole_traj
Expand All @@ -141,10 +153,5 @@ void pybind_camera_classes(py::module &m) {
});
}

void pybind_camera(py::module &m) {
py::module m_submodule = m.def_submodule("camera");
pybind_camera_classes(m_submodule);
}

} // namespace camera
} // namespace open3d
3 changes: 2 additions & 1 deletion cpp/pybind/camera/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
namespace open3d {
namespace camera {

void pybind_camera(py::module &m);
void pybind_camera_declarations(py::module &m);
void pybind_camera_definitions(py::module &m);

} // namespace camera
} // namespace open3d
4 changes: 3 additions & 1 deletion cpp/pybind/core/blob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
namespace open3d {
namespace core {

void pybind_core_blob(py::module &m) { py::class_<Blob> blob(m, "Blob"); }
void pybind_core_blob_declarations(py::module &m) {
py::class_<Blob> blob(m, "Blob");
}

} // namespace core
} // namespace open3d
45 changes: 30 additions & 15 deletions cpp/pybind/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,42 @@
namespace open3d {
namespace core {

void pybind_core(py::module& m) {
void pybind_core_declarations(py::module& m) {
py::module m_core = m.def_submodule("core");

// opn3d::core namespace.
pybind_cuda_utils(m_core);
pybind_sycl_utils(m_core);
pybind_core_blob(m_core);
pybind_core_dtype(m_core);
pybind_core_device(m_core);
pybind_core_size_vector(m_core);
pybind_core_tensor(m_core);
pybind_core_tensor_function(m_core);
pybind_core_linalg(m_core);
pybind_core_kernel(m_core);
pybind_core_hashmap(m_core);
pybind_core_hashset(m_core);
pybind_core_scalar(m_core);
pybind_cuda_utils_declarations(m_core);
pybind_core_blob_declarations(m_core);
pybind_core_dtype_declarations(m_core);
pybind_core_device_declarations(m_core);
pybind_core_size_vector_declarations(m_core);
pybind_core_tensor_declarations(m_core);
pybind_core_kernel_declarations(m_core);
pybind_core_hashmap_declarations(m_core);
pybind_core_hashset_declarations(m_core);
pybind_core_scalar_declarations(m_core);

// opn3d::core::nns namespace.
py::module m_nns = m_core.def_submodule("nns");
nns::pybind_core_nns(m_nns);
nns::pybind_core_nns_declarations(m_nns);
}

void pybind_core_definitions(py::module& m) {
auto m_core = static_cast<py::module>(m.attr("core"));
pybind_cuda_utils_definitions(m_core);
pybind_sycl_utils_definitions(m_core);
pybind_core_dtype_definitions(m_core);
pybind_core_device_definitions(m_core);
pybind_core_size_vector_definitions(m_core);
pybind_core_tensor_definitions(m_core);
pybind_core_tensor_function_definitions(m_core);
pybind_core_linalg_definitions(m_core);
pybind_core_kernel_definitions(m_core);
pybind_core_hashmap_definitions(m_core);
pybind_core_hashset_definitions(m_core);
pybind_core_scalar_definitions(m_core);
auto m_nns = static_cast<py::module>(m_core.attr("nns"));
nns::pybind_core_nns_definitions(m_nns);
}

} // namespace core
Expand Down
39 changes: 25 additions & 14 deletions cpp/pybind/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,32 @@
namespace open3d {
namespace core {

void pybind_core(py::module& m);
void pybind_cuda_utils(py::module& m);
void pybind_sycl_utils(py::module& m);
void pybind_core_blob(py::module& m);
void pybind_core_dtype(py::module& m);
void pybind_core_device(py::module& m);
void pybind_core_size_vector(py::module& m);
void pybind_core_tensor(py::module& m);
void pybind_core_declarations(py::module& m);
void pybind_cuda_utils_declarations(py::module& m);
void pybind_core_blob_declarations(py::module& m);
void pybind_core_dtype_declarations(py::module& m);
void pybind_core_device_declarations(py::module& m);
void pybind_core_size_vector_declarations(py::module& m);
void pybind_core_tensor_declarations(py::module& m);
void pybind_core_tensor_accessor(py::class_<Tensor>& t);
void pybind_core_tensor_function(py::module& m);
void pybind_core_linalg(py::module& m);
void pybind_core_kernel(py::module& m);
void pybind_core_hashmap(py::module& m);
void pybind_core_hashset(py::module& m);
void pybind_core_scalar(py::module& m);
void pybind_core_tensor_function_definitions(py::module& m);
void pybind_core_kernel_declarations(py::module& m);
void pybind_core_hashmap_declarations(py::module& m);
void pybind_core_hashset_declarations(py::module& m);
void pybind_core_scalar_declarations(py::module& m);

void pybind_core_definitions(py::module& m);
void pybind_cuda_utils_definitions(py::module& m);
void pybind_sycl_utils_definitions(py::module& m);
void pybind_core_dtype_definitions(py::module& m);
void pybind_core_device_definitions(py::module& m);
void pybind_core_size_vector_definitions(py::module& m);
void pybind_core_tensor_definitions(py::module& m);
void pybind_core_linalg_definitions(py::module& m);
void pybind_core_kernel_definitions(py::module& m);
void pybind_core_hashmap_definitions(py::module& m);
void pybind_core_hashset_definitions(py::module& m);
void pybind_core_scalar_definitions(py::module& m);

} // namespace core
} // namespace open3d
6 changes: 4 additions & 2 deletions cpp/pybind/core/cuda_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
namespace open3d {
namespace core {

void pybind_cuda_utils(py::module& m) {
void pybind_cuda_utils_declarations(py::module& m) {
py::module m_cuda = m.def_submodule("cuda");

}
void pybind_cuda_utils_definitions(py::module& m) {
auto m_cuda = static_cast<py::module>(m.attr("cuda"));
m_cuda.def("device_count", cuda::DeviceCount,
"Returns the number of available CUDA devices. Returns 0 if "
"Open3D is not compiled with CUDA support.");
Expand Down
14 changes: 8 additions & 6 deletions cpp/pybind/core/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@
namespace open3d {
namespace core {

void pybind_core_device(py::module &m) {
void pybind_core_device_declarations(py::module &m) {
py::class_<Device> device(
m, "Device",
"Device context specifying device type and device id.");
py::enum_<Device::DeviceType>(device, "DeviceType")
.value("CPU", Device::DeviceType::CPU)
.value("CUDA", Device::DeviceType::CUDA)
.export_values();
}
void pybind_core_device_definitions(py::module &m) {
auto device = static_cast<py::class_<Device>>(m.attr("Device"));
device.def(py::init<>());
device.def(py::init<Device::DeviceType, int>());
device.def(py::init<const std::string &, int>());
Expand All @@ -41,11 +48,6 @@ void pybind_core_device(py::module &m) {
return Device(t[0].cast<Device::DeviceType>(),
t[1].cast<int>());
}));

py::enum_<Device::DeviceType>(device, "DeviceType")
.value("CPU", Device::DeviceType::CPU)
.value("CUDA", Device::DeviceType::CUDA)
.export_values();
}

} // namespace core
Expand Down
8 changes: 6 additions & 2 deletions cpp/pybind/core/dtype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@
namespace open3d {
namespace core {

void pybind_core_dtype(py::module &m) {
// open3d.core.Dtype class
void pybind_core_dtype_declarations(py::module &m) {
py::class_<Dtype, std::shared_ptr<Dtype>> dtype(m, "Dtype",
"Open3D data types.");
}
void pybind_core_dtype_definitions(py::module &m) {
// open3d.core.Dtype class
auto dtype = static_cast<py::class_<Dtype, std::shared_ptr<Dtype>>>(
m.attr("Dtype"));
dtype.def(py::init<Dtype::DtypeCode, int64_t, const std::string &>());
dtype.def_readonly_static("Undefined", &core::Undefined);
dtype.def_readonly_static("Float32", &core::Float32);
Expand Down
12 changes: 8 additions & 4 deletions cpp/pybind/core/hashmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ const std::unordered_map<std::string, std::string> argument_docs = {
{"values_buffer_id", "Index of the value buffer tensor."},
{"device_id", "Target CUDA device ID."}};

void pybind_core_hashmap(py::module& m) {
void pybind_core_hashmap_declarations(py::module& m) {
py::class_<HashMap> hashmap(m, "HashMap",
"A HashMap is an unordered map from key to "
"value wrapped by Tensors.");

}
void pybind_core_hashmap_definitions(py::module& m) {
auto hashmap = static_cast<py::class_<HashMap>>(m.attr("HashMap"));
hashmap.def(py::init<int64_t, const Dtype&, const SizeVector&, const Dtype&,
const SizeVector&, const Device&>(),
"init_capacity"_a, "key_dtype"_a, "key_element_shape"_a,
Expand Down Expand Up @@ -193,11 +195,13 @@ void pybind_core_hashmap(py::module& m) {
hashmap.def_property_readonly("is_cuda", &HashMap::IsCUDA);
}

void pybind_core_hashset(py::module& m) {
void pybind_core_hashset_declarations(py::module& m) {
py::class_<HashSet> hashset(
m, "HashSet",
"A HashSet is an unordered set of keys wrapped by Tensors.");

}
void pybind_core_hashset_definitions(py::module& m) {
auto hashset = static_cast<py::class_<HashSet>>(m.attr("HashSet"));
hashset.def(
py::init<int64_t, const Dtype&, const SizeVector&, const Device&>(),
"init_capacity"_a, "key_dtype"_a, "key_element_shape"_a,
Expand Down
5 changes: 4 additions & 1 deletion cpp/pybind/core/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
namespace open3d {
namespace core {

void pybind_core_kernel(py::module &m) {
void pybind_core_kernel_declarations(py::module &m) {
py::module m_kernel = m.def_submodule("kernel");
}
void pybind_core_kernel_definitions(py::module &m) {
auto m_kernel = static_cast<py::module>(m.attr("kernel"));
m_kernel.def("test_linalg_integration",
&core::kernel::TestLinalgIntegration);
}
Expand Down
2 changes: 1 addition & 1 deletion cpp/pybind/core/linalg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
namespace open3d {
namespace core {

void pybind_core_linalg(py::module &m) {
void pybind_core_linalg_definitions(py::module &m) {
m.def(
"matmul",
[](const Tensor &A, const Tensor &B) {
Expand Down
Loading

0 comments on commit 48ccf2a

Please sign in to comment.