arpastrana / compas_cem

Inverse design of 3D truss networks with automatic differentiation
https://arpastrana.github.io/compas_cem
MIT License
37 stars 7 forks source link

Simplify Rhino linking with new pluggable extension of COMPAS >=0.16.3 #2

Closed gonzalocasas closed 3 years ago

gonzalocasas commented 3 years ago

Starting with COMPAS 0.16.3, there is a new extension point called installable_rhino_packages which makes linking compas packages to Rhino almost transparent. The only thing required is to implement a method with that name adding the decorator and so on, and return the list of package names that you want to be installed/linked to Rhino when the main compas install installed (ie. using python -m compas_rhino.install). If this is the first plugin in compas_cem, then also need to add a variable __all_plugins__ = [...] to the main __init__.py pointing to the module in which your plugin method lives.

For reference, check how we are doing it on compas fab: here is the plugin implementation and here the declaration on __init__.

For additional context, the architecture of plugins is documented in the dev guide of compas.

How this plugin is in place, the compas_cem package will be automatically installed/linked to Rhino if it's installed in the active environment.

arpastrana commented 3 years ago

Hi @gonzalocasas! Sorry if it took me a while to come back to this. Does this effectively mean that one would not need to uninstall-install compas packages and plugins (CPPs) anymore into Rhino when switching environments? In other words, Rhino will have available all the CPPs installed in the activated conda environment?

gonzalocasas commented 3 years ago

It almost means exactly that ;) with the only exception that it currently works for compas packages, but I have no idea if it does for plugins (probably doesn't).

PS: It took me multiple seconds to get that CPPs was not C++ files 😄

arpastrana commented 3 years ago

Oh, that was pun intended! 😛 So what is the difference between a compas plugin and a compas package? And why would the new pluggable extension probably work only with the latter?

gonzalocasas commented 3 years ago

The difference is one mostly of convention and naming, rather than of technology. A compas package (or 'extension' as it's now referred to in the docs) is code that adds new features usually in a new domain of knowledge (eg. compas_fab, compas_slicer), it builds ON TOP of compas. A compas plugin is code that implements a feature by extending compas directly, or adding a feature directly INSIDE of compas (eg adding booleans to compas using cgal). For this purpose, the new pluggable interfaces are a way to simplify that scenario.

But pluggable interfaces (and their corresponding implementation) can live anywhere. There are some implementations inside the compas_rhino package, for example, so, they are no limited at all.

arpastrana commented 3 years ago

Hmm...I'm starting to grasp the idea, especially after skimming over compas' dev guide. I see a good motivation behind for plugins being a way to solve what backend to use for a particular function depending on where a user is working at a given point in time. I am sure there is more to the pluggable/plugin interface, but that's my takeaway so far.

For compas_cem, I definitely see how this can be useful to distinguish between methods that cannot run in Rhino because of IronPython. For instance, to compute force equilibrium of a given form, there is a force_equilibrium_not_numpy and force_equilibrium_numpy that are (almost) interchangeable. So would the pluggable/plugin select the most appropriate version under a common signature, say force_equilibrium, and spare the confusion to a user?

Returning to the departure point in the chat, I see that the goal is to simplify linking compas_cem to rhino as a user hops between conda environments. Where would be a good place to put the decorated installable_rhino_packages if we don't have a dedicated compas_cem.rhino module? We could create one but we don't have any rhino dedicated functionality yet...

Overall, where should the plugin files live (not necessarily for linking an extension to Rhino)? The compas dev guide may suggest that the plugin and pluggable live in different places or even in different packages: The plugin lives in compas_plugin_sample/boolean_trimesh.py and the pluggable in compas/geometry/booleans/__init__.py. I might be interpreting this incorrectly but if compas_plugin_sample does not live inside compas/geometry/booleans...how would the technology know where to find it? A file path listed in __all_plugins__? Or does this imply that any plugin that has business to do with a pluggable must live inside the same package?

Hope this make sense!

arpastrana commented 3 years ago

Closed with 079dbd3ba5cd52360c49e0892ae9e03e71d02bdf. @gonzalocasas, the rhino linking of compas_cem is now working like a charm after using the installable_rhino_packages extension point.

Further, compas_cem now also ships as a grasshopper plugin thanks to the GHPythonComponentizer action. These are installed/uninstalled in automatic using the same extension point. For the record, the dev work was done on Mac 🤓 (which led to some issues installing ironpython, but that is a story for another day).

Will keep you posted if I find any issues as I go, but so far so good. In the meantime, thank you!