.. meta:: :description: Infrastructure Dirty signature flags Dirty Signature Flags ===================== Dirty signatures is a mechanism implemented to track the changes made to instances of the class :class:`ORSModel.ors.Managed`. This is done by keeping, in the object model instance, a counter for each given dirty flag name. When a change is made to an object model instance, it is the responsibility of the developer to raise the appropriate dirty flag, so that the entire application can know what to update regarding this instance. When a dirty flag is raised (by a :meth:`ORSModel.ors.Managed.setDirty`) for an object model instance, the dirty signature of that object model instance is incremented and a *PropagateDirtyEvent* event is triggered. This event is sent to all matching callback functions having the corresponding dirty flag name. These callbacks can be set on instances (see :meth:`OrsEvent.eventCallback.EventCallback.addCallbackPropagateDirtyEvent`) and on classes (see :meth:`OrsEvent.eventCallback.EventCallback.addClassCallbackPropagateDirtyEvent`). Note that raising a dirty flag affects the performance of the application, especially if this is done repetitively, because some tasks can be long to compute and should therefore be executed only when necessary. Therefore, it is important to raise only the required dirty flags at the right moment to avoid performance degradation. Associated to :meth:`ORSModel.ors.Managed.setDirty` is :meth:`ORSModel.ors.Node.propagateDirty`. Calling *propagateDirty* on a model object instance inheriting :class:`ORSModel.ors.Node` will raise the dirty flag of every child of that instance. It means that the dirty signature of that dirty flag name is incremented for each child and the *PropagateDirtyEvent* event is also triggered with that dirty flag name. The dirty signature flags defined by the application are found in :ref:`dirtySignatureFlags`. It is also possible to define and use a custom dirty flag for specific purposes. OrsDataDirty ------------ This is used to know when the data of an object is modified. The following table contains some of the modifications of the model object instances for which a *OrsDataDirty* should be raised. +----------------+------------------------------------------------------------------------+ | Class | Modification | +================+========================================================================+ | Channel | - overwriting values (intensity) in the data array | | | - changing the offset, slope or dimension unit | | | - changing the data type (a *propagateDataDirty* is required) | +----------------+------------------------------------------------------------------------+ | ROI | - modifying the contents (painting) | +----------------+------------------------------------------------------------------------+ | MultiROI | - modifying the contents (painting) of any label | | | - adding or removing labels | +----------------+------------------------------------------------------------------------+ | StructuredGrid | - changing the shape | +----------------+------------------------------------------------------------------------+ | Annotation | - changing a control point position | | | - adding or removing a control point | +----------------+------------------------------------------------------------------------+ | Mesh | - changing vertices location | | | - adding or removing vertices | +----------------+------------------------------------------------------------------------+ | LookupTable | - changing the color of an element of the table | | | - adding or removing an element of the table | +----------------+------------------------------------------------------------------------+ | Image | - modifying the contents (painting) | | | - changing the shape | +----------------+------------------------------------------------------------------------+ | Layout | - changing the shape of a view | | | - changing the disposition of the views | +----------------+------------------------------------------------------------------------+ | HistogramData | - changing a bin value | | | - changing the bin limits | +----------------+------------------------------------------------------------------------+ Associated methods: - :meth:`ORSModel.ors.Managed.setDataDirty` - :meth:`ORSModel.ors.Node.propagateDataDirty` - :meth:`ORSModel.ors.Managed.getDataDirtySignature` .. note:: The signature of *OrsDataDirty* is also used to determine if an object needs to be saved before exiting the application. This applies to the instances of the classes visible in the list of *Data Properties and Settings*, namely *Channel*, *ROI*, *MultiROI*, *Annotation*, *Mesh*, *VisualShape*, *VisualOverlay* and *Group*. OrsGeometryDirty ---------------- This is used to know when the box of an object is modified. This is applicable only to model objects for which a box (:class:`ORSModel.ors.Box`) is part of their definition, such as *Channel*, *ROI*, *MultiROI* and *Mesh*. The modifications for which the *OrsGeometryDirty* flag should be raised includes: - changing the position of the box; - changing the orientation (directions) of the box; - changing the size of the box. Associated methods: - :meth:`ORSModel.ors.Managed.setGeometryDirty` - :meth:`ORSModel.ors.Node.propagateGeometryDirty` - :meth:`ORSModel.ors.Managed.getGeometryDirtySignature` .. note:: The signature of *OrsGeometryDirty* is also used to determine if an object needs to be saved before exiting the application. This applies to the instances of the classes visible in the list of *Data Properties and Settings*, namely *Channel*, *ROI*, *MultiROI*, *Annotation*, *Mesh*, *VisualShape*, *VisualOverlay* and *Group*. OrsPropertyDirty ---------------- This is used to know when some properties of an object are modified. The following table contains some of the modifications of the model object instances for which a *OrsPropertyDirty* should be raised. +----------------+---------------------------------------------------------------------------+ | Class | Modification | +================+===========================================================================+ | Channel | - changing the LUT | | | - changing the opacity | +----------------+---------------------------------------------------------------------------+ | ROI | - changing the color | | | - changing the opacity | +----------------+---------------------------------------------------------------------------+ | MultiROI | - changing the LUT | | | - changing the opacity | | | - changing the color of a label | +----------------+---------------------------------------------------------------------------+ | Mesh | - changing the LUT | | | - changing the opacity | +----------------+---------------------------------------------------------------------------+ | View | - changing the dimension unit | | | - changing the view mode (2D, 3D, ...) | | | - changing rendering parameters (light, shadow, background color, ...) | +----------------+---------------------------------------------------------------------------+ | Managed | - changing the title | +----------------+---------------------------------------------------------------------------+ | Visual | - changing the highlight status | +----------------+---------------------------------------------------------------------------+ Associated methods: - :meth:`ORSModel.ors.Managed.setPropertyDirty` - :meth:`ORSModel.ors.Node.propagatePropertyDirty` - :meth:`ORSModel.ors.Managed.getPropertyDirtySignature` .. note:: The signature of *OrsPropertyDirty* is also used to determine if an object needs to be saved before exiting the application. This applies to the instances of the classes visible in the list of *Data Properties and Settings*, namely *Channel*, *ROI*, *MultiROI*, *Annotation*, *Mesh*, *VisualShape*, *VisualOverlay* and *Group*. .. note:: The signature of *OrsPropertyDirty* of the instances of *Visual* is also used to determine if the 3D view needs to be redrawn. OrsVisibilityDirty ------------------ This is used to know when the visibility of an object is modified. Associated methods: - :meth:`ORSModel.ors.Managed.setVisibilityDirty` - :meth:`ORSModel.ors.Node.propagateVisibilityDirty` - :meth:`ORSModel.ors.Managed.getVisibilityDirtySignature` OrsRangeHighlightDirty ---------------------- This is used to know when the range highlight of a dataset is changed. .. note:: This *range highlight* is also named in the code as *WindowLevel2*. OrsScalarMeshPropertyDirty -------------------------- This is used to know when the scalar values of a mesh are changed. More specifically, it is used to update the rendering when the colors associated to vertices of a mesh are modified. Demos ----- **Using dirty flags** In this demonstration, different properties associated to the dirty flags *OrsDataDirty*, *OrsGeometryDirty*, *OrsPropertyDirty* and *OrsVisibilityDirty* can be modified for a given *ROI* instance, for which the dirty flags will be raised to keep the application synchronized. Also, dirty flags raised by other tools of the application used to modify that *ROI* will be used to refresh the information on the UI. .. _sourcecodeexample_plugin_DemoDirtyFlags_0ac5ff5eaf7b11e78346448a5b5d70c0: Source code example: #. Download the :download:`compressed file `; #. Extract these files into a :ref:`plugin extension folder `; #. Start the application; #. Open the top level menu *Demos* to see the menu item named *Demo: dirty flags*; #. By clicking on the menu item, an instance of the plugin will be created and his mainform will be displayed; #. Import or create one or more ROIs. Note that the combo box of the plugin UI is updated each time a *ROI* is published or deleted in order to show all the representable *ROIs*; #. Select a *ROI* in the combo box of the available *ROIs*; #. In the *OrsDataDirty* group box, use the *Draw* and *Erase* push buttons to modify the data of the *ROI*, for which a *OrsDataDirty* dirty flag is raised. Note the incrementation of the *OrsDataDirty* dirty signature flag; #. Use any tool to change the data of the *ROI* (*ROI Painter*, *ROI Tools*, ...). Note the incrementation of the *OrsDataDirty* dirty signature flag; #. In the *OrsGeometryDirty* group box, use the rotation buttons to rotate the *ROI*, for which a *OrsGeometryDirty* dirty flag is raised. Note that it is the actual position of the *ROI* that is changed, not the camera. This can be observed by drawing an annotation (for example, a ruler) in the view and then using the rotation buttons to move the *ROI*. Note the incrementation of the *OrsGeometryDirty* dirty signature flag; #. Use the *Move* tools (NOT the *Flip/Rotate*, which tools are to control the camera) to move the *ROI*. Note the incrementation of the *OrsGeometryDirty* dirty signature flag; #. In the *OrsPropertyDirty* group box, change the title and the color of the *ROI*, for which a *OrsPropertyDirty* dirty flag is raised. Note the incrementation of the *OrsPropertyDirty* dirty signature flag. Note also that the title of the *ROI* in the combo box used to select the *ROI* to analyze has also been updated; #. Use the *Data Properties and Settings* to modify the title and the color of the *ROI*. Note the incrementation of the *OrsPropertyDirty* dirty signature flag, of the title and of the color; #. In the *OrsVisibilityDirty* group box, use the toggle button to make the *ROI* visible or not, for which a *OrsVisibilityDirty* dirty flag is raised. Note the incrementation of the *OrsVisibilityDirty* dirty signature flag; #. Use the *Data Properties and Settings* to show and hide the *ROI*. Note the incrementation of the *OrsVisibilityDirty* dirty signature flag and the status of the visibility toggle button. .. **Creating custom dirty flags**