meshpro / pygalmesh

:spider_web: A Python interface to CGAL's meshing tools
GNU General Public License v3.0
581 stars 57 forks source link

Operator overloading for domain combinations #142

Open ES-Alexander opened 3 years ago

ES-Alexander commented 3 years ago

I'm thinking it would help with intuitive use of domains if domain combinations could also be implemented as operator overloads, e.g. support the following in DomainBase:

operator function map to/return e.g.
\| __or__(self, obj) pygalmesh.Union(self, obj) Ball \| Ball
& __and__(self, obj) pygalmesh.Intersection(self, obj) Ball & Ball
- __sub__(self, obj) pygalmesh.Difference(self, obj) Ball - Ball
+ __add__(self, obj) pygalmesh.Translate(self, obj) Ball + [x,y,z]
+ __radd__(self, obj) self.__add__(obj) [x,y,z] + Ball
* __mul__(self, obj) pygalmesh.Scale(self, obj) Ball * [x,y,z]
* __rmul__(self, obj) self.__mul__(obj) [x,y,z] * Ball

I'm unsure about Rotate (possibly @ (__matmul__)) and Stretch (possibly % (__mod__) or ** (__pow__), or just left off).

I was planning to implement this as a PR but then saw that DomainBase and its subclasses are implemented in C++, which I'm not very familiar with. I'm also not sure if a class (e.g. DomainBase) can have methods that return its own subclasses, which is what would be desired here.

EDIT: updated with examples and to better reflect valid inputs.

nschloe commented 3 years ago

A good idea, but you'll have to dive into C++ to implement it indeed. I'd love to elevate more code to the Python level, but the problem is that the primitives' eval() method is called many times during the mesh building process. If the primitives were in written Python (which I'd like much better), the Python-C++ call overhead would dominate the run time.

ES-Alexander commented 3 years ago

If I understand correctly, splitting domain.hpp into a header file that declares DomainBase and the domain operations and a code file that defines them would allow returning subclasses from a DomainBase function call right? If that's the case then the only missing components (from my understanding) would be how to return a class instance from a C++ function, and agreement on which operators to overload.

Thinking now that % might actually be more appropriate for rotation, since it's effectively an operator that represents a cyclic conversion...

nschloe commented 3 years ago

Just give it a shot, I'll review all PRs. Best start out with one operator, like +. If given two domains, it should Union, if given a domain and a vec of length three, it should translate, and otherwise fail.