diff --git a/Modules/MitkExt/Algorithms/mitkSimpleHistogram.cpp b/Modules/MitkExt/Algorithms/mitkSimpleHistogram.cpp index c5fdb6ad27..7959a2b668 100644 --- a/Modules/MitkExt/Algorithms/mitkSimpleHistogram.cpp +++ b/Modules/MitkExt/Algorithms/mitkSimpleHistogram.cpp @@ -1,243 +1,246 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSimpleHistogram.h" #include "mitkSimpleUnstructuredGridHistogram.h" #include "mitkUnstructuredGrid.h" namespace mitk { void SimpleImageHistogram::ComputeFromBaseData( BaseData* src ) { valid = false; //check if input is valid if (src==NULL) return; Image* source = dynamic_cast(src); if (source==NULL) return; else if (source->IsEmpty()) return; // dummy histogram { min=0; max=1; first=0; last=1; } { int typInt=0; { const std::type_info& typ=source->GetPixelType().GetTypeId(); if (typ == typeid(unsigned char )) typInt=0; else if(typ == typeid(signed char )) typInt=1; else if(typ == typeid(unsigned short)) typInt=2; else if(typ == typeid(signed short )) typInt=3; else { MITK_WARN << "SimpleImageHistogram currently only supports un/signed char/short"; return; } } first=-32768; last=65535; // support at least full signed and unsigned short range if(histogram) delete histogram; histogram = new CountType[last-first+1]; memset(histogram,0,sizeof(CountType)*(last-first+1)); highest = 0; max = first - 1; min = last + 1; unsigned int num=1; for(unsigned int r=0;rGetDimension();r++) num*=source->GetDimension(r); // MITK_INFO << "building histogramm of integer image: 0=" << source->GetDimension(0) << " 1=" << source->GetDimension(1) << " 2=" << source->GetDimension(2) << " 3=" << source->GetDimension(3); void *src=source->GetData(); do { int value; switch(typInt) { case 0: { unsigned char *t=(unsigned char *)src; value=*t++; src=(void*)t; } break; case 1: { signed char *t=( signed char *)src; value=*t++; src=(void*)t; } break; case 2: { unsigned short *t=(unsigned short*)src; value=*t++; src=(void*)t; } break; case 3: { signed short *t=( signed short*)src; value=*t++; src=(void*)t; } break; } if(value >= first && value <= last) { if(value < min) min = value; if(value > max) max = value; CountType tmp = ++histogram[value-first]; if(tmp > highest) highest = tmp; } } while(--num); MITK_INFO << "histogramm computed: min=" << min << " max=" << max << " highestBin=" << highest << " samples=" << num; } invLogHighest = 1.0/log(double(highest)); valid = true; } bool SimpleImageHistogram::GetValid() { return valid; } float SimpleImageHistogram::GetRelativeBin( double left, double right ) const { if( !valid ) return 0.0f; int iLeft = floorf(left); int iRight = ceilf(right); /* double sum = 0; for( int r = 0 ; r < 256 ; r++) { int pos = left + (right-left) * r/255.0; int posInArray = floorf(pos+0.5f) - first; sum += float(log(double(histogram[posInArray]))); } sum /= 256.0; return float(sum*invLogHighest); */ CountType maximum = 0; for( int i = iLeft; i <= iRight ; i++) { int posInArray = i - first; if( histogram[posInArray] > maximum ) maximum = histogram[posInArray]; } return float(log(double(maximum))*invLogHighest); } class ImageHistogramCacheElement : public SimpleHistogramCache::Element { public: void ComputeFromBaseData(BaseData* baseData) { histogram.ComputeFromBaseData(baseData); } SimpleHistogram* GetHistogram() { return &histogram; } SimpleImageHistogram histogram; }; class UnstructuredGridHistogramCacheElement : public SimpleHistogramCache::Element { public: void ComputeFromBaseData(BaseData* baseData) { histogram.ComputeFromBaseData(baseData); } SimpleHistogram* GetHistogram() { return &histogram; } SimpleUnstructuredGridHistogram histogram; }; SimpleHistogram* SimpleHistogramCache::operator[](BaseData::Pointer sp_BaseData) { BaseData *p_BaseData = sp_BaseData.GetPointer(); if(!p_BaseData) { MITK_WARN << "SimpleHistogramCache::operator[] with null base data called"; return 0; } Element *elementToUpdate = 0; bool first = true; for(CacheContainer::iterator iter = cache.begin(); iter != cache.end(); iter++) { Element *e = *iter; BaseData *p_tmp = e->baseData.GetPointer(); if(p_tmp == p_BaseData) { if(!first) { cache.erase(iter); cache.push_front(e); } if( p_BaseData->GetMTime() > e->m_LastUpdateTime.GetMTime()) + { + elementToUpdate = e; goto recomputeElement; + } //MITK_INFO << "using a cached histogram"; return e->GetHistogram(); } first = false; } if (dynamic_cast(p_BaseData)) { elementToUpdate = new ImageHistogramCacheElement(); } else if (dynamic_cast(p_BaseData)) { elementToUpdate = new UnstructuredGridHistogramCacheElement(); } else { MITK_WARN << "not supported: " << p_BaseData->GetNameOfClass(); } elementToUpdate->baseData = p_BaseData; cache.push_front(elementToUpdate); TrimCache(); recomputeElement: //MITK_INFO << "computing a new histogram"; elementToUpdate->ComputeFromBaseData(p_BaseData); elementToUpdate->m_LastUpdateTime.Modified(); return elementToUpdate->GetHistogram(); } } diff --git a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/QmitkUGVisualizationView.cpp b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/QmitkUGVisualizationView.cpp index c2b7016ed2..c8cde70d67 100644 --- a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/QmitkUGVisualizationView.cpp +++ b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/QmitkUGVisualizationView.cpp @@ -1,301 +1,301 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkUGVisualizationView.h" #include "QmitkStdMultiWidget.h" #include #include #include #include #include #include #include #include class UGVisVolumeObserver : public mitk::PropertyView { public: UGVisVolumeObserver(mitk::BoolProperty* property, QmitkUGVisualizationView* view) : PropertyView(property), m_View(view), m_BoolProperty(property) { } protected: virtual void PropertyChanged() { m_View->m_VolumeMode = m_BoolProperty->GetValue(); m_View->UpdateEnablement(); } virtual void PropertyRemoved() { m_View->m_VolumeMode = false; m_Property = 0; m_BoolProperty = 0; } QmitkUGVisualizationView* m_View; mitk::BoolProperty* m_BoolProperty; }; const std::string QmitkUGVisualizationView::VIEW_ID = "org.mitk.views.ugvisualization"; QmitkUGVisualizationView::QmitkUGVisualizationView() : QmitkFunctionality(), m_MultiWidget(0), m_Outline2DAction(0), m_Outline2DWidget(0), m_LODAction(0), m_ScalarVisibilityAction(0), m_ScalarVisibilityWidget(0), m_FirstVolumeRepId(-1), m_ShowTFGeneratorWidget(true), m_ShowScalarOpacityWidget(false), m_ShowColorWidget(true), m_ShowGradientOpacityWidget(false), m_ShowTFGeneratorAction(0), m_ShowScalarOpacityAction(0), m_ShowColorAction(0), m_ShowGradientOpacityAction(0), m_VolumeModeObserver(0) { } QmitkUGVisualizationView::QmitkUGVisualizationView(const QmitkUGVisualizationView& other) { Q_UNUSED(other) throw std::runtime_error("Copy constructor not implemented"); } QmitkUGVisualizationView::~QmitkUGVisualizationView() { delete m_VolumeModeObserver; } void QmitkUGVisualizationView::CreateQtPartControl( QWidget *parent ) { m_Controls.setupUi( parent ); m_Outline2DWidget = new QmitkBoolPropertyWidget("Outline 2D polygons", parent); m_Outline2DAction = new QWidgetAction(this); m_Outline2DAction->setDefaultWidget(m_Outline2DWidget); m_LODAction = new QAction("Enable LOD (Level Of Detail)", this); m_LODAction->setCheckable(true); m_ScalarVisibilityWidget = new QmitkBoolPropertyWidget("Visualize scalars", parent); m_ScalarVisibilityAction = new QWidgetAction(this); m_ScalarVisibilityAction->setDefaultWidget(m_ScalarVisibilityWidget); m_ShowColorAction = new QAction("Show color transfer function", this); m_ShowColorAction->setCheckable(true); m_ShowColorAction->setChecked(m_ShowColorWidget); m_ShowGradientOpacityAction = new QAction("Show gradient opacity function", this); m_ShowGradientOpacityAction->setCheckable(true); m_ShowGradientOpacityAction->setChecked(m_ShowGradientOpacityWidget); m_ShowScalarOpacityAction = new QAction("Show scalar opacity function", this); m_ShowScalarOpacityAction->setCheckable(true); m_ShowScalarOpacityAction->setChecked(m_ShowScalarOpacityWidget); m_ShowTFGeneratorAction = new QAction("Show transfer function generator", this); m_ShowTFGeneratorAction->setCheckable(true); m_ShowTFGeneratorAction->setChecked(m_ShowTFGeneratorWidget); QMenu* menu = new QMenu(parent); menu->addAction(m_ScalarVisibilityAction); menu->addAction(m_Outline2DAction); //menu->addAction(m_LODAction); menu->addSeparator(); menu->addAction(m_ShowTFGeneratorAction); menu->addAction(m_ShowScalarOpacityAction); menu->addAction(m_ShowColorAction); menu->addAction(m_ShowGradientOpacityAction); m_Controls.m_OptionsButton->setMenu(menu); m_Controls.m_TransferFunctionWidget->SetScalarLabel("Scalar value"); // const mitk::EnumerationProperty::EnumStringsContainerType& scalarStrings = scalarProp->GetEnumStrings(); // for (mitk::EnumerationProperty::EnumStringsContainerType::const_iterator it = scalarStrings.begin(); // it != scalarStrings.end(); ++it) // { // MITK_INFO << "ADding: " << it->first; // m_Controls.m_ScalarModeComboBox->addItem(QString::fromStdString(it->first), it->second); // } this->UpdateGUI(); CreateConnections(); } void QmitkUGVisualizationView::CreateConnections() { connect(m_Controls.m_ScalarModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateRenderWindow())); connect(m_Controls.m_RepresentationComboBox, SIGNAL(activated(int)), this, SLOT(UpdateRenderWindow())); connect(m_Outline2DWidget, SIGNAL(toggled(bool)), this, SLOT(UpdateRenderWindow())); connect(m_ScalarVisibilityWidget, SIGNAL(toggled(bool)), this, SLOT(UpdateRenderWindow())); connect(m_Controls.m_TransferFunctionGeneratorWidget, SIGNAL(SignalUpdateCanvas()), m_Controls.m_TransferFunctionWidget, SLOT(OnUpdateCanvas())); connect(m_ShowColorAction, SIGNAL(triggered(bool)), this, SLOT(ShowColorWidget(bool))); connect(m_ShowGradientOpacityAction, SIGNAL(triggered(bool)), this, SLOT(ShowGradientOpacityWidget(bool))); connect(m_ShowScalarOpacityAction, SIGNAL(triggered(bool)), this, SLOT(ShowScalarOpacityWidget(bool))); connect(m_ShowTFGeneratorAction, SIGNAL(triggered(bool)), this, SLOT(ShowTFGeneratorWidget(bool))); } void QmitkUGVisualizationView::UpdateRenderWindow() { mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkUGVisualizationView::ShowTFGeneratorWidget(bool show) { m_ShowTFGeneratorWidget = show; UpdateEnablement(); } void QmitkUGVisualizationView::ShowScalarOpacityWidget(bool show) { m_ShowScalarOpacityWidget = show; UpdateEnablement(); } void QmitkUGVisualizationView::ShowColorWidget(bool show) { m_ShowColorWidget = show; UpdateEnablement(); } void QmitkUGVisualizationView::ShowGradientOpacityWidget(bool show) { m_ShowGradientOpacityWidget = show; UpdateEnablement(); } void QmitkUGVisualizationView::UpdateEnablement() { m_Controls.m_TransferFunctionGeneratorWidget->setVisible(m_ShowTFGeneratorWidget); m_Controls.m_TransferFunctionWidget->ShowScalarOpacityFunction(m_ShowScalarOpacityWidget); m_Controls.m_TransferFunctionWidget->ShowColorFunction(m_ShowColorWidget); m_Controls.m_TransferFunctionWidget->ShowGradientOpacityFunction(m_ShowGradientOpacityWidget); - m_Controls.m_TransferFunctionGeneratorWidget->SetThresholdTabEnabled(m_VolumeMode); - m_Controls.m_TransferFunctionGeneratorWidget->SetBellTabEnabled(m_VolumeMode); - m_Controls.m_TransferFunctionWidget->SetScalarOpacityFunctionEnabled(m_VolumeMode); + m_Controls.m_TransferFunctionGeneratorWidget->SetThresholdTabEnabled(m_ScalarVisibilityWidget->isChecked()); + m_Controls.m_TransferFunctionGeneratorWidget->SetBellTabEnabled(m_ScalarVisibilityWidget->isChecked()); + m_Controls.m_TransferFunctionWidget->SetScalarOpacityFunctionEnabled(m_ScalarVisibilityWidget->isChecked()); m_Controls.m_TransferFunctionWidget->SetGradientOpacityFunctionEnabled(m_VolumeMode); } void QmitkUGVisualizationView::UpdateGUI() { bool enable = false; mitk::DataNode* node = 0; std::vector nodes = this->GetDataManagerSelection(); if (!nodes.empty()) { node = nodes.front(); if (node) { // here we have a valid mitk::DataNode // a node itself is not very useful, we need its data item mitk::BaseData* data = node->GetData(); if (data) { // test if this data item is an unstructured grid enable = dynamic_cast( data ); } } } m_Controls.m_SelectedLabel->setVisible(enable); m_Controls.m_ErrorLabel->setVisible(!enable); m_Controls.m_ContainerWidget->setEnabled(enable); m_Controls.m_OptionsButton->setEnabled(enable); if (enable) { m_VolumeMode = false; node->GetBoolProperty("volumerendering", m_VolumeMode); m_Controls.m_SelectedLabel->setText(QString("Selected UG: ") + node->GetName().c_str()); m_Controls.m_TransferFunctionGeneratorWidget->SetDataNode(node); m_Controls.m_TransferFunctionWidget->SetDataNode(node); mitk::BoolProperty* outlineProp = 0; node->GetProperty(outlineProp, "outline polygons"); m_Outline2DWidget->SetProperty(outlineProp); mitk::BoolProperty* scalarVisProp = 0; node->GetProperty(scalarVisProp, "scalar visibility"); m_ScalarVisibilityWidget->SetProperty(scalarVisProp); mitk::VtkScalarModeProperty* scalarProp = 0; if (node->GetProperty(scalarProp, "scalar mode")) { m_Controls.m_ScalarModeComboBox->SetProperty(scalarProp); } mitk::GridRepresentationProperty* gridRepProp = 0; mitk::GridVolumeMapperProperty* gridVolumeProp = 0; mitk::BoolProperty* volumeProp = 0; node->GetProperty(gridRepProp, "grid representation"); node->GetProperty(gridVolumeProp, "volumerendering.mapper"); node->GetProperty(volumeProp, "volumerendering"); m_Controls.m_RepresentationComboBox->SetProperty(gridRepProp, gridVolumeProp, volumeProp); if (m_VolumeModeObserver) { delete m_VolumeModeObserver; m_VolumeModeObserver = 0; } if (volumeProp) { m_VolumeModeObserver = new UGVisVolumeObserver(volumeProp, this); } } UpdateEnablement(); } void QmitkUGVisualizationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkUGVisualizationView::StdMultiWidgetNotAvailable() { m_MultiWidget = 0; } void QmitkUGVisualizationView::OnSelectionChanged( std::vector nodes ) { UpdateGUI(); }