Using decorators to link pybind
geometry classes to pure Python
classes with Numpy
arrays
#6802
evbernardes
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
This was mostly just a little personal experiment to see what was possible to do with decorators, so bear with me. This is also using legacy geometry elements.
I decided to create the abomination that I will be describing in this post. This is definitely quite ugly, but I wonder if something like this could be actually implemented in a better way or if someone could point out to me where the bugs would be!
"Problems" I want to solve
Problem 1
One of the "problems" I wanted to solve is that all properties of the geometry classes are of type
std::vector<Eigen::Something>
. Example:And also, when giving points, I have to first transform them to
Eigen
classes. This fails:But this works:
(As far as I know, this is not a problem with
Tensor
classes).Problem 2
There are also problems with inheritance, which was the main problem I had, as I wanted to implement some other stuff with both pointclouds and meshes.
As far as I know, this is also a problem with
Tensor
classes:Solution
My idea to solve Problem 2 was to create a class that has an internal property that points to the Open3D equivalent class. But having to call it all the time, then convert everything to Eigen classes, and take the return values and convert them to numpy arrays was a bit clunky, so I decided to create some ugly decorators to do this for me.
Decorator 1: converting returns to Numpy arrays
This decorator takes the results of methods and, one of the results is a member of
open3d.utility
, it converts it to a Numpy array recursively:Decorator 2: converting args to Eigen arrays
The second, arguably the ugliest, would be to do the inverse: check all elements on the args and see if there is an equivalent array type on
open3d.utility
. This string-based solution is obviously ridiculous, but this could be replaced by some actual implementation insideutility
that is a bit more general.NOTE: this would also convert any
self
argument to the internalas_open3d
element, which is important.Decorator 3: a fusion of 1 and 2:
Decorator 4: the class decorator
Ok, I lied. THIS is the ugliest one yet. The idea is to copy the definitions of all attributes of the original class, but using the decorators (including for the properties), creating a new
__init__
that actually initializes the original class.Base linker class
The idea is then to finally just create a base class that gives the internal instance as a property:
Testing
Here I demonstrate the use of this experiment. Suppose I want to use pointclouds, then:
Now I can init the
PointCloud
normally (note that it automatically copies the__repr__
element too):I can set the points normally from the property setter, and it sets the points inside of the internal object:
I can use methods like
translate
for example with no problem:Indexing also words:
Conclusion
And this is the end of the experiment, in which I achieved what I wanted. There are of course some issues there, specially coming from the bad conversion method from args to Eigen types, but that could potentially be solved by some kind of proper compatibility utility converter.
What are your thoughts? Where would it fail? Could something actually usable and safe be implemented in a similar manner, hipothetically, in order to improve the compatibility with Python?
Beta Was this translation helpful? Give feedback.
All reactions