PZero codebase structure - gecos-lab/PZero GitHub Wiki
PZero is structured into four fundamental levels, based on three main libraries (VTK, Pandas and PySide6). Additionally, there are other input/output and processing functions that are not covered here.
Entities
These are geometric-topological objects (points, lines, surfaces, images, etc.) based on subclasses of VTK classes. The entities are defined in pzero/entities_factory.py. We consider this part of the project rather mature and we do not feel the need to make main modifications.
Collections
These are sets of entities and metadata organized logically (from a geological and geomodeling perspective). Collections are Pandas dataframes, with one row for each object contributing to the project. Various columns contain metadata, including a uid (a unique ID created with uuid), different metadata related to the geological significance of the object, and a reference to the entity mentioned earlier (column vtk_obj).
Collections are defined in pzero/collections/*, starting from an abstract class AbstractCollection.py (based on the ABC framework used to standardize abstract classes), which can either be extended directly or through another intermediate abstract class (e.g., DIM_collection.py). This part of the project is also mature and we do not feel the need to make main modifications.
Project Window
The main window is implemented in pzero/project_window.py, and it is built using Qt (Pyside6). The graphical interface and main actions are designed with Qt Designer and can be found in pzero/ui/project_window_ui.py (Python version exported from Designer) and pzero/gui/project_window.ui (Qt source file).
The Project Window includes:
- A top-left block (A1) with TableViews displaying the underlying data of the collections (with a Qt Model/View paradigm).
- A bottom-left block (A2) containing:
- A geological legend that allows modifying how entities are displayed based on their metadata.
- A properties legend, which does the same for properties associated with entities.
- A terminal displaying messages.
This part of the project is also mature and we do not feel the need to make main modifications.
Windows of Various Types
Various windows are implemented starting from pzero/windows_factory.py. These are multiple, independent Qt-based windows that can be opened in unlimited numbers. They follow a regular layout consisting of:
- A graphical canvas (B1) for 3D/2D views, statistical plots, etc.
- A set of QTreeWidget and QTableWidget (B2), listing all project objects (or a subset in some cases, e.g., for cross-sections). These allow users to:
- Show/hide objects using checkboxes.
- Select a uniform color or a color scale representing a property via dropdown menus.
The windows are multiple, potentially unlimited, and they have a mechanism where they are generated within a Dock area of the Project Window, but they can be dragged to other positions, even outside the Project Window (undocking). The windows can be closed if necessary using the classic X in the top-right corner. However, if the X is clicked while the window is in an undocked state, it simply returns to its original docked position. This behavior is managed by the DockWindow class, which contains, within its central canvas, the windows instantiated from other classes located in pzero/windows_factory.py. This system works well and does not pose any issues at the moment.
The classes used to display 3D views, 2D views, plots, etc. (B1 in the figure) are implemented using two prototypes (both derived from BaseView):
- VTKView, based on VTK/PyVista (PyVista is a library that simplifies the creation of VTK views).
- MPLView, based on Matplotlib.
All concrete views are derived from these two prototypes. The graphical canvases currently do not present any issues, with the only exception of the tool used to select actors in VTK/PyVista-based canvases.
The area of PZero where we need to improve the code architecture at the moment is the set of QTreeWidget and QTableWidget (B2) that appear in every window (B2), particularly regarding three points:
-
Refactoring to Reduce Code Duplication Both
pzero/build_and_updateandpzero/add_remove_update_actorscontain duplicated code. The current duplication slows down the interface and makes debugging difficult. We need a rationalized structure, potentially using abstract classes to reduce redundant methods, but other solutions might be considered. -
Multi-Level Checkboxes in QTreeWidget We need to implement check/uncheck propagation so that selecting/deselecting a higher-level item applies the action to all lower levels. We also want to enable multiple selection (via CTRL/SHIFT) and allow check/uncheck via right-click menu and/or keyboard shortcuts.
-
Dynamic Column Reordering in QTreeWidget & QTableWidget We need to implement drag-and-drop functionality for column reordering, and ensure that this order is reflected in the tree hierarchy. This would allow eliminating the duplicate QTreeWidgets for "geology" and "fluid," which currently exist for different hierarchical structures (role-based vs. topology-based).