![]() |
ImFusion SDK 4.3
|
Algorithms are one of the central concepts of the ImFusion framework because they allow to develop new functionality in a clean, well-defined manner without having to modify the base framework or interfering with existing algorithms. All algorithms are derived from the Algorithm interface. The central methods of this interface are the compute method and the createCompatible method which must be defined by every algorithm. Optionally an algorithm controller derived from Algorithm Controller can be defined which can be used to display a graphical user interface for interacting with the algorithm, for instance allowing to set properties or to create new views for displaying algorithm results. To make an algorithm known to the framework a factory needs to be written which in turn has to be registered with the global FactoryRegistry object.
Support for loading and saving custom data formats can be added by implementing specialized algorithms. In contrast to regular algorithms I/O-algorithms derive from IoAlgorithm. IoAlgorithms have special properties which allow to generically specify the location of the data and whether data should be imported or exported. The actual loading and writing of the data is performed in the compute method. It is also possible to write controllers for an IoAlgorithm which can for instance display custom import and export options. For the common use case of only needing to select the input/output file the default controller IoController can be used.
To create a new algorithm a class deriving from Algorithm needs to be created. Inside this class the compute and the createCompatible method need to be defined. compute is called by the framework or the algorithm controller to perform the actual computations. createCompatible is used to create an algorithm instance for a given set of input data represented as a DataList object. Inside createCompatible the algorithm needs to check whether it supports operating on the provided data. If so it should create an instance of itself and configure it so that it runs on the input data. createCompatible should only succeed when all data in the data list is needed by the algorithm to operate. For instance an algorithm which downsamples a single 2D image should fail createCompatible if the data list contains more than one element even if one of them is a 2D image. The framework generates the data list passed to createCompatible in one of two ways:
If the algorithm creates output data it also needs to implement the takeOutput method to provide the data to the framework or the controller.
To support automated algorithm serialization and instantiation by the framework for instance for including the algorithm configuration in a workspace file the methods of the Configurable interface need to be implemented.
If desired an algorithm controller can be written to implement custom logic and user interface components for interacting with the algorithm. The algorithm controller needs to derive from the AlgorithmController class. Typically the algorithm controller class also derives from QWidget to be able to display a widget; however, this is not a requirement. If a controller is available for an algorithm the framework creates the controller after creating the algorithm. The previously created algorithm object is passed to the algorithm controller constructor so that it can be accessed from the controller. Then the init method which every controller needs to implement is called by the framework. Use this method for initializations requiring access to MainWindowBase or DisplayWidgetMulti as init is called only after the m_disp and m_main attributes have been set. A controller with user interface components additionally needs to contain methods to react to user interaction such as a button press to call methods on the actual algorithm instance. While it is possible to perform all computations inside the controller and leave the algorithm as a stub, this should be avoided for the sake of a clean separation of GUI and processing code and to enable the usage of algorithms from non-GUI aware code.
A controller can fully interact with the framework allowing it to add new data to the data model (m_main->dataModel()->add(<data>)
) or to add custom views (m_disp->addView(<view>)
) or annotations (m_disp->addObject(<object>, ...)
).
To make the application aware of the algorithm and optionally the controller they need to be registered with the global factory registry. To this end it is necessary to derive classes from AlgorithmFactory and AlgorithmControllerFactory respectively:
To make the application aware of the factories - depending on your use case - it is necessary to do one of the following: