Skip to content

Commit

Permalink
[pydrake] Factor out make_shared_ptr_from_py_object for reuse (#22478)
Browse files Browse the repository at this point in the history
  • Loading branch information
jwnimmer-tri authored Jan 21, 2025
1 parent e554f53 commit a22266d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 13 deletions.
14 changes: 2 additions & 12 deletions bindings/pydrake/geometry/geometry_py_render.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,8 @@ class PyRenderEngine : public py::wrapper<RenderEngine> {
}
return copied;
};
py::object py_engine = make_python_deepcopy();
// Convert the py_engine to a shared_ptr<RenderEngine> whose C++ lifetime
// keeps the python object alive.
RenderEngine* cpp_engine = py::cast<RenderEngine*>(py_engine);
DRAKE_DEMAND(cpp_engine != nullptr);
return std::shared_ptr<RenderEngine>(
/* stored pointer = */ cpp_engine,
/* deleter = */ [captured_py_engine = std::move(py_engine)](
void*) mutable {
py::gil_scoped_acquire deleter_guard;
captured_py_engine = py::none();
});
py::object result = make_python_deepcopy();
return make_shared_ptr_from_py_object<RenderEngine>(result);
}

void DoRenderColorImage(ColorRenderCamera const& camera,
Expand Down
20 changes: 19 additions & 1 deletion bindings/pydrake/pydrake_pybind.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,30 @@ inline void ExecuteExtraPythonCode(py::module m, bool use_subdir = false) {
/// anything -- it's managed object is null, so there is no reference counting.
/// Calling get() on the result will return `raw`.
template <typename T>
auto make_unowned_shared_ptr_from_raw(T* raw) {
std::shared_ptr<T> make_unowned_shared_ptr_from_raw(T* raw) {
return std::shared_ptr<T>(
/* managed object = */ std::shared_ptr<void>{},
/* stored pointer = */ raw);
}

/// Given a Python object, returns a shared_ptr wrapper around it that keeps
/// the Python object alive. If the py_object is None, returns nullptr. You
/// must supply the expected C++ type to cast to as `T`.
template <typename T>
std::shared_ptr<T> make_shared_ptr_from_py_object(py::object py_object) {
if (py_object.is_none()) {
return {};
}
T* cpp_object = py::cast<T*>(py_object);
return std::shared_ptr<T>(
/* stored pointer = */ cpp_object,
/* deleter = */ [captured_py_object = std::move(py_object)](
void*) mutable {
py::gil_scoped_acquire deleter_guard;
captured_py_object = py::none();
});
}

} // namespace pydrake
} // namespace drake

Expand Down

0 comments on commit a22266d

Please sign in to comment.