JWock82 / Pynite

A 3D structural engineering finite element library for Python.
MIT License
469 stars 95 forks source link

Idea: Move visualization modules to separate packages #208

Open connorferster opened 3 months ago

connorferster commented 3 months ago

Is your feature request related to a problem? Please describe. Currently, @JWock82 has implemented a combination of VTK, PyVista, and Matplotlib visualizations however I know that he prefers to keep the dependencies for these capabilities out of the core PyNite package since the software itself does not actually require them to do its job.

With the release of the (excellent) PyVista visualization module, the idea was to deprecate the existing VTK module. However, I think it would be unfortunate to waste all of the work that has gone into this (also excellent) visualization.

The thing with VTK is that it seems best suited for desktop application use. PyVista seems best suited for certain web-based applications (e.g. Jupyter), although PyVista cannot run everywhere (e.g. in Jupyterlite or Streamlit), for reasons which are beyond our control. Matplotlib does run everywhere but is perhaps not as nice as some of the other options. So it seems different visualization engines are better suited to certain Python execution environments and/or applications.

Describe the solution you'd like Move visualization modules into separate packages (e.g. PyNite-VTK, PyNite-PyVista and PyNite-Plotly (which I am currently working on) so that people can "pick and choose" the visualization tool that suits their needs/preferences.

I believe @JWock82 is only interested in maintaining the PyVista visualization going forward. This is great and no one needs to commit themselves to perpetually maintaining these packages if they do not want to. They can simply be available and, if outside contributors want to make updates and perform maintenance, they are free to do so.

I think this approach allows for PyNite to remain focused on its core functionality while allowing maximum flexibility for defining new and customized visualization tools.

Describe alternatives you've considered

  1. Only having one visualization tool: Currently, there is a combination of matplotlib and PyVista. PyVista is used for rendering whole models and matplotlib is used for rendering individual member diagrams. However, the VTK module is still in the package and it seems unfortunate to simply discard it.
  2. Maintaining several visualization packages as part of PyNite: I think this makes the package too cumbersome. The PyVista visualization requires a LOT of heavy dependencies that are C-extensions (same with VTK) which means they need to be recompiled for new OS, chips, Python versions when they come out. If additional visualization modules are added, then there are just more dependencies to the package, which I understand @JWock82 really wishes to avoid.
  3. Everyone patching their own branch of PyNite to include their own visualization package: this seems unnecessary and fussy since we have the technology in Python to avoid this necessity.

Additional context Python allows for the creation and definition of "entrypoints" which allow plugin-based software to work. PyNite would expose an entrypoint and, if there are any packages installed that use that entrypoint, then those packages would be used for the visualization. No configuration is necessary. If PyNite is installed and another visualization module is installed, then PyNite will use that module by default.

Here is a brief description of how this works: https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata

Since matplotlib is currently a core dependency of PyNite, my thought is to use matplotlib to define the default visualization engine (3D model and diagrams). We can define an interface and use the matplotlib visualization module to demonstrate who the interface should be implemented. Then, any other visualization module could be substituted as long as it defines the same interface. And when I say, "we can define an interface", I am fully signing myself up to actually do this work (not expecting anyone else to have to take it on if they do not want).

JWock82 commented 3 months ago

One of the core objectives of Pynite is to keep the code simple. VTK was originally chosen because of its cross-platform compatibility and its compatible licensing, but VTK was hard to code with. It requires assembling the whole visual pipeline (objects, mappers, actors, labels, label actors, label mappers) manually. Pyvista manages most of this for you and was seen as a major simplification to Pynite's code. I've noticed Pyvista takes a little more time to generate the renderings than VTK did.

Trying to do this all in matplotlib will be painful as far as I can tell, but if you want to add it I won't stop you. Both VTK and Pyvista provide a lot of tools to simplify rendering. They are engines built with finite elements in mind. They also provide tools for picking, which Pynite doesn't use right now, but could be useful if we ever want to add a GUI.

My plan has been to keep Pyvista incorporated with Pynite and maintain it. I'll leave the VTK code in, but I don't plan to maintain it myself going forward. It was too difficult to maintain as it was. Making it as a separate package would be a good idea, but I don't want to break everyone's legacy code either.