Skip to content

Commit 48ccf2a

Browse files
authored
Split pybind declarations and definitions (#6869)
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]>
1 parent 7f9377d commit 48ccf2a

File tree

114 files changed

+3248
-2456
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+3248
-2456
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
- Fix build with fmt v10.2.0 (#6783)
4141
- Fix segmentation fault (lambda reference capture) of VisualizerWithCustomAnimation::Play (PR #6804)
4242
- Add O3DVisualizer API to enable collapse control of verts in the side panel (PR #6865)
43+
- Split pybind declarations/definitions to avoid C++ types in Python docs (PR #6869)
4344
- Fix minimal oriented bounding box of MeshBase derived classes and add new unit tests (PR #6898)
4445

4546
## 0.13

cpp/pybind/camera/camera.cpp

+52-45
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,48 @@
1414
namespace open3d {
1515
namespace camera {
1616

17-
void pybind_camera_classes(py::module &m) {
18-
// open3d.camera.PinholeCameraIntrinsic
17+
void pybind_camera_declarations(py::module &m) {
18+
py::module m_camera = m.def_submodule("camera");
1919
py::class_<PinholeCameraIntrinsic> pinhole_intr(
20-
m, "PinholeCameraIntrinsic",
20+
m_camera, "PinholeCameraIntrinsic",
2121
"PinholeCameraIntrinsic class stores intrinsic camera matrix, and "
2222
"image height and width.");
23+
// open3d.camera.PinholeCameraIntrinsicParameters
24+
py::enum_<PinholeCameraIntrinsicParameters> pinhole_intr_params(
25+
m_camera, "PinholeCameraIntrinsicParameters", py::arithmetic(),
26+
"PinholeCameraIntrinsicParameters");
27+
pinhole_intr_params
28+
.value("PrimeSenseDefault",
29+
PinholeCameraIntrinsicParameters::PrimeSenseDefault,
30+
"Default camera intrinsic parameter for PrimeSense.")
31+
.value("Kinect2DepthCameraDefault",
32+
PinholeCameraIntrinsicParameters::Kinect2DepthCameraDefault,
33+
"Default camera intrinsic parameter for Kinect2 depth "
34+
"camera.")
35+
.value("Kinect2ColorCameraDefault",
36+
PinholeCameraIntrinsicParameters::Kinect2ColorCameraDefault,
37+
"Default camera intrinsic parameter for Kinect2 color "
38+
"camera.")
39+
.export_values();
40+
pinhole_intr_params.attr("__doc__") = docstring::static_property(
41+
py::cpp_function([](py::handle arg) -> std::string {
42+
return "Enum class that contains default camera intrinsic "
43+
"parameters for different sensors.";
44+
}),
45+
py::none(), py::none(), "");
46+
py::class_<PinholeCameraParameters> pinhole_param(
47+
m_camera, "PinholeCameraParameters",
48+
"Contains both intrinsic and extrinsic pinhole camera parameters.");
49+
py::class_<PinholeCameraTrajectory> pinhole_traj(
50+
m_camera, "PinholeCameraTrajectory",
51+
"Contains a list of ``PinholeCameraParameters``, useful to storing "
52+
"trajectories.");
53+
}
54+
void pybind_camera_definitions(py::module &m) {
55+
auto m_camera = static_cast<py::module>(m.attr("camera"));
56+
// open3d.camera.PinholeCameraIntrinsic
57+
auto pinhole_intr = static_cast<py::class_<PinholeCameraIntrinsic>>(
58+
m_camera.attr("PinholeCameraIntrinsic"));
2359
py::detail::bind_default_constructor<PinholeCameraIntrinsic>(pinhole_intr);
2460
py::detail::bind_copy_functions<PinholeCameraIntrinsic>(pinhole_intr);
2561
pinhole_intr
@@ -64,50 +100,28 @@ void pybind_camera_classes(py::module &m) {
64100
std::string(
65101
".\nAccess intrinsics with intrinsic_matrix.");
66102
});
67-
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic", "__init__");
68-
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic",
103+
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
104+
"__init__");
105+
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
69106
"set_intrinsics",
70107
{{"width", "Width of the image."},
71108
{"height", "Height of the image."},
72109
{"fx", "X-axis focal length"},
73110
{"fy", "Y-axis focal length."},
74111
{"cx", "X-axis principle point."},
75112
{"cy", "Y-axis principle point."}});
76-
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic",
113+
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
77114
"get_focal_length");
78-
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic",
115+
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
79116
"get_principal_point");
80-
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic", "get_skew");
81-
docstring::ClassMethodDocInject(m, "PinholeCameraIntrinsic", "is_valid");
82-
83-
// open3d.camera.PinholeCameraIntrinsicParameters
84-
py::enum_<PinholeCameraIntrinsicParameters> pinhole_intr_params(
85-
m, "PinholeCameraIntrinsicParameters", py::arithmetic(),
86-
"PinholeCameraIntrinsicParameters");
87-
pinhole_intr_params
88-
.value("PrimeSenseDefault",
89-
PinholeCameraIntrinsicParameters::PrimeSenseDefault,
90-
"Default camera intrinsic parameter for PrimeSense.")
91-
.value("Kinect2DepthCameraDefault",
92-
PinholeCameraIntrinsicParameters::Kinect2DepthCameraDefault,
93-
"Default camera intrinsic parameter for Kinect2 depth "
94-
"camera.")
95-
.value("Kinect2ColorCameraDefault",
96-
PinholeCameraIntrinsicParameters::Kinect2ColorCameraDefault,
97-
"Default camera intrinsic parameter for Kinect2 color "
98-
"camera.")
99-
.export_values();
100-
pinhole_intr_params.attr("__doc__") = docstring::static_property(
101-
py::cpp_function([](py::handle arg) -> std::string {
102-
return "Enum class that contains default camera intrinsic "
103-
"parameters for different sensors.";
104-
}),
105-
py::none(), py::none(), "");
117+
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
118+
"get_skew");
119+
docstring::ClassMethodDocInject(m_camera, "PinholeCameraIntrinsic",
120+
"is_valid");
106121

107122
// open3d.camera.PinholeCameraParameters
108-
py::class_<PinholeCameraParameters> pinhole_param(
109-
m, "PinholeCameraParameters",
110-
"Contains both intrinsic and extrinsic pinhole camera parameters.");
123+
auto pinhole_param = static_cast<py::class_<PinholeCameraParameters>>(
124+
m_camera.attr("PinholeCameraParameters"));
111125
py::detail::bind_default_constructor<PinholeCameraParameters>(
112126
pinhole_param);
113127
py::detail::bind_copy_functions<PinholeCameraParameters>(pinhole_param);
@@ -125,10 +139,8 @@ void pybind_camera_classes(py::module &m) {
125139
});
126140

127141
// open3d.camera.PinholeCameraTrajectory
128-
py::class_<PinholeCameraTrajectory> pinhole_traj(
129-
m, "PinholeCameraTrajectory",
130-
"Contains a list of ``PinholeCameraParameters``, useful to storing "
131-
"trajectories.");
142+
auto pinhole_traj = static_cast<py::class_<PinholeCameraTrajectory>>(
143+
m_camera.attr("PinholeCameraTrajectory"));
132144
py::detail::bind_default_constructor<PinholeCameraTrajectory>(pinhole_traj);
133145
py::detail::bind_copy_functions<PinholeCameraTrajectory>(pinhole_traj);
134146
pinhole_traj
@@ -141,10 +153,5 @@ void pybind_camera_classes(py::module &m) {
141153
});
142154
}
143155

144-
void pybind_camera(py::module &m) {
145-
py::module m_submodule = m.def_submodule("camera");
146-
pybind_camera_classes(m_submodule);
147-
}
148-
149156
} // namespace camera
150157
} // namespace open3d

cpp/pybind/camera/camera.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
namespace open3d {
1313
namespace camera {
1414

15-
void pybind_camera(py::module &m);
15+
void pybind_camera_declarations(py::module &m);
16+
void pybind_camera_definitions(py::module &m);
1617

1718
} // namespace camera
1819
} // namespace open3d

cpp/pybind/core/blob.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
namespace open3d {
1515
namespace core {
1616

17-
void pybind_core_blob(py::module &m) { py::class_<Blob> blob(m, "Blob"); }
17+
void pybind_core_blob_declarations(py::module &m) {
18+
py::class_<Blob> blob(m, "Blob");
19+
}
1820

1921
} // namespace core
2022
} // namespace open3d

cpp/pybind/core/core.cpp

+30-15
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,42 @@
1616
namespace open3d {
1717
namespace core {
1818

19-
void pybind_core(py::module& m) {
19+
void pybind_core_declarations(py::module& m) {
2020
py::module m_core = m.def_submodule("core");
2121

2222
// opn3d::core namespace.
23-
pybind_cuda_utils(m_core);
24-
pybind_sycl_utils(m_core);
25-
pybind_core_blob(m_core);
26-
pybind_core_dtype(m_core);
27-
pybind_core_device(m_core);
28-
pybind_core_size_vector(m_core);
29-
pybind_core_tensor(m_core);
30-
pybind_core_tensor_function(m_core);
31-
pybind_core_linalg(m_core);
32-
pybind_core_kernel(m_core);
33-
pybind_core_hashmap(m_core);
34-
pybind_core_hashset(m_core);
35-
pybind_core_scalar(m_core);
23+
pybind_cuda_utils_declarations(m_core);
24+
pybind_core_blob_declarations(m_core);
25+
pybind_core_dtype_declarations(m_core);
26+
pybind_core_device_declarations(m_core);
27+
pybind_core_size_vector_declarations(m_core);
28+
pybind_core_tensor_declarations(m_core);
29+
pybind_core_kernel_declarations(m_core);
30+
pybind_core_hashmap_declarations(m_core);
31+
pybind_core_hashset_declarations(m_core);
32+
pybind_core_scalar_declarations(m_core);
3633

3734
// opn3d::core::nns namespace.
3835
py::module m_nns = m_core.def_submodule("nns");
39-
nns::pybind_core_nns(m_nns);
36+
nns::pybind_core_nns_declarations(m_nns);
37+
}
38+
39+
void pybind_core_definitions(py::module& m) {
40+
auto m_core = static_cast<py::module>(m.attr("core"));
41+
pybind_cuda_utils_definitions(m_core);
42+
pybind_sycl_utils_definitions(m_core);
43+
pybind_core_dtype_definitions(m_core);
44+
pybind_core_device_definitions(m_core);
45+
pybind_core_size_vector_definitions(m_core);
46+
pybind_core_tensor_definitions(m_core);
47+
pybind_core_tensor_function_definitions(m_core);
48+
pybind_core_linalg_definitions(m_core);
49+
pybind_core_kernel_definitions(m_core);
50+
pybind_core_hashmap_definitions(m_core);
51+
pybind_core_hashset_definitions(m_core);
52+
pybind_core_scalar_definitions(m_core);
53+
auto m_nns = static_cast<py::module>(m_core.attr("nns"));
54+
nns::pybind_core_nns_definitions(m_nns);
4055
}
4156

4257
} // namespace core

cpp/pybind/core/core.h

+25-14
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,32 @@
1313
namespace open3d {
1414
namespace core {
1515

16-
void pybind_core(py::module& m);
17-
void pybind_cuda_utils(py::module& m);
18-
void pybind_sycl_utils(py::module& m);
19-
void pybind_core_blob(py::module& m);
20-
void pybind_core_dtype(py::module& m);
21-
void pybind_core_device(py::module& m);
22-
void pybind_core_size_vector(py::module& m);
23-
void pybind_core_tensor(py::module& m);
16+
void pybind_core_declarations(py::module& m);
17+
void pybind_cuda_utils_declarations(py::module& m);
18+
void pybind_core_blob_declarations(py::module& m);
19+
void pybind_core_dtype_declarations(py::module& m);
20+
void pybind_core_device_declarations(py::module& m);
21+
void pybind_core_size_vector_declarations(py::module& m);
22+
void pybind_core_tensor_declarations(py::module& m);
2423
void pybind_core_tensor_accessor(py::class_<Tensor>& t);
25-
void pybind_core_tensor_function(py::module& m);
26-
void pybind_core_linalg(py::module& m);
27-
void pybind_core_kernel(py::module& m);
28-
void pybind_core_hashmap(py::module& m);
29-
void pybind_core_hashset(py::module& m);
30-
void pybind_core_scalar(py::module& m);
24+
void pybind_core_tensor_function_definitions(py::module& m);
25+
void pybind_core_kernel_declarations(py::module& m);
26+
void pybind_core_hashmap_declarations(py::module& m);
27+
void pybind_core_hashset_declarations(py::module& m);
28+
void pybind_core_scalar_declarations(py::module& m);
29+
30+
void pybind_core_definitions(py::module& m);
31+
void pybind_cuda_utils_definitions(py::module& m);
32+
void pybind_sycl_utils_definitions(py::module& m);
33+
void pybind_core_dtype_definitions(py::module& m);
34+
void pybind_core_device_definitions(py::module& m);
35+
void pybind_core_size_vector_definitions(py::module& m);
36+
void pybind_core_tensor_definitions(py::module& m);
37+
void pybind_core_linalg_definitions(py::module& m);
38+
void pybind_core_kernel_definitions(py::module& m);
39+
void pybind_core_hashmap_definitions(py::module& m);
40+
void pybind_core_hashset_definitions(py::module& m);
41+
void pybind_core_scalar_definitions(py::module& m);
3142

3243
} // namespace core
3344
} // namespace open3d

cpp/pybind/core/cuda_utils.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
namespace open3d {
1313
namespace core {
1414

15-
void pybind_cuda_utils(py::module& m) {
15+
void pybind_cuda_utils_declarations(py::module& m) {
1616
py::module m_cuda = m.def_submodule("cuda");
17-
17+
}
18+
void pybind_cuda_utils_definitions(py::module& m) {
19+
auto m_cuda = static_cast<py::module>(m.attr("cuda"));
1820
m_cuda.def("device_count", cuda::DeviceCount,
1921
"Returns the number of available CUDA devices. Returns 0 if "
2022
"Open3D is not compiled with CUDA support.");

cpp/pybind/core/device.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@
1414
namespace open3d {
1515
namespace core {
1616

17-
void pybind_core_device(py::module &m) {
17+
void pybind_core_device_declarations(py::module &m) {
1818
py::class_<Device> device(
1919
m, "Device",
2020
"Device context specifying device type and device id.");
21+
py::enum_<Device::DeviceType>(device, "DeviceType")
22+
.value("CPU", Device::DeviceType::CPU)
23+
.value("CUDA", Device::DeviceType::CUDA)
24+
.export_values();
25+
}
26+
void pybind_core_device_definitions(py::module &m) {
27+
auto device = static_cast<py::class_<Device>>(m.attr("Device"));
2128
device.def(py::init<>());
2229
device.def(py::init<Device::DeviceType, int>());
2330
device.def(py::init<const std::string &, int>());
@@ -41,11 +48,6 @@ void pybind_core_device(py::module &m) {
4148
return Device(t[0].cast<Device::DeviceType>(),
4249
t[1].cast<int>());
4350
}));
44-
45-
py::enum_<Device::DeviceType>(device, "DeviceType")
46-
.value("CPU", Device::DeviceType::CPU)
47-
.value("CUDA", Device::DeviceType::CUDA)
48-
.export_values();
4951
}
5052

5153
} // namespace core

cpp/pybind/core/dtype.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@
1515
namespace open3d {
1616
namespace core {
1717

18-
void pybind_core_dtype(py::module &m) {
19-
// open3d.core.Dtype class
18+
void pybind_core_dtype_declarations(py::module &m) {
2019
py::class_<Dtype, std::shared_ptr<Dtype>> dtype(m, "Dtype",
2120
"Open3D data types.");
21+
}
22+
void pybind_core_dtype_definitions(py::module &m) {
23+
// open3d.core.Dtype class
24+
auto dtype = static_cast<py::class_<Dtype, std::shared_ptr<Dtype>>>(
25+
m.attr("Dtype"));
2226
dtype.def(py::init<Dtype::DtypeCode, int64_t, const std::string &>());
2327
dtype.def_readonly_static("Undefined", &core::Undefined);
2428
dtype.def_readonly_static("Float32", &core::Float32);

cpp/pybind/core/hashmap.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ const std::unordered_map<std::string, std::string> argument_docs = {
5050
{"values_buffer_id", "Index of the value buffer tensor."},
5151
{"device_id", "Target CUDA device ID."}};
5252

53-
void pybind_core_hashmap(py::module& m) {
53+
void pybind_core_hashmap_declarations(py::module& m) {
5454
py::class_<HashMap> hashmap(m, "HashMap",
5555
"A HashMap is an unordered map from key to "
5656
"value wrapped by Tensors.");
57-
57+
}
58+
void pybind_core_hashmap_definitions(py::module& m) {
59+
auto hashmap = static_cast<py::class_<HashMap>>(m.attr("HashMap"));
5860
hashmap.def(py::init<int64_t, const Dtype&, const SizeVector&, const Dtype&,
5961
const SizeVector&, const Device&>(),
6062
"init_capacity"_a, "key_dtype"_a, "key_element_shape"_a,
@@ -193,11 +195,13 @@ void pybind_core_hashmap(py::module& m) {
193195
hashmap.def_property_readonly("is_cuda", &HashMap::IsCUDA);
194196
}
195197

196-
void pybind_core_hashset(py::module& m) {
198+
void pybind_core_hashset_declarations(py::module& m) {
197199
py::class_<HashSet> hashset(
198200
m, "HashSet",
199201
"A HashSet is an unordered set of keys wrapped by Tensors.");
200-
202+
}
203+
void pybind_core_hashset_definitions(py::module& m) {
204+
auto hashset = static_cast<py::class_<HashSet>>(m.attr("HashSet"));
201205
hashset.def(
202206
py::init<int64_t, const Dtype&, const SizeVector&, const Device&>(),
203207
"init_capacity"_a, "key_dtype"_a, "key_element_shape"_a,

cpp/pybind/core/kernel.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414
namespace open3d {
1515
namespace core {
1616

17-
void pybind_core_kernel(py::module &m) {
17+
void pybind_core_kernel_declarations(py::module &m) {
1818
py::module m_kernel = m.def_submodule("kernel");
19+
}
20+
void pybind_core_kernel_definitions(py::module &m) {
21+
auto m_kernel = static_cast<py::module>(m.attr("kernel"));
1922
m_kernel.def("test_linalg_integration",
2023
&core::kernel::TestLinalgIntegration);
2124
}

cpp/pybind/core/linalg.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
namespace open3d {
2222
namespace core {
2323

24-
void pybind_core_linalg(py::module &m) {
24+
void pybind_core_linalg_definitions(py::module &m) {
2525
m.def(
2626
"matmul",
2727
[](const Tensor &A, const Tensor &B) {

0 commit comments

Comments
 (0)