While working on {T28640} I realized that different tools provide a `CanHandle` function which look different and I'm not sure if this makes sense in most cases.
I will list the different functions here so that we can discuss their function-body and the differences.
The `CanHandle`-function is available in the `mitk::Tool`-class and is mostly overridden by semi-automatic interactive segmentation tools.
```
bool mitk::Tool::CanHandle(const BaseData* referenceData, const BaseData* /*workingData*/) const
{
if (referenceData == nullptr)
return false;
return true;
}
```
The basic `mitk::Tool` restricts the data that can be handled to reference-data - working-data pairs, where
- the reference-data is valid
---
~~The `mitk::AutoSegmentationTool`, subclassing the basic `mitk::Tool`, does not override the `CanHandle`-function and thus does not restrict the data to be handled more.~~
~~The `mitk::AutoSegmentationWithPreviewTool`, subclassing the `mitk::AutoSegmentationTool`, does override the `CanHandle`-function:~~
The classes have been merged and renamed to `SegWithPreviewTool`.
```
bool mitk::SegWithPreviewTool::CanHandle(const BaseData* referenceData, const BaseData* workingData) const
{
if (!Superclass::CanHandle(referenceData, workingData))
return false;
if (workingData == nullptr)
return true;
auto* labelSet = dynamic_cast<const LabelSetImage*>(workingData);
if (labelSet != nullptr)
return true;
auto* image = dynamic_cast<const Image*>(workingData);
if (image == nullptr)
return false;
//if it is a normal image and not a label set image is used as working data
//it must have the same pixel type as a label set.
return MakeScalarPixelType< DefaultSegmentationDataType >() == image->GetPixelType();
}
```
It restricts the data that can be handled to reference-data - working-data pairs, where
- the working-data is not valid
or
- the working-data is valid and either a `mitk::Image` or a `mitk::LabelSetImage`
- the `mitk::Image` has to have a `DefaultSegmentationDataType` pixel type
---
Following classes subclass the `mitk::AutoSegmentationWithPreviewTool` but they restrict the data to be handled more:
```
bool mitk::PickingTool::CanHandle(const BaseData* referenceData, const BaseData* workingData) const
{
if (!Superclass::CanHandle(referenceData,workingData))
return false;
auto* image = dynamic_cast<const Image*>(referenceData);
if (image == nullptr)
return false;
return true;
}
```
It restricts the data that can be handled to reference-data - working-data pairs, where
- the reference-data is a `mitk::Image`
```
bool mitk::FastMarchingBaseTool::CanHandle(const BaseData* referenceData, const BaseData* workingData) const
{
if(!Superclass::CanHandle(referenceData, workingData))
return false;
if (referenceData == nullptr)
return false;
auto *image = dynamic_cast<const Image *>(referenceData);
if (image == nullptr)
return false;
if (image->GetDimension() < 3)
return false;
return true;
}
```
It restricts the data that can be handled to reference-data - working-data pairs, where
- the reference-data is valid (which is already guaranteed by the base-class `mitk::Tool`)
- the reference-data is a `mitk::Image`
- the reference image is not a 2D image
---
The `mitk::AdaptiveRegionGrowingTool` directly subclasses the `mitk::AutoSegmentationTool` but it restricts the data to be handled more:
```
bool mitk::AdaptiveRegionGrowingTool::CanHandle(const BaseData* referenceData, const BaseData* /*workingData*/) const
{
if (referenceData == nullptr)
return false;
auto *image = dynamic_cast<const Image *>(referenceData);
if (image == nullptr)
return false;
if (image->GetDimension() < 3)
return false;
if (image->GetTimeSteps() > 1) //release quickfix for T28275
return false;
return true;
}
```
It restricts the data that can be handled to reference-data - working-data pairs, where
- the reference-data is valid (which is already guaranteed by the base-class `mitk::Tool`, but the function does not call `Superclass::CanHandle`)
- the reference-data is a `mitk::Image`
- the reference image is not a 2D image
- the reference image is not a 4D image
---
There are some problems / inconsistencies with these different implementations so I will address them in the comments.